File indexing completed on 2025-01-18 09:53:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_TYPEOF_MSVC_TYPEOF_IMPL_HPP_INCLUDED
0010 # define BOOST_TYPEOF_MSVC_TYPEOF_IMPL_HPP_INCLUDED
0011
0012 # include <boost/config.hpp>
0013 # include <boost/config/workaround.hpp>
0014 # include <boost/typeof/constant.hpp>
0015 # include <type_traits>
0016
0017 # include <typeinfo>
0018
0019 namespace boost
0020 {
0021 namespace type_of
0022 {
0023
0024
0025 # if defined(_MSC_EXTENSIONS)
0026 template<int N> struct the_counter;
0027
0028 template<typename T,int N = 5>
0029 struct encode_counter
0030 {
0031 __if_exists(the_counter<N + 256>)
0032 {
0033 BOOST_STATIC_CONSTANT(unsigned,count=(encode_counter<T,N + 257>::count));
0034 }
0035 __if_not_exists(the_counter<N + 256>)
0036 {
0037 __if_exists(the_counter<N + 64>)
0038 {
0039 BOOST_STATIC_CONSTANT(unsigned,count=(encode_counter<T,N + 65>::count));
0040 }
0041 __if_not_exists(the_counter<N + 64>)
0042 {
0043 __if_exists(the_counter<N + 16>)
0044 {
0045 BOOST_STATIC_CONSTANT(unsigned,count=(encode_counter<T,N + 17>::count));
0046 }
0047 __if_not_exists(the_counter<N + 16>)
0048 {
0049 __if_exists(the_counter<N + 4>)
0050 {
0051 BOOST_STATIC_CONSTANT(unsigned,count=(encode_counter<T,N + 5>::count));
0052 }
0053 __if_not_exists(the_counter<N + 4>)
0054 {
0055 __if_exists(the_counter<N>)
0056 {
0057 BOOST_STATIC_CONSTANT(unsigned,count=(encode_counter<T,N + 1>::count));
0058 }
0059 __if_not_exists(the_counter<N>)
0060 {
0061 BOOST_STATIC_CONSTANT(unsigned,count=N);
0062 typedef the_counter<N> type;
0063 }
0064 }
0065 }
0066 }
0067 }
0068 };
0069
0070 # define BOOST_TYPEOF_INDEX(T) (encode_counter<T>::count)
0071 # define BOOST_TYPEOF_NEXT_INDEX(next)
0072 # else
0073 template<int N> struct encode_counter : encode_counter<N - 1> {};
0074 template<> struct encode_counter<0> {};
0075
0076
0077 char (*encode_index(...))[5];
0078
0079 # define BOOST_TYPEOF_INDEX(T) (sizeof(*boost::type_of::encode_index((boost::type_of::encode_counter<1005>*)0)))
0080 # define BOOST_TYPEOF_NEXT_INDEX(next) friend char (*encode_index(encode_counter<next>*))[next];
0081 # endif
0082
0083
0084
0085 # if BOOST_WORKAROUND(BOOST_MSVC,>=1400)
0086 struct msvc_extract_type_default_param {};
0087
0088 template<typename ID, typename T = msvc_extract_type_default_param>
0089 struct msvc_extract_type;
0090
0091 template<typename ID>
0092 struct msvc_extract_type<ID, msvc_extract_type_default_param> {
0093 template<bool>
0094 struct id2type_impl;
0095
0096 typedef id2type_impl<true> id2type;
0097 };
0098
0099 template<typename ID, typename T>
0100 struct msvc_extract_type : msvc_extract_type<ID,msvc_extract_type_default_param>
0101 {
0102 template<>
0103 struct id2type_impl<true>
0104 {
0105 typedef T type;
0106 };
0107 template<bool>
0108 struct id2type_impl;
0109
0110 typedef id2type_impl<true> id2type;
0111 };
0112
0113 template<typename T, typename ID>
0114 struct msvc_register_type : msvc_extract_type<ID, T>
0115 {
0116 };
0117 # else
0118 template<typename ID>
0119 struct msvc_extract_type
0120 {
0121 struct id2type;
0122 };
0123
0124 template<typename T, typename ID>
0125 struct msvc_register_type : msvc_extract_type<ID>
0126 {
0127 typedef msvc_extract_type<ID> base_type;
0128 struct base_type::id2type
0129 {
0130 typedef T type;
0131 };
0132 };
0133 # endif
0134
0135 template<int ID>
0136 struct msvc_typeid_wrapper {
0137 typedef typename msvc_extract_type<constant<int,ID> >::id2type id2type;
0138 typedef typename id2type::type type;
0139 };
0140
0141 template<>
0142 struct msvc_typeid_wrapper<1> {
0143 typedef msvc_typeid_wrapper<1> type;
0144 };
0145
0146 template<>
0147 struct msvc_typeid_wrapper<4> {
0148 typedef msvc_typeid_wrapper<4> type;
0149 };
0150
0151
0152 template<typename T>
0153 struct encode_type
0154 {
0155
0156 BOOST_STATIC_CONSTANT(unsigned,value=BOOST_TYPEOF_INDEX(T));
0157
0158 typedef typename msvc_register_type<T,constant<int,value> >::id2type type;
0159
0160 BOOST_STATIC_CONSTANT(unsigned,next=value+1);
0161
0162 BOOST_TYPEOF_NEXT_INDEX(next);
0163 };
0164
0165 template<class T>
0166 struct sizer
0167 {
0168 typedef char(*type)[encode_type<T>::value];
0169 };
0170 template<typename T> typename std::enable_if<
0171 !std::is_function<T>::value,
0172 typename sizer<T>::type>::type encode_start(T const&);
0173
0174 template<typename T> typename std::enable_if<
0175 std::is_function<T>::value,
0176 typename sizer<T>::type>::type encode_start(T&);
0177 template<typename Organizer, typename T>
0178 msvc_register_type<T,Organizer> typeof_register_type(const T&,Organizer* =0);
0179
0180 # define BOOST_TYPEOF(expr) \
0181 boost::type_of::msvc_typeid_wrapper<sizeof(*boost::type_of::encode_start(expr))>::type
0182
0183 # define BOOST_TYPEOF_TPL(expr) typename BOOST_TYPEOF(expr)
0184
0185 # define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \
0186 struct name {\
0187 enum {_typeof_register_value=sizeof(boost::type_of::typeof_register_type<name>(expr))};\
0188 typedef typename boost::type_of::msvc_extract_type<name>::id2type id2type;\
0189 typedef typename id2type::type type;\
0190 };
0191
0192 # define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \
0193 struct name {\
0194 enum {_typeof_register_value=sizeof(boost::type_of::typeof_register_type<name>(expr))};\
0195 typedef boost::type_of::msvc_extract_type<name>::id2type id2type;\
0196 typedef id2type::type type;\
0197 };
0198
0199 }
0200 }
0201
0202 #endif