Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:12

0001 
0002 // Copyright (C) 2005 Igor Chesnokov, mailto:ichesnokov@gmail.com (VC 6.5,VC 7.1 + counter code)
0003 // Copyright (C) 2005-2007 Peder Holt (VC 7.0 + framework)
0004 // Copyright (C) 2006 Steven Watanabe (VC 8.0)
0005 
0006 // Use, modification and distribution is subject to the Boost Software
0007 // License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt)
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         //Compile time constant code
0025 # if defined(_MSC_EXTENSIONS)
0026         template<int N> struct the_counter;
0027 
0028         template<typename T,int N = 5/*for similarity*/>
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         //Need to default to a larger value than 4, as due to MSVC's ETI errors. (sizeof(int)==4)
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         //Typeof code
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>  //VC8.0 specific bugfeature
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 // This uses nice VC6.5 and VC7.1 bugfeature
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         //Workaround for ETI-bug for VC6 and VC7
0141         template<>
0142         struct msvc_typeid_wrapper<1> {
0143             typedef msvc_typeid_wrapper<1> type;
0144         };
0145         //Workaround for ETI-bug for VC7.1
0146         template<>
0147         struct msvc_typeid_wrapper<4> {
0148             typedef msvc_typeid_wrapper<4> type;
0149         };
0150 
0151         //Tie it all together
0152         template<typename T>
0153         struct encode_type
0154         {
0155             //Get the next available compile time constants index
0156             BOOST_STATIC_CONSTANT(unsigned,value=BOOST_TYPEOF_INDEX(T));
0157             //Instantiate the template
0158             typedef typename msvc_register_type<T,constant<int,value> >::id2type type;
0159             //Set the next compile time constants index
0160             BOOST_STATIC_CONSTANT(unsigned,next=value+1);
0161             //Increment the compile time constant (only needed when extensions are not active
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//BOOST_TYPEOF_MSVC_TYPEOF_IMPL_HPP_INCLUDED