diff --git a/include/boost/typeof/msvc/typeof_impl.hpp b/include/boost/typeof/msvc/typeof_impl.hpp index c29b388..c7b5890 100755 --- a/include/boost/typeof/msvc/typeof_impl.hpp +++ b/include/boost/typeof/msvc/typeof_impl.hpp @@ -1,6 +1,6 @@ - + // Copyright (C) 2005 Igor Chesnokov, mailto:ichesnokov@gmail.com (VC 6.5,VC 7.1 + counter code) -// Copyright (C) 2005 Peder Holt (VC 7.0 + framework) +// Copyright (C) 2005-2007 Peder Holt (VC 7.0 + framework) // Copyright (C) 2006 Steven Watanabe (VC 8.0) // Use, modification and distribution is subject to the Boost Software @@ -15,6 +15,10 @@ # include # include +# if BOOST_WORKAROUND(BOOST_MSVC,>=1310) +# include +# endif + namespace boost { namespace type_of @@ -23,7 +27,7 @@ namespace boost //Compile time constant code # if BOOST_WORKAROUND(BOOST_MSVC,>=1300) && defined(_MSC_EXTENSIONS) template struct the_counter; - + template struct encode_counter { @@ -40,7 +44,7 @@ namespace boost __if_not_exists(the_counter) { __if_exists(the_counter) - { + { BOOST_STATIC_CONSTANT(unsigned,count=(encode_counter::count)); } __if_not_exists(the_counter) @@ -71,7 +75,7 @@ namespace boost # else template struct encode_counter : encode_counter {}; template<> struct encode_counter<0> {}; - + //Need to default to a larger value than 4, as due to MSVC's ETI errors. (sizeof(int)==4) char (*encode_index(...))[5]; @@ -132,7 +136,7 @@ namespace boost struct msvc_register_type : msvc_extract_type { }; -# else +# else template struct msvc_extract_type { @@ -149,7 +153,57 @@ namespace boost }; }; # endif +# if BOOST_WORKAROUND(BOOST_MSVC,>=1310) + template + struct msvc_typeid_wrapper { + typedef typename msvc_extract_type::id2type id2type; + typedef typename id2type::type wrapped_type; + typedef typename wrapped_type::type type; + }; + //This class is used for registering the type T. encode_type is mapped against typeid(encode_type). + //msvc_typeid_wrapper)> will now have a type typedef that equals encode_type. + template + struct encode_type + { + typedef encode_type input_type; + //Invoke registration of encode_type. typeid(encode_type) is now mapped to encode_type. Do not use registered_type for anything. + //The reason for registering encode_type rather than T, is that VC handles typeid(function reference) poorly. By adding another + //level of indirection, we solve this problem. + typedef typename msvc_register_type >::id2type registered_type; + typedef T type; + }; + template typename disable_if< + typename is_function::type, + typename encode_type::input_type>::type encode_start(T const&); + + template typename enable_if< + typename is_function::type, + typename encode_type::input_type>::type encode_start(T&); + + template + msvc_register_type typeof_register_type(const T&); + +# define BOOST_TYPEOF(expr) \ + boost::type_of::msvc_typeid_wrapper::type + +# define BOOST_TYPEOF_TPL(expr) typename BOOST_TYPEOF(expr) + +# define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \ +struct name {\ + enum {_typeof_register_value=sizeof(typeid(boost::type_of::typeof_register_type(expr)))};\ + typedef typename boost::type_of::msvc_extract_type::id2type id2type;\ + typedef typename id2type::type type;\ +}; + +# define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \ +struct name {\ + enum {_typeof_register_value=sizeof(typeid(boost::type_of::typeof_register_type(expr)))};\ + typedef boost::type_of::msvc_extract_type::id2type id2type;\ + typedef id2type::type type;\ +}; + +# else template struct msvc_typeid_wrapper { typedef typename msvc_extract_type >::id2type id2type; @@ -177,7 +231,7 @@ namespace boost //Set the next compile time constants index BOOST_STATIC_CONSTANT(unsigned,next=value+1); //Increment the compile time constant (only needed when extensions are not active - BOOST_TYPEOF_NEXT_INDEX(next); + BOOST_TYPEOF_NEXT_INDEX(next); }; template @@ -186,24 +240,11 @@ namespace boost typedef char(*type)[encode_type::value]; }; -# ifdef BOOST_NO_SFINAE - template typename sizer::type encode_start(T const&); -# else - - template typename disable_if< - typename is_function::type, - typename sizer::type>::type encode_start(T const&); - - template typename enable_if< - typename is_function::type, - typename sizer::type>::type encode_start(T&); - -# endif - } -} + template + msvc_register_type typeof_register_type(const T&,Organizer* =0); # define BOOST_TYPEOF(expr) \ boost::type_of::msvc_typeid_wrapper::type @@ -212,20 +253,20 @@ namespace boost # define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \ struct name {\ - template\ - static boost::type_of::msvc_register_type _typeof_register_function(const T&);\ - BOOST_STATIC_CONSTANT(int,_typeof_register_value=sizeof(_typeof_register_function(expr)));\ + BOOST_STATIC_CONSTANT(int,_typeof_register_value=sizeof(boost::type_of::typeof_register_type(expr)));\ typedef typename boost::type_of::msvc_extract_type::id2type id2type;\ typedef typename id2type::type type;\ }; # define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \ struct name {\ - template\ - static boost::type_of::msvc_register_type _typeof_register_function(const T&);\ - BOOST_STATIC_CONSTANT(int,_typeof_register_value=sizeof(_typeof_register_function(expr)));\ + BOOST_STATIC_CONSTANT(int,_typeof_register_value=sizeof(boost::type_of::typeof_register_type(expr)));\ typedef boost::type_of::msvc_extract_type::id2type id2type;\ typedef id2type::type type;\ }; +#endif + } +} + #endif//BOOST_TYPEOF_MSVC_TYPEOF_IMPL_HPP_INCLUDED