Implemented BOOST_TYPEOF_NESTED_TYPEDEF.

This macro works around known bugs in VC7.1 and VC8.0 concerning the use of BOOST_TYPEOF inside templates. It also eliminates the limitation imposed by BOOST_TYPEOF_LIMIT_SIZE.


[SVN r33355]
This commit is contained in:
Peder Holt 2006-03-16 17:10:19 +00:00
parent e2d492bb49
commit dbfa74603c
12 changed files with 198 additions and 31 deletions

View File

@ -578,7 +578,7 @@ but removes the top-level qualifiers, `const&`
BOOST_TYPEOF_TPL(expr)
[variablelist Arguments
[[expr][a valid c++ expression that has a type]]
[[expr][a valid c++ expression that can be converted to const T&]]
]
[h4 Remarks]
@ -602,6 +602,48 @@ which takes care of `typename` inside the `typeof` expression.
[endsect]
[section:typo TYPEOF_NESTED_TYPEDEF, TYPEOF_NESTED_TYPEDEF_TPL]
The `TYPEOF_NESTED_TYPEDEF` macro works in much the same way as the 'TYPEOF' macro does, but
workarounds several compiler deficiencies.
[h4 Usage]
BOOST_TYPEOF_NESTED_TYPEDEF(name,expr)
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr)
[variablelist Arguments
[[name][a valid identifier to nest the typeof operation inside]
[expr][a valid c++ expression that can be converted to const T&]]
]
[h4 Remarks]
'typeof_nested_typedef' nests the 'typeof' operation inside a struct. By doing this, the 'typeof' operation
can be split into two steps, deconfusing several compilers (notably VC7.1 and VC8.0) on the way.
This also removes the limitation imposed by `BOOST_TYPEOF_LIMIT_SIZE` and allows you to use 'typeof' on much
larger expressions.
If you want to use `typeof_nested_typedef` in a template-context, use `BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr)`,
which takes care of `typename` inside the `typeof` expression.
[h4 Sample Code]
template<typename A, typename B>
struct result_of_conditional
{
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested,true?A():B());
typedef typename nested::type type;
};
template<typename A, typename B>
result_of_conditional<A, B>::type min(const A& a,const B& b)
{
return a < b ? a : b;
}
[endsect]
[endsect]
[section:other Other considerations and tips]

View File

@ -17,8 +17,8 @@ can't bind a function pointer to const T&
namespace boost { namespace type_of {
template<class T>
sizer<typename encode_type<BOOST_TYPEOF_VECTOR(0)<>, T*>::type> encode(T*,
template<class V,class T>
sizer<typename encode_type<V, T*>::type> encode(T*,
typename enable_if<typename is_function<T>::type>::type* = 0);
}}

View File

@ -10,6 +10,7 @@
# include <boost/config.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/mpl/int.hpp>
namespace boost
{
@ -78,8 +79,8 @@ namespace boost
//Typeof code
# if BOOST_WORKAROUND(BOOST_MSVC,==1300)
template<int ID>
struct msvc_typeof_base
template<typename ID>
struct msvc_extract_type
{
template<bool>
struct id2type_impl;
@ -87,35 +88,36 @@ namespace boost
typedef id2type_impl<true> id2type;
};
template<typename T, int ID>
struct msvc_typeof : msvc_typeof_base<ID>
template<typename T, typename ID>
struct msvc_register_type : msvc_extract_type<ID>
{
template<>
struct id2type_impl<true>
struct id2type_impl<true> //VC7.0 specific bugfeature
{
typedef T type;
};
};
# else
template<int ID>
struct msvc_typeof_base
template<typename ID>
struct msvc_extract_type
{
struct id2type;
};
template<typename T, int ID>
struct msvc_typeof : msvc_typeof_base<ID>
template<typename T, typename ID>
struct msvc_register_type : msvc_extract_type<ID>
{
struct msvc_typeof_base<ID>::id2type // This uses nice VC6-VC7 bugfeature
typedef msvc_extract_type<ID> base_type;
struct base_type::id2type // This uses nice VC6.5 and VC7.1 bugfeature
{
typedef T type;
};
};
# endif
template<int ID>
struct msvc_typeid_wrapper {
typedef typename msvc_typeof_base<ID>::id2type id2type;
typedef typename msvc_extract_type<mpl::int_<ID> >::id2type id2type;
typedef typename id2type::type type;
};
//Workaround for ETI-bug for VC6 and VC7
@ -136,7 +138,7 @@ namespace boost
//Get the next available compile time constants index
BOOST_STATIC_CONSTANT(unsigned,value=BOOST_TYPEOF_INDEX(T));
//Instantiate the template
typedef typename msvc_typeof<T,value>::id2type type;
typedef typename msvc_register_type<T,mpl::int_<value> >::id2type type;
//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
@ -153,4 +155,22 @@ namespace boost
# define BOOST_TYPEOF_TPL(expr) typename BOOST_TYPEOF(expr)
# define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \
struct name {\
template<typename T>\
static boost::type_of::msvc_register_type<T,name> _typeof_register_function(const T&);\
BOOST_STATIC_CONSTANT(int,_typeof_register_value=sizeof(_typeof_register_function(expr)));\
typedef typename boost::type_of::msvc_extract_type<name>::id2type id2type;\
typedef typename id2type::type type;\
};
# define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \
struct name {\
template<typename T>\
static boost::type_of::msvc_register_type<T,name> _typeof_register_function(const T&);\
BOOST_STATIC_CONSTANT(int,_typeof_register_value=sizeof(_typeof_register_function(expr)));\
typedef boost::type_of::msvc_extract_type<name>::id2type id2type;\
typedef id2type::type type;\
};
#endif//BOOST_TYPEOF_MSVC_TYPEOF_IMPL_HPP_INCLUDED

View File

@ -144,6 +144,14 @@
# define BOOST_TYPEOF(expr) BOOST_TYPEOF_KEYWORD(boost::type_of::ensure_obj(expr))
# define BOOST_TYPEOF_TPL BOOST_TYPEOF
# define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \
struct name {\
typedef BOOST_TYPEOF_TPL(expr) type;\
};
# define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \
struct name {\
typedef BOOST_TYPEOF(expr) type;\
};
# endif
# define BOOST_TYPEOF_REGISTER_TYPE(x)
# define BOOST_TYPEOF_REGISTER_TEMPLATE(x, params)

View File

@ -16,8 +16,7 @@
#define BOOST_TYPEOF_sizer_item(z, n, _)\
char item ## n[V::item ## n ::value];
namespace boost { namespace type_of {
namespace boost { namespace type_of {
template<class V>
struct sizer
{
@ -28,8 +27,8 @@ namespace boost { namespace type_of {
BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_sizer_item, ~)
};
template<class T>
sizer<typename encode_type<BOOST_TYPEOF_VECTOR(0)<>, T>::type> encode(const T&);
template<class V,class T>
sizer<typename encode_type<V, T>::type> encode(const T&);
}}
#undef BOOST_TYPEOF_sizer_item
@ -44,7 +43,7 @@ namespace boost { namespace type_of {
}}
#define BOOST_TYPEOF_TYPEITEM(z, n, expr)\
boost::mpl::size_t<sizeof(boost::type_of::encode(expr).item ## n)>
boost::mpl::size_t<sizeof(boost::type_of::encode<BOOST_TYPEOF_VECTOR(0)<> >(expr).item ## n)>
#define BOOST_TYPEOF_ENCODED_VECTOR(Expr) \
BOOST_TYPEOF_VECTOR(BOOST_TYPEOF_LIMIT_SIZE)< \
@ -56,4 +55,54 @@ namespace boost { namespace type_of {
#define BOOST_TYPEOF_TPL typename BOOST_TYPEOF
//offset_vector is used to delay the insertion of data into the vector in order to allow
//encoding to be done in many steps
namespace boost { namespace type_of {
template<typename V,typename Offset>
struct offset_vector {
};
template<class V,class Offset,class T>
struct push_back<boost::type_of::offset_vector<V,Offset>,T> {
typedef offset_vector<V,typename Offset::prior> type;
};
template<class V,class T>
struct push_back<boost::type_of::offset_vector<V,mpl::size_t<0> >,T> {
typedef typename push_back<V,T>::type type;
};
}}
#define BOOST_TYPEOF_NESTED_TYPEITEM(z, n, expr)\
BOOST_STATIC_CONSTANT(int,BOOST_PP_CAT(value,n) = sizeof(boost::type_of::encode<_typeof_start_vector>(expr).item ## n));\
typedef boost::mpl::size_t<BOOST_PP_CAT(value,n)> BOOST_PP_CAT(item,n);
#define BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr) \
template<int _Typeof_Iteration>\
struct _typeof_encode_fraction {\
BOOST_STATIC_CONSTANT(int,_typeof_encode_offset = (_Typeof_Iteration*BOOST_TYPEOF_LIMIT_SIZE));\
typedef boost::type_of::offset_vector<BOOST_TYPEOF_VECTOR(0)<>,boost::mpl::size_t<_typeof_encode_offset> > _typeof_start_vector;\
BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE,BOOST_TYPEOF_NESTED_TYPEITEM,expr);\
};\
template<typename Pos>\
struct _typeof_fraction_iter {\
BOOST_STATIC_CONSTANT(int,pos=(Pos::value));\
BOOST_STATIC_CONSTANT(int,iteration=(pos/BOOST_TYPEOF_LIMIT_SIZE));\
BOOST_STATIC_CONSTANT(int,where=pos%BOOST_TYPEOF_LIMIT_SIZE);\
typedef typename boost::type_of::v_iter<_typeof_encode_fraction<iteration>,boost::mpl::int_<where> >::type type;\
typedef _typeof_fraction_iter<typename Pos::next> next;\
};
# define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \
struct name {\
BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr)\
typedef typename boost::type_of::decode_type<_typeof_fraction_iter<boost::mpl::size_t<0> > >::type type;\
};
# define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \
struct name {\
BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr)\
typedef boost::type_of::decode_type<_typeof_fraction_iter<boost::mpl::size_t<0> > >::type type;\
};
#endif//BOOST_TYPEOF_COMPLIANT_TYPEOF_IMPL_HPP_INCLUDED

View File

@ -84,7 +84,7 @@
namespace boost { namespace type_of {
template<class V, class Pos> struct v_iter; // not defined
template<class V, class Increase_BOOST_TYPEOF_LIMIT_SIZE> struct v_iter; // not defined
# define BOOST_PP_LOCAL_MACRO BOOST_TYPEOF_spec_iter
# define BOOST_PP_LOCAL_LIMITS \
(BOOST_PP_DEC(BOOST_TYPEOF_PP_START_SIZE), \
@ -138,7 +138,10 @@ namespace boost { namespace type_of {
namespace boost { namespace type_of {
template<class V, class T> struct push_back; // not defined
template<class V, class T> struct push_back {
typedef V type;
}; //default behaviour is to let push_back ignore T, and return the input vector.
//This is to let BOOST_TYPEOF_NESTED_TYPEDEF work properly with the default vector.
# define BOOST_PP_LOCAL_MACRO BOOST_TYPEOF_spec_push_back
# define BOOST_PP_LOCAL_LIMITS \
(BOOST_PP_DEC(BOOST_TYPEOF_PP_START_SIZE), \

View File

@ -9,7 +9,7 @@
namespace boost { namespace type_of {
template<class V, class Pos> struct v_iter;
template<class V, class Increase_BOOST_TYPEOF_LIMIT_SIZE> struct v_iter; // not defined
template<class V> struct v_iter<V, mpl::int_<0> > { typedef typename V::item0 type; typedef v_iter<V, mpl::int_<0 + 1> > next; };
template<class V> struct v_iter<V, mpl::int_<1> > { typedef typename V::item1 type; typedef v_iter<V, mpl::int_<1 + 1> > next; };
template<class V> struct v_iter<V, mpl::int_<2> > { typedef typename V::item2 type; typedef v_iter<V, mpl::int_<2 + 1> > next; };
@ -215,7 +215,9 @@ namespace boost { namespace type_of {
template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 , class P10 , class P11 , class P12 , class P13 , class P14 , class P15 , class P16 , class P17 , class P18 , class P19 , class P20 , class P21 , class P22 , class P23 , class P24 , class P25 , class P26 , class P27 , class P28 , class P29 , class P30 , class P31 , class P32 , class P33 , class P34 , class P35 , class P36 , class P37 , class P38 , class P39 , class P40 , class P41 , class P42 , class P43 , class P44 , class P45 , class P46 , class P47 , class P48 , class P49 , class P50 , class P51 , class P52 , class P53 , class P54 , class P55 , class P56 , class P57 , class P58 , class P59 , class P60 , class P61 , class P62 , class P63 , class P64 , class P65 , class P66 , class P67 , class P68 , class P69 , class P70 , class P71 , class P72 , class P73 , class P74 , class P75 , class P76 , class P77 , class P78 , class P79 , class P80 , class P81 , class P82 , class P83 , class P84 , class P85 , class P86 , class P87 , class P88 , class P89 , class P90 , class P91 , class P92 , class P93 , class P94 , class P95 , class P96 , class P97 , class P98 , class P99 > struct vector100 { typedef v_iter<vector100, boost::mpl::int_<0> > begin; typedef P0 item0; typedef P1 item1; typedef P2 item2; typedef P3 item3; typedef P4 item4; typedef P5 item5; typedef P6 item6; typedef P7 item7; typedef P8 item8; typedef P9 item9; typedef P10 item10; typedef P11 item11; typedef P12 item12; typedef P13 item13; typedef P14 item14; typedef P15 item15; typedef P16 item16; typedef P17 item17; typedef P18 item18; typedef P19 item19; typedef P20 item20; typedef P21 item21; typedef P22 item22; typedef P23 item23; typedef P24 item24; typedef P25 item25; typedef P26 item26; typedef P27 item27; typedef P28 item28; typedef P29 item29; typedef P30 item30; typedef P31 item31; typedef P32 item32; typedef P33 item33; typedef P34 item34; typedef P35 item35; typedef P36 item36; typedef P37 item37; typedef P38 item38; typedef P39 item39; typedef P40 item40; typedef P41 item41; typedef P42 item42; typedef P43 item43; typedef P44 item44; typedef P45 item45; typedef P46 item46; typedef P47 item47; typedef P48 item48; typedef P49 item49; typedef P50 item50; typedef P51 item51; typedef P52 item52; typedef P53 item53; typedef P54 item54; typedef P55 item55; typedef P56 item56; typedef P57 item57; typedef P58 item58; typedef P59 item59; typedef P60 item60; typedef P61 item61; typedef P62 item62; typedef P63 item63; typedef P64 item64; typedef P65 item65; typedef P66 item66; typedef P67 item67; typedef P68 item68; typedef P69 item69; typedef P70 item70; typedef P71 item71; typedef P72 item72; typedef P73 item73; typedef P74 item74; typedef P75 item75; typedef P76 item76; typedef P77 item77; typedef P78 item78; typedef P79 item79; typedef P80 item80; typedef P81 item81; typedef P82 item82; typedef P83 item83; typedef P84 item84; typedef P85 item85; typedef P86 item86; typedef P87 item87; typedef P88 item88; typedef P89 item89; typedef P90 item90; typedef P91 item91; typedef P92 item92; typedef P93 item93; typedef P94 item94; typedef P95 item95; typedef P96 item96; typedef P97 item97; typedef P98 item98; typedef P99 item99; typedef mpl::int_<1> item100; typedef mpl::int_<1> item101; typedef mpl::int_<1> item102; typedef mpl::int_<1> item103; typedef mpl::int_<1> item104; typedef mpl::int_<1> item105; typedef mpl::int_<1> item106; typedef mpl::int_<1> item107; typedef mpl::int_<1> item108; typedef mpl::int_<1> item109; typedef mpl::int_<1> item110; typedef mpl::int_<1> item111; typedef mpl::int_<1> item112; typedef mpl::int_<1> item113; typedef mpl::int_<1> item114; typedef mpl::int_<1> item115; typedef mpl::int_<1> item116; typedef mpl::int_<1> item117; typedef mpl::int_<1> item118; typedef mpl::int_<1> item119; typedef mpl::int_<1> item120; typedef mpl::int_<1> item121; typedef mpl::int_<1> item122; typedef mpl::int_<1> item123; typedef mpl::int_<1> item124; typedef mpl::int_<1> item125; typedef mpl::int_<1> item126; typedef mpl::int_<1> item127; typedef mpl::int_<1> item128; typedef mpl::int_<1> item129; typedef mpl::int_<1> item130; typedef mpl::int_<1> item131; typedef mpl::int_<1> item132; typedef mpl::int_<1> item133; typedef mpl::int_<1> item134; typedef mpl::int_<1> item135; typedef mpl::int_<1> item136; typedef mpl::int_<1> item137; typedef mpl::int_<1> item138; typedef mpl::int_<1> item139; typedef mpl::int_<1> item140; typedef mpl::int_<1> item141; typedef mpl::int_<1> item142; typedef mpl::int_<1> item143; typedef mpl::int_<1> item144; typedef mpl::int_<1> item145; typedef mpl::int_<1> item146; typedef mpl::int_<1> item147; typedef mpl::int_<1> item148; };
}}
namespace boost { namespace type_of {
template<class V, class T> struct push_back;
template<class V, class T> struct push_back {
typedef V type;
};
template< class T> struct push_back<boost::type_of::vector0<>, T> { typedef boost::type_of::vector1< T > type; };
template< class P0 , class T> struct push_back<boost::type_of::vector1< P0>, T> { typedef boost::type_of::vector2< P0 , T > type; };
template< class P0 , class P1 , class T> struct push_back<boost::type_of::vector2< P0 , P1>, T> { typedef boost::type_of::vector3< P0 , P1 , T > type; };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
namespace boost { namespace type_of {
template<class V, class Pos> struct v_iter;
template<class V, class Increase_BOOST_TYPEOF_LIMIT_SIZE> struct v_iter; // not defined
template<class V> struct v_iter<V, mpl::int_<0> > { typedef typename V::item0 type; typedef v_iter<V, mpl::int_<0 + 1> > next; };
template<class V> struct v_iter<V, mpl::int_<1> > { typedef typename V::item1 type; typedef v_iter<V, mpl::int_<1 + 1> > next; };
template<class V> struct v_iter<V, mpl::int_<2> > { typedef typename V::item2 type; typedef v_iter<V, mpl::int_<2 + 1> > next; };
@ -115,7 +115,9 @@ namespace boost { namespace type_of {
template< class P0 , class P1 , class P2 , class P3 , class P4 , class P5 , class P6 , class P7 , class P8 , class P9 , class P10 , class P11 , class P12 , class P13 , class P14 , class P15 , class P16 , class P17 , class P18 , class P19 , class P20 , class P21 , class P22 , class P23 , class P24 , class P25 , class P26 , class P27 , class P28 , class P29 , class P30 , class P31 , class P32 , class P33 , class P34 , class P35 , class P36 , class P37 , class P38 , class P39 , class P40 , class P41 , class P42 , class P43 , class P44 , class P45 , class P46 , class P47 , class P48 , class P49 > struct vector50 { typedef v_iter<vector50, boost::mpl::int_<0> > begin; typedef P0 item0; typedef P1 item1; typedef P2 item2; typedef P3 item3; typedef P4 item4; typedef P5 item5; typedef P6 item6; typedef P7 item7; typedef P8 item8; typedef P9 item9; typedef P10 item10; typedef P11 item11; typedef P12 item12; typedef P13 item13; typedef P14 item14; typedef P15 item15; typedef P16 item16; typedef P17 item17; typedef P18 item18; typedef P19 item19; typedef P20 item20; typedef P21 item21; typedef P22 item22; typedef P23 item23; typedef P24 item24; typedef P25 item25; typedef P26 item26; typedef P27 item27; typedef P28 item28; typedef P29 item29; typedef P30 item30; typedef P31 item31; typedef P32 item32; typedef P33 item33; typedef P34 item34; typedef P35 item35; typedef P36 item36; typedef P37 item37; typedef P38 item38; typedef P39 item39; typedef P40 item40; typedef P41 item41; typedef P42 item42; typedef P43 item43; typedef P44 item44; typedef P45 item45; typedef P46 item46; typedef P47 item47; typedef P48 item48; typedef P49 item49; typedef mpl::int_<1> item50; typedef mpl::int_<1> item51; typedef mpl::int_<1> item52; typedef mpl::int_<1> item53; typedef mpl::int_<1> item54; typedef mpl::int_<1> item55; typedef mpl::int_<1> item56; typedef mpl::int_<1> item57; typedef mpl::int_<1> item58; typedef mpl::int_<1> item59; typedef mpl::int_<1> item60; typedef mpl::int_<1> item61; typedef mpl::int_<1> item62; typedef mpl::int_<1> item63; typedef mpl::int_<1> item64; typedef mpl::int_<1> item65; typedef mpl::int_<1> item66; typedef mpl::int_<1> item67; typedef mpl::int_<1> item68; typedef mpl::int_<1> item69; typedef mpl::int_<1> item70; typedef mpl::int_<1> item71; typedef mpl::int_<1> item72; typedef mpl::int_<1> item73; typedef mpl::int_<1> item74; typedef mpl::int_<1> item75; typedef mpl::int_<1> item76; typedef mpl::int_<1> item77; typedef mpl::int_<1> item78; typedef mpl::int_<1> item79; typedef mpl::int_<1> item80; typedef mpl::int_<1> item81; typedef mpl::int_<1> item82; typedef mpl::int_<1> item83; typedef mpl::int_<1> item84; typedef mpl::int_<1> item85; typedef mpl::int_<1> item86; typedef mpl::int_<1> item87; typedef mpl::int_<1> item88; typedef mpl::int_<1> item89; typedef mpl::int_<1> item90; typedef mpl::int_<1> item91; typedef mpl::int_<1> item92; typedef mpl::int_<1> item93; typedef mpl::int_<1> item94; typedef mpl::int_<1> item95; typedef mpl::int_<1> item96; typedef mpl::int_<1> item97; typedef mpl::int_<1> item98; typedef mpl::int_<1> item99; };
}}
namespace boost { namespace type_of {
template<class V, class T> struct push_back;
template<class V, class T> struct push_back {
typedef V type;
};
template< class T> struct push_back<boost::type_of::vector0<>, T> { typedef boost::type_of::vector1< T > type; };
template< class P0 , class T> struct push_back<boost::type_of::vector1< P0>, T> { typedef boost::type_of::vector2< P0 , T > type; };
template< class P0 , class P1 , class T> struct push_back<boost::type_of::vector2< P0 , P1>, T> { typedef boost::type_of::vector3< P0 , P1 , T > type; };

View File

@ -73,4 +73,7 @@ test-suite "typeof"
[ compile function_ptr_from_tpl.cpp : <define>BOOST_TYPEOF_NATIVE special-requirements : function_ptr_from_tpl_native ]
[ compile function_ptr_from_tpl.cpp : <define>BOOST_TYPEOF_COMPLIANT special-requirements : function_ptr_from_tpl_emulation ]
[ compile nested_typedef.cpp : <define>BOOST_TYPEOF_NATIVE special-requirements : nested_typedef_native ]
[ compile nested_typedef.cpp : <define>BOOST_TYPEOF_COMPLIANT special-requirements : nested_typedef_emulation ]
;

34
test/nested_typedef.cpp Normal file
View File

@ -0,0 +1,34 @@
#include <boost/typeof/typeof.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
void do_int(int) {}
struct {
template<typename T>
T operator[](const T&) {}
} int_p;
template<typename T> struct wrap
{
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested,int_p[& do_int]);
typedef typename nested::type type;
};
BOOST_TYPEOF_REGISTER_TEMPLATE(wrap,1)
template<typename T> struct parser
{
struct __rule {
static T & a_placeholder;
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested,int_p[a_placeholder]);
typedef typename nested::type type;
};
};
BOOST_STATIC_ASSERT((boost::is_same<wrap<double>::type,void(*)(int)>::value));
BOOST_STATIC_ASSERT((boost::is_same<parser<wrap<double> >::__rule::type,wrap<double> >::value));