diff --git a/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst b/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst index bcf19bb..e6c8766 100644 --- a/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst +++ b/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst @@ -13,7 +13,7 @@ Synopsis .. parsed-literal:: - #define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \\ + #define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \\ |unspecified-token-seq| \\ /\*\*/ @@ -21,17 +21,16 @@ Synopsis Description ----------- -Expands into the definition of a boolean n-ary |Metafunction| -``has_name`` such that for any types ``x, a1, a2, ..., an`` -``has_name::value == true`` if and only if ``x`` is a -class type and has a nested template member ``x::template name``. +Expands into the definition of a boolean |Metafunction| ``has_name`` +such that for any type ``x`` ``has_name::value == true`` if and +only if ``x`` is a class type and has a nested template member +``x::template name`` with no more than +|BOOST_MPL_LIMIT_METAFUNCTION_ARITY| parameters. On deficient compilers not capable of performing the detection, -``has_name::value`` always returns ``false``. A -boolean configuration macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is -provided to signal or override the "deficient" status of a particular -compiler. +``has_name::value`` is always ``false``. A boolean configuration +macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is provided to signal or +override the "deficient" status of a particular compiler. |Note:| |BOOST_MPL_HAS_XXX_TEMPLATE_DEF| is a simplified front end to the |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| introspection macro |-- end @@ -55,19 +54,16 @@ Parameters +===============+===============================+===================================================+ | ``name`` | A legal identifier token | A name of the template member being detected. | +---------------+-------------------------------+---------------------------------------------------+ -| ``n`` | An integral constant >= 0 | The arity of the template member being detected. | -+---------------+-------------------------------+---------------------------------------------------+ Expression semantics -------------------- -For any legal C++ identifier ``name`` and integral constant expression -``n`` greater than or equal to 0: +For any legal C++ identifier ``name``: .. parsed-literal:: - BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) + BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) :Precondition: Appears at namespace scope. @@ -81,7 +77,7 @@ For any legal C++ identifier ``name`` and integral constant expression .. parsed-literal:: BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( - BOOST_PP_CAT(has\_,name), name, n, false + BOOST_PP_CAT(has\_,name), name, false ) @@ -90,7 +86,7 @@ Example .. parsed-literal:: - BOOST_MPL_HAS_XXX_TEMPLATE_DEF(xxx, 1) + BOOST_MPL_HAS_XXX_TEMPLATE_DEF(xxx) struct test1 {}; struct test2 { void xxx(); }; @@ -102,24 +98,25 @@ Example struct test8 { typedef void (xxx)(); }; struct test9 { template< class T > struct xxx {}; }; - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) - BOOST_MPL_ASSERT(( has_xxx )); + BOOST_MPL_ASSERT(( has_xxx )); #endif - BOOST_MPL_ASSERT(( has_xxx )); + BOOST_MPL_ASSERT(( has_xxx )); See also -------- -|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| +|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF|, +|BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, |BOOST_MPL_LIMIT_METAFUNCTION_ARITY| diff --git a/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst b/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst index 93706d3..b715cc0 100644 --- a/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst +++ b/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst @@ -13,7 +13,7 @@ Synopsis .. parsed-literal:: - #define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default\_) \\ + #define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default\_) \\ |unspecified-token-seq| \\ /\*\*/ @@ -21,19 +21,19 @@ Synopsis Description ----------- -Expands into the definition of a boolean n-ary |Metafunction| ``trait`` -such that for any types ``x, a1, a2, ..., an`` ``trait::value == true`` if and only if ``x`` is a class type and has a -nested template member ``x::template name``. +Expands into the definition of a boolean |Metafunction| ``trait`` such +that for any type ``x`` ``trait::value == true`` if and only if +``x`` is a class type and has a nested template member ``x::template +name`` with no more than |BOOST_MPL_LIMIT_METAFUNCTION_ARITY| +parameters. On deficient compilers not capable of performing the detection, -``trait::value`` always returns a fallback value -``default_``. A boolean configuration macro, -|BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is provided to signal or override -the "deficient" status of a particular compiler. |Note:| The fallback -value can also be provided at the point of the metafunction -invocation; see the `Expression semantics` section for details |-- end -note| +``trait::value`` always returns a fallback value ``default_``. A +boolean configuration macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is +provided to signal or override the "deficient" status of a particular +compiler. |Note:| The fallback value can also be provided at the +point of the metafunction invocation; see the `Expression semantics` +section for details |-- end note| Header @@ -54,8 +54,6 @@ Parameters +---------------+-------------------------------+---------------------------------------------------+ | ``name`` | A legal identifier token | A name of the member being detected. | +---------------+-------------------------------+---------------------------------------------------+ -| ``n`` | An integral constant >= 0 | The arity of the template member being detected. | -+---------------+-------------------------------+---------------------------------------------------+ | ``default_`` | An boolean constant | A fallback value for the deficient compilers. | +---------------+-------------------------------+---------------------------------------------------+ @@ -63,14 +61,13 @@ Parameters Expression semantics -------------------- -For any legal C++ identifiers ``trait`` and ``name``, integral -constant expression ``n`` greater than or equal to 0, boolean constant +For any legal C++ identifiers ``trait`` and ``name``, boolean constant expression ``c1``, boolean |Integral Constant| ``c2``, and arbitrary type ``x``: .. parsed-literal:: - BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, c1) + BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, c1) :Precondition: Appears at namespace scope. @@ -86,7 +83,6 @@ type ``x``: template< typename X - , typename A1, ..., typename An , typename fallback = boost::mpl::bool\_ > struct trait @@ -100,7 +96,7 @@ type ``x``: .. parsed-literal:: - typedef trait::type r; + typedef trait::type r; :Return type: |Integral Constant|. @@ -108,13 +104,13 @@ type ``x``: :Semantics: If |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| is defined, ``r::value == c1``; otherwise, ``r::value == true`` if and only if ``x`` - is a class type that has a nested type member ``x::template - name``. + is a class type that has a nested template member ``x::template + name`` with no more than |BOOST_MPL_LIMIT_METAFUNCTION_ARITY|. .. parsed-literal:: - typedef trait< x, a1, ..., an, c2 >::type r; + typedef trait< x, c2 >::type r; :Return type: |Integral Constant|. @@ -125,7 +121,7 @@ type ``x``: .. parsed-literal:: - typedef trait::type r; + typedef trait::type r; Example @@ -134,7 +130,7 @@ Example .. parsed-literal:: BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( - has_xxx, xxx, 1, false + has_xxx, xxx, false ) struct test1 {}; @@ -147,24 +143,25 @@ Example struct test8 { typedef void (xxx)(); }; struct test9 { template< class T > struct xxx {}; }; - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) - BOOST_MPL_ASSERT(( has_xxx )); + BOOST_MPL_ASSERT(( has_xxx )); #endif - BOOST_MPL_ASSERT(( has_xxx )); + BOOST_MPL_ASSERT(( has_xxx )); See also -------- -|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| +|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, +|BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, |BOOST_MPL_LIMIT_METAFUNCTION_ARITY| diff --git a/include/boost/mpl/has_xxx.hpp b/include/boost/mpl/has_xxx.hpp index 4b201d8..4ef0196 100644 --- a/include/boost/mpl/has_xxx.hpp +++ b/include/boost/mpl/has_xxx.hpp @@ -280,12 +280,11 @@ struct trait \ #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) -// Create boolean n-ary Metafunction to detect a nested template -// member with n template parameters. This implementation is based on -// a USENET newsgroup's posting by Aleksey Gurtovoy -// (comp.lang.c++.moderated, 2002-03-19), Rani Sharoni's USENET -// posting cited above, the non-template has_xxx implementations -// above, and discussion on the Boost mailing list. +// Create a boolean Metafunction to detect a nested template +// member. This implementation is based on a USENET newsgroup's +// posting by Aleksey Gurtovoy (comp.lang.c++.moderated, 2002-03-19), +// Rani Sharoni's USENET posting cited above, the non-template has_xxx +// implementations above, and discussion on the Boost mailing list. # if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) @@ -294,35 +293,27 @@ struct trait \ # endif # if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION) -# if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) \ - || BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303)) +# if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)) # define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1 # endif # endif -# if !defined(BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE) -# if BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303) -# define BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE 1 -# endif -# endif - # if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) # define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1 # endif # endif -// NOTE: All internal implementation macros take a Boost.Preprocessor -// array argument called args which contains the arguments passed to -// HAS_XXX_TEMPLATE_NAMED_DEF and is of the following form. -// ( 4, ( trait, name, n, default_ ) ) +// NOTE: Many internal implementation macros take a Boost.Preprocessor +// array argument called args which is of the following form. +// ( 4, ( trait, name, max_arity, default_ ) ) # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \ /**/ -# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ - BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute) \ +# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ + BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute), n) \ /**/ # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \ @@ -332,13 +323,23 @@ struct trait \ // Thanks to Guillaume Melquiond for pointing out the need for the // "substitute" template as an argument to the overloaded test // functions to get SFINAE to work for member templates with the -// correct name but incorrect arguments. -# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ - template< substitute_macro(args, V) > \ - struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) { \ +// correct name but different number of arguments. +# define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE(z, n, args) \ + template< \ + template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename V) > class V \ + > \ + struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) { \ }; \ /**/ +# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE \ + , args \ + ) \ + /**/ + # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ template< typename V > \ @@ -353,16 +354,23 @@ struct trait \ # endif # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES -# define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ +# define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \ template< typename V > \ static boost::mpl::aux::yes_tag \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ boost::mpl::aux::type_wrapper< V > const volatile* \ - , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) < \ - member_macro(args, V, T) \ + , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) < \ + V::template BOOST_PP_ARRAY_ELEM(1, args) \ >* = 0 \ ); \ /**/ +# define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT \ + , args \ + ) \ + /**/ # else # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ template< typename V > \ @@ -419,9 +427,6 @@ struct trait \ ) \ template< \ typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS( \ - BOOST_PP_ARRAY_ELEM(2, args), typename T \ - ) \ , typename fallback_ \ = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \ > \ @@ -436,45 +441,9 @@ struct trait \ }; \ /**/ -// For example, -// BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( -// (4, (has_xxx, xxx, 2, false)) -// , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER -// , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS -// ) -// expands to something like the following... -// -// template< -// typename T , typename T0 , typename T1 -// , typename fallback_ = boost::mpl::bool_< false > -// > -// class has_xxx { -// template< typename U > -// struct has_xxx_introspect { -// template< template< typename V0 , typename V1 > class V > -// struct has_xxx_substitute { -// }; -// -// template< typename V > -// static boost::mpl::aux::no_tag -// has_xxx_test(...); -// -// template< typename V > -// static boost::mpl::aux::yes_tag -// has_xxx_test( -// boost::mpl::aux::type_wrapper< V > const volatile* -// , has_xxx_substitute < V::template xxx >* = 0 -// ); -// -// static const bool value -// = sizeof(has_xxx_test< U >(0)) -// == sizeof(boost::mpl::aux::yes_tag); -// typedef boost::mpl::bool_< value > type; -// }; -// public: -// static const bool value = has_xxx_introspect< T >::value; -// typedef typename has_xxx_introspect< T >::type type; -// }; +// BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE expands to the full +// implementation of the function-based metafunction. Compile with -E +// to see the preprocessor output for this macro. # define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ args, substitute_macro, member_macro \ ) \ @@ -496,17 +465,17 @@ struct trait \ # if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, n \ ) \ - BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ /**/ # else # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, n \ ) \ BOOST_PP_CAT( \ boost_mpl_has_xxx_ \ - , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ + , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ ) \ /**/ # endif @@ -516,20 +485,20 @@ struct trait \ ) \ BOOST_PP_CAT( \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, 0 \ ) \ , _tag \ ) \ /**/ -# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro \ +# define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + z, n, args \ ) \ - typedef void \ - BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ - template< substitute_macro(args, U) > \ + template< \ + template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename U) > class U \ + > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, n \ ) { \ typedef \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ @@ -537,14 +506,23 @@ struct trait \ }; \ /**/ +# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + args, substitute_macro \ + ) \ + typedef void \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE \ + , args \ + ) \ + /**/ + # define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \ args, member_macro \ ) \ template< \ typename U \ - BOOST_PP_ENUM_TRAILING_PARAMS( \ - BOOST_PP_ARRAY_ELEM(2, args), typename U \ - ) \ , typename V \ = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ > \ @@ -554,22 +532,17 @@ struct trait \ }; \ /**/ -# define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \ - args, member_macro \ +# define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE( \ + z, n, args \ ) \ - template< \ - typename U \ - BOOST_PP_ENUM_TRAILING_PARAMS( \ - BOOST_PP_ARRAY_ELEM(2, args), typename U \ - ) \ - > \ + template< typename U > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ - U BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), U) \ + U \ , typename \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, n \ )< \ - member_macro(args, U, U) \ + BOOST_MSVC_TYPENAME U::BOOST_PP_ARRAY_ELEM(1, args)< > \ >::type \ > { \ BOOST_STATIC_CONSTANT(bool, value = true); \ @@ -577,89 +550,30 @@ struct trait \ }; \ /**/ -# define BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ +# define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \ + args, member_macro \ + ) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE \ + , args \ + ) \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ args, substitute_macro, member_macro \ ) \ BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \ BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \ template< typename U > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ - : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ - U \ - BOOST_PP_ENUM_TRAILING_PARAMS( \ - BOOST_PP_ARRAY_ELEM(2, args) \ - , T \ - ) \ - > { \ + : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U > { \ }; \ /**/ - -# if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE -# define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro, member_macro \ - ) \ - BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro \ - ) \ - BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro, member_macro \ - ) \ - /**/ -# else -# define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro, member_macro \ - ) \ - BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro, member_macro \ - ) \ - /**/ -# endif - -// For example, -// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( -// (4, (has_xxx, xxx, 2, false)) -// , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER -// , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS -// ) -// expands to something like the following... -// -// template< -// typename T , typename T0 , typename T1 -// , typename fallback_ = boost::mpl::bool_< false > -// > -// class has_xxx { -// typedef void has_xxx_substitute_tag; -// -// template< template< typename U0 , typename U1 > class U > -// struct has_xxx_substitute { -// typedef has_xxx_substitute_tag type; -// }; -// -// template< -// typename U , typename U0 , typename U1 -// , typename V = has_xxx_substitute_tag -// > -// struct has_xxx_test { -// static const bool value = false; -// typedef boost::mpl::bool_< value > type; -// }; -// -// template< typename U , typename U0 , typename U1 > -// struct has_xxx_test< -// U , U0 , U1 -// , typename has_xxx_substitute< U::template xxx >::type -// > { -// static const bool value = true; -// typedef boost::mpl::bool_< value > type; -// }; -// -// template< typename U > -// struct has_xxx_introspect : has_xxx_test< U , T0 , T1 > { -// }; -// public: -// static const bool value = has_xxx_introspect< T >::value; -// typedef typename has_xxx_introspect< T >::type type; -// }; + +// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE expands to the full +// implementation of the template-based metafunction. Compile with -E +// to see the preprocessor output for this macro. // // Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is // defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs @@ -668,6 +582,9 @@ struct trait \ # define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ args, substitute_macro, member_macro \ ) \ + BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + args, substitute_macro \ + ) \ BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ args \ , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \ @@ -678,130 +595,22 @@ struct trait \ # endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER( \ - args, param \ - ) \ - typename \ - /**/ - -# if !BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_SUBSTITUTE_PARAMETER( \ - args, param \ - ) \ - template< \ - BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), typename param) \ - > \ - class param\ - /**/ - -// See comment at BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS below. -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER(args, param) \ - BOOST_PP_IF( \ - BOOST_PP_ARRAY_ELEM(2, args) \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_SUBSTITUTE_PARAMETER \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER \ - ) ( args, param ) \ - /**/ -# else -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER(args, param) \ - BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER( \ - args, param \ - ) \ - /**/ -# endif - -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS( \ - args, class_type, param \ - ) \ - typename class_type::template BOOST_PP_ARRAY_ELEM(1, args)< \ - BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), param) \ - > \ - /**/ - -# if !BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_ACCESS( \ - args, class_type, param \ - ) \ - class_type::template BOOST_PP_ARRAY_ELEM(1, args) \ - /**/ - -// Note: to recognize templates with no required arguments use -// explicit access since a substitute template with no args cannot be -// declared. -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS(args, class_type, param) \ - BOOST_PP_IF( \ - BOOST_PP_ARRAY_ELEM(2, args) \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_ACCESS \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS \ - ) ( args, class_type, param ) \ - /**/ -# else -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS(args, class_type, param) \ - BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS( \ - args, class_type, param \ - ) \ - /**/ -# endif - -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) -// MSVC (7.1, 8.0) accepts the member template access syntax below -// regardless of the member template's arity. introspect will reject -// member templates with the wrong arity due to the substitute -// template. Note that using this syntax also enables MSVC -// template-based SFINAE to reject non-template members. This is -// important because explicitly passing the template args will match -// templates with the correct name and arguments but will cause ICE on -// non-template members. However, MSVC nullary template-based SFINAE -// (introspection for a member template with no required args) can not -// reject non-template members, but MSVC function-based SFINAE -// can. So, one of the two is chosen based on the number of required -// template parameters. -# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC( \ - args, class_type, param \ - ) \ - typename class_type::template BOOST_PP_ARRAY_ELEM(1, args)< > \ - /**/ -# else -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC( \ - args, class_type, param \ - ) \ - class_type::BOOST_PP_ARRAY_ELEM(1, agrs)< > \ - /**/ -# endif - -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_MSVC( \ - args, substitute_macro, member_macro \ - ) \ - BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro \ - ) \ - BOOST_PP_IF( \ - BOOST_PP_ARRAY_ELEM(2, args) \ - , BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE \ - , BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE \ - ) ( \ - args \ - , substitute_macro \ - , member_macro \ - ) \ - /**/ -# endif - +// Note: In the current implementation the parameter and access macros +// are no longer expanded. # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) -# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ - ( 4, ( trait, name, n, default_ ) ) \ + ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ ) \ /**/ # else -# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ - BOOST_MPL_HAS_MEMBER_TEMPLATE_MSVC( \ - ( 4, ( trait, name, n, default_ ) ) \ +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ + BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ + ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC \ + , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ ) \ /**/ # endif @@ -810,9 +619,8 @@ struct trait \ // placeholder implementation -# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ template< typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, typename U) \ , typename fallback_ = boost::mpl::bool_< default_ > > \ struct trait { \ BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \ @@ -822,9 +630,9 @@ struct trait \ #endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE -# define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \ +# define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \ BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \ - BOOST_PP_CAT(has_, name), name, n, false \ + BOOST_PP_CAT(has_, name), name, false \ ) \ /**/ diff --git a/test/has_xxx.cpp b/test/has_xxx.cpp index f755ae5..c466db2 100644 --- a/test/has_xxx.cpp +++ b/test/has_xxx.cpp @@ -17,12 +17,8 @@ #include BOOST_MPL_HAS_XXX_TRAIT_DEF(xxx) -BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx0, xxx, 0, false) -BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx1, xxx, 1, false) -BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx2, xxx, 2, false) -BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy0, 0) -BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy1, 1) -BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy2, 2) +BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx_template, xxx, false) +BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy) struct a1 {}; struct a2 { void xxx(); }; @@ -38,12 +34,13 @@ struct b5 { typedef int xxx[10]; }; struct b6 { typedef void (*xxx)(); }; struct b7 { typedef void (xxx)(); }; -struct c0 { template< typename T0 = int > struct xxx {}; }; -struct c1 { template< typename T1 > struct xxx {}; }; +struct c1 { template< typename T > struct xxx {}; }; struct c2 { template< typename T1, typename T2 > struct xxx {}; }; -struct c3 { template< typename T0 = int > struct yyy0 {}; }; -struct c4 { template< typename T1 > struct yyy1 {}; }; -struct c5 { template< typename T1, typename T2 > struct yyy2 {}; }; +struct c3 { template< typename T1, typename T2, typename T3 > struct xxx {}; }; +struct c4 { template< typename T1, typename T2, typename T3, typename T4 > struct xxx {}; }; +struct c5 { template< typename T1, typename T2, typename T3, typename T4, typename T5 > struct xxx {}; }; +struct c6 { template< typename T > struct yyy {}; }; +struct c7 { template< typename T1, typename T2 > struct yyy {}; }; template< typename T > struct outer; template< typename T > struct inner { typedef typename T::type type; }; @@ -56,195 +53,80 @@ template< typename T > struct xxx; MPL_TEST_CASE() { MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int > )); - MPL_ASSERT_NOT(( has_xxx1< int, int > )); - MPL_ASSERT_NOT(( has_xxx2< int, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int > )); - MPL_ASSERT_NOT(( has_yyy1< int, int > )); - MPL_ASSERT_NOT(( has_yyy2< int, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int& > )); - MPL_ASSERT_NOT(( has_xxx1< int&, int > )); - MPL_ASSERT_NOT(( has_xxx2< int&, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int& > )); - MPL_ASSERT_NOT(( has_yyy1< int&, int > )); - MPL_ASSERT_NOT(( has_yyy2< int&, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int* > )); - MPL_ASSERT_NOT(( has_xxx1< int*, int > )); - MPL_ASSERT_NOT(( has_xxx2< int*, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int* > )); - MPL_ASSERT_NOT(( has_yyy1< int*, int > )); - MPL_ASSERT_NOT(( has_yyy2< int*, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int[] > )); - MPL_ASSERT_NOT(( has_xxx1< int[], int > )); - MPL_ASSERT_NOT(( has_xxx2< int[], int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int[] > )); - MPL_ASSERT_NOT(( has_yyy1< int[], int > )); - MPL_ASSERT_NOT(( has_yyy2< int[], int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int (*)() > )); - MPL_ASSERT_NOT(( has_xxx1< int (*)(), int > )); - MPL_ASSERT_NOT(( has_xxx2< int (*)(), int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int (*)() > )); - MPL_ASSERT_NOT(( has_yyy1< int (*)(), int > )); - MPL_ASSERT_NOT(( has_yyy2< int (*)(), int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< a2 > )); - MPL_ASSERT_NOT(( has_xxx1< a2, int > )); - MPL_ASSERT_NOT(( has_xxx2< a2, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< a2 > )); - MPL_ASSERT_NOT(( has_yyy1< a2, int > )); - MPL_ASSERT_NOT(( has_yyy2< a2, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< a3 > )); - MPL_ASSERT_NOT(( has_xxx1< a3, int > )); - MPL_ASSERT_NOT(( has_xxx2< a3, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< a3 > )); - MPL_ASSERT_NOT(( has_yyy1< a3, int > )); - MPL_ASSERT_NOT(( has_yyy2< a3, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< a4 > )); - MPL_ASSERT_NOT(( has_xxx1< a4, int > )); - MPL_ASSERT_NOT(( has_xxx2< a4, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< a4 > )); - MPL_ASSERT_NOT(( has_yyy1< a4, int > )); - MPL_ASSERT_NOT(( has_yyy2< a4, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) MPL_ASSERT_NOT(( has_xxx )); + MPL_ASSERT(( has_xxx_template )); #endif MPL_ASSERT_NOT(( has_xxx< enum_ > )); - MPL_ASSERT_NOT(( has_xxx0< enum_ > )); - MPL_ASSERT_NOT(( has_xxx1< enum_, int > )); - MPL_ASSERT_NOT(( has_xxx2< enum_, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< enum_ > )); - MPL_ASSERT_NOT(( has_yyy1< enum_, int > )); - MPL_ASSERT_NOT(( has_yyy2< enum_, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< enum_ > )); #endif MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< a1 > )); - MPL_ASSERT_NOT(( has_xxx1< a1, int > )); - MPL_ASSERT_NOT(( has_xxx2< a1, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< a1 > )); - MPL_ASSERT_NOT(( has_yyy1< a1, int > )); - MPL_ASSERT_NOT(( has_yyy2< a1, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx< outer< inner > > )); - MPL_ASSERT_NOT(( has_xxx0< outer< inner > > )); - MPL_ASSERT_NOT(( has_xxx1< outer< inner >, int > )); - MPL_ASSERT_NOT(( has_xxx2< outer< inner >, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< outer< inner > > )); - MPL_ASSERT_NOT(( has_yyy1< outer< inner >, int > )); - MPL_ASSERT_NOT(( has_yyy2< outer< inner >, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< outer< inner > > )); MPL_ASSERT_NOT(( has_xxx< incomplete > )); - MPL_ASSERT_NOT(( has_xxx0< incomplete > )); - MPL_ASSERT_NOT(( has_xxx1< incomplete, int > )); - MPL_ASSERT_NOT(( has_xxx2< incomplete, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< incomplete > )); - MPL_ASSERT_NOT(( has_yyy1< incomplete, int > )); - MPL_ASSERT_NOT(( has_yyy2< incomplete, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< incomplete > )); MPL_ASSERT_NOT(( has_xxx< abstract > )); - MPL_ASSERT_NOT(( has_xxx0< abstract > )); - MPL_ASSERT_NOT(( has_xxx1< abstract, int > )); - MPL_ASSERT_NOT(( has_xxx2< abstract, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< abstract > )); - MPL_ASSERT_NOT(( has_yyy1< abstract, int > )); - MPL_ASSERT_NOT(( has_yyy2< abstract, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< abstract > )); MPL_ASSERT_NOT(( has_xxx< noncopyable > )); - MPL_ASSERT_NOT(( has_xxx0< noncopyable > )); - MPL_ASSERT_NOT(( has_xxx1< noncopyable, int > )); - MPL_ASSERT_NOT(( has_xxx2< noncopyable, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< noncopyable > )); - MPL_ASSERT_NOT(( has_yyy1< noncopyable, int > )); - MPL_ASSERT_NOT(( has_yyy2< noncopyable, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< noncopyable > )); #if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) - MPL_ASSERT_NOT(( has_xxx0< b1 > )); - MPL_ASSERT_NOT(( has_xxx1< b1, int > )); - MPL_ASSERT_NOT(( has_xxx2< b1, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b1 > )); - MPL_ASSERT_NOT(( has_yyy1< b1, int > )); - MPL_ASSERT_NOT(( has_yyy2< b1, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b2 > )); - MPL_ASSERT_NOT(( has_xxx1< b2, int > )); - MPL_ASSERT_NOT(( has_xxx2< b2, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b2 > )); - MPL_ASSERT_NOT(( has_yyy1< b2, int > )); - MPL_ASSERT_NOT(( has_yyy2< b2, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b3 > )); - MPL_ASSERT_NOT(( has_xxx1< b3, int > )); - MPL_ASSERT_NOT(( has_xxx2< b3, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b3 > )); - MPL_ASSERT_NOT(( has_yyy1< b3, int > )); - MPL_ASSERT_NOT(( has_yyy2< b3, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b4 > )); - MPL_ASSERT_NOT(( has_xxx1< b4, int > )); - MPL_ASSERT_NOT(( has_xxx2< b4, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b4 > )); - MPL_ASSERT_NOT(( has_yyy1< b4, int > )); - MPL_ASSERT_NOT(( has_yyy2< b4, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b5 > )); - MPL_ASSERT_NOT(( has_xxx1< b5, int > )); - MPL_ASSERT_NOT(( has_xxx2< b5, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b5 > )); - MPL_ASSERT_NOT(( has_yyy1< b5, int > )); - MPL_ASSERT_NOT(( has_yyy2< b5, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b6 > )); - MPL_ASSERT_NOT(( has_xxx1< b6, int > )); - MPL_ASSERT_NOT(( has_xxx2< b6, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b6 > )); - MPL_ASSERT_NOT(( has_yyy1< b6, int > )); - MPL_ASSERT_NOT(( has_yyy2< b6, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b7 > )); - MPL_ASSERT_NOT(( has_xxx1< b7, int > )); - MPL_ASSERT_NOT(( has_xxx2< b7, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b7 > )); - MPL_ASSERT_NOT(( has_yyy1< b7, int > )); - MPL_ASSERT_NOT(( has_yyy2< b7, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); #endif // Same name, different args. - // Note: has_xxx0 is not test here because it's impossible to - // declare a template with no arguments (only no required - // arguments), so there is no zero argument substitute template - // to reject n-ary member templates. -#if (!BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303) \ - && !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308))) - MPL_ASSERT_NOT(( has_xxx1 )); - MPL_ASSERT_NOT(( has_xxx2 )); - MPL_ASSERT_NOT(( has_xxx2 )); -#endif - - // Different name, same args. - MPL_ASSERT_NOT(( has_xxx0 )); - MPL_ASSERT_NOT(( has_xxx1 )); - MPL_ASSERT_NOT(( has_xxx2 )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_yyy )); + MPL_ASSERT(( has_yyy )); // Different name, different args. - MPL_ASSERT_NOT(( has_xxx0 )); - MPL_ASSERT_NOT(( has_xxx1 )); - MPL_ASSERT_NOT(( has_xxx2 )); - MPL_ASSERT_NOT(( has_xxx2 )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_yyy )); + MPL_ASSERT_NOT(( has_yyy )); + MPL_ASSERT_NOT(( has_yyy )); + MPL_ASSERT_NOT(( has_yyy )); + MPL_ASSERT_NOT(( has_yyy )); MPL_ASSERT(( has_xxx )); MPL_ASSERT(( has_xxx )); @@ -254,14 +136,7 @@ MPL_TEST_CASE() MPL_ASSERT(( has_xxx )); MPL_ASSERT(( has_xxx )); -#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, >= 1500) - MPL_ASSERT(( has_xxx0 )); - MPL_ASSERT(( has_yyy0 )); -#endif - MPL_ASSERT(( has_xxx1 )); - MPL_ASSERT(( has_xxx2 )); - MPL_ASSERT(( has_yyy1 )); - MPL_ASSERT(( has_yyy2 )); + MPL_ASSERT(( has_xxx_template )); #if !defined(HAS_XXX_ASSERT) # define HAS_XXX_ASSERT(x) MPL_ASSERT(x) @@ -279,12 +154,5 @@ MPL_TEST_CASE() # define HAS_XXX_TEMPLATE_ASSERT(x) MPL_ASSERT(x) #endif -#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, >= 1500) - HAS_XXX_TEMPLATE_ASSERT(( has_xxx0 )); - HAS_XXX_TEMPLATE_ASSERT(( has_yyy0 )); -#endif - HAS_XXX_TEMPLATE_ASSERT(( has_xxx1 )); - HAS_XXX_TEMPLATE_ASSERT(( has_xxx2 )); - HAS_XXX_TEMPLATE_ASSERT(( has_yyy1 )); - HAS_XXX_TEMPLATE_ASSERT(( has_yyy2 )); + HAS_XXX_TEMPLATE_ASSERT(( has_xxx_template )); }