Ticket #861: has_xxx_template.2.patch

File has_xxx_template.2.patch, 43.7 KB (added by Steven Watanabe, 12 years ago)

Revised patch. I've checked that the docs build correctly, and run the tests with MSVC 10, as well.

  • boost/mpl/aux_/config/has_xxx.hpp

     
    2727        )
    2828
    2929#   define BOOST_MPL_CFG_NO_HAS_XXX
     30#   define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
    3031
    3132#endif
    3233
  • boost/mpl/has_xxx.hpp

     
    44
    55// Copyright Aleksey Gurtovoy 2002-2006
    66// Copyright David Abrahams 2002-2003
     7// Copyright Daniel Walker 2007
    78//
    89// Distributed under the Boost Software License, Version 1.0.
    910// (See accompanying file LICENSE_1_0.txt or copy at
     
    1819#include <boost/mpl/bool.hpp>
    1920#include <boost/mpl/aux_/type_wrapper.hpp>
    2021#include <boost/mpl/aux_/yes_no.hpp>
     22#include <boost/mpl/aux_/config/gcc.hpp>
    2123#include <boost/mpl/aux_/config/has_xxx.hpp>
    2224#include <boost/mpl/aux_/config/msvc_typename.hpp>
    2325#include <boost/mpl/aux_/config/msvc.hpp>
    2426#include <boost/mpl/aux_/config/static_constant.hpp>
    2527#include <boost/mpl/aux_/config/workaround.hpp>
    2628
     29#include <boost/preprocessor/array/elem.hpp>
    2730#include <boost/preprocessor/cat.hpp>
     31#include <boost/preprocessor/control/if.hpp>
     32#include <boost/preprocessor/repetition/enum_params.hpp>
     33#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
    2834
    2935#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) )
    3036# include <boost/type_traits/is_class.hpp>
     
    271277    BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \
    272278/**/
    273279
     280
     281#if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
     282
     283// Create boolean n-ary Metafunction to detect a nested template
     284// member with n template parameters. This implementation is based on
     285// a USENET newsgroup's posting by Aleksey Gurtovoy
     286// (comp.lang.c++.moderated, 2002-03-19), Rani Sharoni's USENET
     287// posting cited above, the non-template has_xxx implementations
     288// above, and discussion on the Boost mailing list.
     289
     290#   if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES)
     291#     if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
     292#       define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1
     293#     endif
     294#   endif
     295
     296#   if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION)
     297#     if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) \
     298          || BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303))
     299#       define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1
     300#     endif
     301#   endif
     302
     303#   if !defined(BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE)
     304#     if BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303)
     305#       define BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE 1
     306#     endif
     307#   endif
     308
     309#   if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE)
     310#     if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
     311#       define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1
     312#     endif
     313#   endif
     314
     315// NOTE: All internal implementation macros take a Boost.Preprocessor
     316// array argument called args which contains the arguments passed to
     317// HAS_XXX_TEMPLATE_NAMED_DEF and is of the following form.
     318//               ( 4, ( trait, name, n, default_ ) )
     319
     320#   define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
     321      BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \
     322    /**/
     323
     324#   define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \
     325      BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute) \
     326    /**/
     327
     328#   define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \
     329      BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _test) \
     330    /**/
     331
     332// Thanks to Guillaume Melquiond for pointing out the need for the
     333// "substitute" template as an argument to the overloaded test
     334// functions to get SFINAE to work for member templates with the
     335// correct name but incorrect arguments.
     336#   define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
     337      template< substitute_macro(args, V) > \
     338      struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) { \
     339      }; \
     340    /**/
     341
     342#   if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
     343#     define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
     344        template< typename V > \
     345        static boost::mpl::aux::no_tag \
     346        BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
     347      /**/
     348#   else
     349#     define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
     350        static boost::mpl::aux::no_tag \
     351        BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
     352      /**/
     353#   endif
     354
     355#   if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
     356#     define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
     357        template< typename V > \
     358        static boost::mpl::aux::yes_tag \
     359        BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
     360            boost::mpl::aux::type_wrapper< V > const volatile* \
     361          , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) < \
     362                member_macro(args, V, T) \
     363            >* = 0 \
     364        ); \
     365      /**/
     366#   else
     367#     define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
     368        template< typename V > \
     369        static boost::mpl::aux::yes_tag \
     370        BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
     371            V const volatile* \
     372          , member_macro(args, V, T)* = 0 \
     373        ); \
     374      /**/
     375#   endif
     376
     377#   if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
     378#     define BOOST_MPL_HAS_MEMBER_TEST(args) \
     379          sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \
     380              == sizeof(boost::mpl::aux::yes_tag) \
     381      /**/
     382#   else
     383#     if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
     384#       define BOOST_MPL_HAS_MEMBER_TEST(args) \
     385          sizeof( \
     386              BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
     387                  static_cast< boost::mpl::aux::type_wrapper< U >* >(0) \
     388              ) \
     389          ) == sizeof(boost::mpl::aux::yes_tag) \
     390        /**/
     391#     else
     392#       define BOOST_MPL_HAS_MEMBER_TEST(args) \
     393          sizeof( \
     394              BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
     395                  static_cast< U* >(0) \
     396              ) \
     397          ) == sizeof(boost::mpl::aux::yes_tag) \
     398        /**/
     399#     endif
     400#   endif
     401
     402#   define BOOST_MPL_HAS_MEMBER_INTROSPECT( \
     403               args, substitute_macro, member_macro \
     404           ) \
     405      template< typename U > \
     406      struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \
     407          BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
     408          BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
     409          BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
     410          BOOST_STATIC_CONSTANT( \
     411              bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \
     412          ); \
     413          typedef boost::mpl::bool_< value > type; \
     414      }; \
     415    /**/
     416
     417#   define BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
     418               args, introspect_macro, substitute_macro, member_macro \
     419           ) \
     420      template< \
     421          typename T \
     422          BOOST_PP_ENUM_TRAILING_PARAMS( \
     423              BOOST_PP_ARRAY_ELEM(2, args), typename T \
     424          )  \
     425        , typename fallback_ \
     426              = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \
     427      > \
     428      class BOOST_PP_ARRAY_ELEM(0, args) { \
     429          introspect_macro(args, substitute_macro, member_macro) \
     430      public: \
     431          static const bool value \
     432              = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \
     433          typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \
     434              T \
     435          >::type type; \
     436      }; \
     437    /**/
     438
     439// For example,
     440// BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE(
     441//     (4, (has_xxx, xxx, 2, false))
     442//   , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER
     443//   , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS
     444// )
     445// expands to something like the following...
     446//
     447// template<
     448//     typename T , typename T0 , typename T1
     449//   , typename fallback_ = boost::mpl::bool_< false >
     450// >
     451// class has_xxx {
     452//     template< typename U >
     453//     struct has_xxx_introspect {
     454//         template< template< typename V0 , typename V1 > class V >
     455//         struct has_xxx_substitute {
     456//         };
     457//
     458//         template< typename V >
     459//         static boost::mpl::aux::no_tag
     460//         has_xxx_test(...);
     461//
     462//         template< typename V >
     463//         static boost::mpl::aux::yes_tag
     464//         has_xxx_test(
     465//             boost::mpl::aux::type_wrapper< V > const volatile*
     466//           , has_xxx_substitute < V::template xxx >* = 0
     467//         );
     468//
     469//         static const bool value
     470//             = sizeof(has_xxx_test< U >(0))
     471//                   == sizeof(boost::mpl::aux::yes_tag);
     472//         typedef boost::mpl::bool_< value > type;
     473//     };
     474// public:
     475//     static const bool value = has_xxx_introspect< T >::value;
     476//     typedef typename has_xxx_introspect< T >::type type;
     477// };
     478#   define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
     479               args, substitute_macro, member_macro \
     480           ) \
     481      BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
     482          args \
     483        , BOOST_MPL_HAS_MEMBER_INTROSPECT \
     484        , substitute_macro \
     485        , member_macro \
     486      ) \
     487    /**/
     488
     489#   if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
     490
     491#     if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE)
     492#       if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
     493#         define BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1
     494#       endif
     495#     endif
     496
     497#     if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE
     498#       define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
     499                   args \
     500               ) \
     501          BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \
     502        /**/
     503#     else
     504#       define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
     505                   args \
     506               ) \
     507          BOOST_PP_CAT( \
     508              boost_mpl_has_xxx_ \
     509            , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \
     510          ) \
     511        /**/
     512#     endif
     513
     514#     define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \
     515                 args \
     516             ) \
     517        BOOST_PP_CAT( \
     518            BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
     519                args \
     520            ) \
     521          , _tag \
     522        ) \
     523      /**/
     524
     525#     define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
     526                 args, substitute_macro \
     527             ) \
     528        typedef void \
     529            BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \
     530        template< substitute_macro(args, U) > \
     531        struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
     532                args \
     533               ) { \
     534            typedef \
     535                BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
     536                type; \
     537        }; \
     538      /**/
     539
     540#     define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \
     541                 args, member_macro \
     542             ) \
     543        template< \
     544            typename U \
     545            BOOST_PP_ENUM_TRAILING_PARAMS( \
     546                BOOST_PP_ARRAY_ELEM(2, args), typename U \
     547            ) \
     548          , typename V \
     549                = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
     550        > \
     551        struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \
     552            BOOST_STATIC_CONSTANT(bool, value = false); \
     553            typedef boost::mpl::bool_< value > type; \
     554        }; \
     555      /**/
     556
     557#     define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \
     558                 args, member_macro \
     559             ) \
     560        template< \
     561            typename U \
     562            BOOST_PP_ENUM_TRAILING_PARAMS( \
     563                BOOST_PP_ARRAY_ELEM(2, args), typename U \
     564            ) \
     565        > \
     566        struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \
     567            U BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), U) \
     568          , typename \
     569                BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
     570                    args \
     571                )< \
     572                    member_macro(args, U, U) \
     573                >::type \
     574        > { \
     575            BOOST_STATIC_CONSTANT(bool, value = true); \
     576            typedef boost::mpl::bool_< value > type; \
     577        }; \
     578      /**/
     579
     580#     define BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \
     581                 args, substitute_macro, member_macro \
     582             ) \
     583        BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \
     584        BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \
     585        template< typename U > \
     586        struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
     587            : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \
     588                  U \
     589                  BOOST_PP_ENUM_TRAILING_PARAMS( \
     590                      BOOST_PP_ARRAY_ELEM(2, args) \
     591                    , T \
     592                  ) \
     593              > { \
     594        }; \
     595      /**/
     596
     597#     if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE
     598#       define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \
     599                   args, substitute_macro, member_macro \
     600               ) \
     601          BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
     602              args, substitute_macro \
     603          ) \
     604          BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \
     605              args, substitute_macro, member_macro \
     606          ) \
     607        /**/
     608#     else
     609#       define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \
     610                   args, substitute_macro, member_macro \
     611               ) \
     612          BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \
     613              args, substitute_macro, member_macro \
     614          ) \
     615        /**/
     616#     endif
     617
     618// For example,
     619// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE(
     620//     (4, (has_xxx, xxx, 2, false))
     621//   , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER
     622//   , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS
     623// )
     624// expands to something like the following...
     625//
     626// template<
     627//     typename T , typename T0 , typename T1
     628//   , typename fallback_ = boost::mpl::bool_< false >
     629// >
     630// class has_xxx {
     631//     typedef void has_xxx_substitute_tag;
     632//
     633//     template< template< typename U0 , typename U1 > class U >
     634//     struct has_xxx_substitute {
     635//         typedef has_xxx_substitute_tag type;
     636//     };
     637//
     638//     template<
     639//         typename U , typename U0 , typename U1
     640//       , typename V = has_xxx_substitute_tag
     641//     >
     642//     struct has_xxx_test {
     643//         static const bool value = false;
     644//         typedef boost::mpl::bool_< value > type;
     645//     };
     646//
     647//     template< typename U , typename U0 , typename U1 >
     648//     struct has_xxx_test<
     649//         U , U0 , U1
     650//       , typename has_xxx_substitute< U::template xxx >::type
     651//     > {
     652//         static const bool value = true;
     653//         typedef boost::mpl::bool_< value > type;
     654//     };
     655//
     656//     template< typename U >
     657//     struct has_xxx_introspect : has_xxx_test< U , T0 , T1 > {
     658//     };
     659// public:
     660//     static const bool value = has_xxx_introspect< T >::value;
     661//     typedef typename has_xxx_introspect< T >::type type;
     662// };
     663//
     664// Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is
     665// defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs
     666// to be expanded at namespace level before
     667// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used.
     668#     define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \
     669                 args, substitute_macro, member_macro \
     670             ) \
     671        BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
     672            args \
     673          , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \
     674          , substitute_macro \
     675          , member_macro \
     676        ) \
     677      /**/
     678
     679#   endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
     680
     681#   define BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER( \
     682               args, param \
     683           ) \
     684      typename \
     685    /**/
     686
     687#   if !BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE
     688#     define BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_SUBSTITUTE_PARAMETER( \
     689                 args, param \
     690             ) \
     691        template< \
     692            BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), typename param) \
     693        > \
     694        class param\
     695      /**/
     696
     697// See comment at BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS below.
     698#     define BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER(args, param) \
     699        BOOST_PP_IF( \
     700            BOOST_PP_ARRAY_ELEM(2, args) \
     701          , BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_SUBSTITUTE_PARAMETER \
     702          , BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER \
     703        ) ( args, param ) \
     704      /**/
     705#   else
     706#     define BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER(args, param) \
     707        BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER( \
     708            args, param \
     709        ) \
     710      /**/
     711#   endif
     712
     713#   define BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS( \
     714               args, class_type, param \
     715           ) \
     716      typename class_type::template BOOST_PP_ARRAY_ELEM(1, args)< \
     717          BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), param) \
     718      > \
     719    /**/
     720
     721#   if !BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE
     722#     define BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_ACCESS( \
     723               args, class_type, param \
     724             ) \
     725        class_type::template BOOST_PP_ARRAY_ELEM(1, args) \
     726      /**/
     727
     728// Note: to recognize templates with no required arguments use
     729// explicit access since a substitute template with no args cannot be
     730// declared.
     731#     define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS(args, class_type, param) \
     732        BOOST_PP_IF( \
     733            BOOST_PP_ARRAY_ELEM(2, args) \
     734          , BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_ACCESS \
     735          , BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS \
     736        ) ( args, class_type, param ) \
     737      /**/
     738#   else
     739#     define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS(args, class_type, param) \
     740        BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS( \
     741            args, class_type, param \
     742        ) \
     743      /**/
     744#   endif
     745
     746#   if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
     747// MSVC (7.1, 8.0) accepts the member template access syntax below
     748// regardless of the member template's arity. introspect will reject
     749// member templates with the wrong arity due to the substitute
     750// template. Note that using this syntax also enables MSVC
     751// template-based SFINAE to reject non-template members. This is
     752// important because explicitly passing the template args will match
     753// templates with the correct name and arguments but will cause ICE on
     754// non-template members. However, MSVC nullary template-based SFINAE
     755// (introspection for a member template with no required args) can not
     756// reject non-template members, but MSVC function-based SFINAE
     757// can. So, one of the two is chosen based on the number of required
     758// template parameters.
     759#     if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
     760#       define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC( \
     761                   args, class_type, param \
     762               ) \
     763          typename class_type::template BOOST_PP_ARRAY_ELEM(1, args)< > \
     764        /**/
     765#     else
     766#       define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC( \
     767                   args, class_type, param \
     768               ) \
     769          class_type::BOOST_PP_ARRAY_ELEM(1, agrs)< > \
     770        /**/
     771#     endif
     772
     773#     define BOOST_MPL_HAS_MEMBER_TEMPLATE_MSVC( \
     774                 args, substitute_macro, member_macro \
     775             ) \
     776        BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
     777            args, substitute_macro \
     778        ) \
     779        BOOST_PP_IF( \
     780            BOOST_PP_ARRAY_ELEM(2, args) \
     781          , BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE \
     782          , BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE \
     783        ) ( \
     784            args \
     785          , substitute_macro \
     786          , member_macro \
     787        ) \
     788      /**/
     789#   endif
     790
     791#   if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
     792#     define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \
     793        BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
     794            ( 4, ( trait, name, n, default_ ) ) \
     795          , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
     796          , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \
     797        ) \
     798      /**/
     799#   else
     800#     define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \
     801        BOOST_MPL_HAS_MEMBER_TEMPLATE_MSVC( \
     802            ( 4, ( trait, name, n, default_ ) ) \
     803          , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
     804          , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC \
     805        ) \
     806      /**/
     807#   endif
     808
     809#else // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
     810
     811// placeholder implementation
     812
     813#   define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \
     814      template< typename T \
     815                BOOST_PP_ENUM_TRAILING_PARAMS(n, typename U) \
     816              , typename fallback_ = boost::mpl::bool_< default_ > > \
     817      struct trait { \
     818          BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
     819          typedef fallback_ type; \
     820      }; \
     821    /**/
     822
     823#endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
     824
     825#   define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \
     826      BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \
     827          BOOST_PP_CAT(has_, name), name, n, false \
     828      ) \
     829    /**/
     830
    274831#endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED
  • libs/mpl/test/has_xxx.cpp

     
    11
    22// Copyright Aleksey Gurtovoy 2000-2004
     3// Copyright Daniel Walker 2007
    34//
    45// Distributed under the Boost Software License, Version 1.0.
    56// (See accompanying file LICENSE_1_0.txt or copy at
     
    1617#include <boost/mpl/aux_/test.hpp>
    1718
    1819BOOST_MPL_HAS_XXX_TRAIT_DEF(xxx)
     20BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx0, xxx, 0, false)
     21BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx1, xxx, 1, false)
     22BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx2, xxx, 2, false)
     23BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy0, 0)
     24BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy1, 1)
     25BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy2, 2)
    1926
    2027struct a1 {};
    2128struct a2 { void xxx(); };
     
    3138struct b6 { typedef void (*xxx)(); };
    3239struct b7 { typedef void (xxx)(); };
    3340
     41struct c0 { template< typename T0 = int > struct xxx {}; };
     42struct c1 { template< typename T1 > struct xxx {}; };
     43struct c2 { template< typename T1, typename T2 > struct xxx {}; };
     44struct c3 { template< typename T0 = int > struct yyy0 {}; };
     45struct c4 { template< typename T1 > struct yyy1 {}; };
     46struct c5 { template< typename T1, typename T2 > struct yyy2 {}; };
     47
    3448template< typename T > struct outer;
    3549template< typename T > struct inner { typedef typename T::type type; };
    3650
     
    4256MPL_TEST_CASE()
    4357{
    4458    MPL_ASSERT_NOT(( has_xxx<int> ));
     59    MPL_ASSERT_NOT(( has_xxx0< int > ));
     60    MPL_ASSERT_NOT(( has_xxx1< int, int > ));
     61    MPL_ASSERT_NOT(( has_xxx2< int, int, int > ));
     62    MPL_ASSERT_NOT(( has_yyy0< int > ));
     63    MPL_ASSERT_NOT(( has_yyy1< int, int > ));
     64    MPL_ASSERT_NOT(( has_yyy2< int, int, int > ));
     65
    4566#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    4667    MPL_ASSERT_NOT(( has_xxx<int&> ));
     68    MPL_ASSERT_NOT(( has_xxx0< int& > ));
     69    MPL_ASSERT_NOT(( has_xxx1< int&, int > ));
     70    MPL_ASSERT_NOT(( has_xxx2< int&, int, int > ));
     71    MPL_ASSERT_NOT(( has_yyy0< int& > ));
     72    MPL_ASSERT_NOT(( has_yyy1< int&, int > ));
     73    MPL_ASSERT_NOT(( has_yyy2< int&, int, int > ));
     74
    4775    MPL_ASSERT_NOT(( has_xxx<int*> ));
     76    MPL_ASSERT_NOT(( has_xxx0< int* > ));
     77    MPL_ASSERT_NOT(( has_xxx1< int*, int > ));
     78    MPL_ASSERT_NOT(( has_xxx2< int*, int, int > ));
     79    MPL_ASSERT_NOT(( has_yyy0< int* > ));
     80    MPL_ASSERT_NOT(( has_yyy1< int*, int > ));
     81    MPL_ASSERT_NOT(( has_yyy2< int*, int, int > ));
     82
    4883    MPL_ASSERT_NOT(( has_xxx<int[]> ));
     84    MPL_ASSERT_NOT(( has_xxx0< int[] > ));
     85    MPL_ASSERT_NOT(( has_xxx1< int[], int > ));
     86    MPL_ASSERT_NOT(( has_xxx2< int[], int, int > ));
     87    MPL_ASSERT_NOT(( has_yyy0< int[] > ));
     88    MPL_ASSERT_NOT(( has_yyy1< int[], int > ));
     89    MPL_ASSERT_NOT(( has_yyy2< int[], int, int > ));
     90
    4991    MPL_ASSERT_NOT(( has_xxx<int (*)()> ));
     92    MPL_ASSERT_NOT(( has_xxx0< int (*)() > ));
     93    MPL_ASSERT_NOT(( has_xxx1< int (*)(), int > ));
     94    MPL_ASSERT_NOT(( has_xxx2< int (*)(), int, int > ));
     95    MPL_ASSERT_NOT(( has_yyy0< int (*)() > ));
     96    MPL_ASSERT_NOT(( has_yyy1< int (*)(), int > ));
     97    MPL_ASSERT_NOT(( has_yyy2< int (*)(), int, int > ));
    5098
    5199    MPL_ASSERT_NOT(( has_xxx<a2> ));
     100    MPL_ASSERT_NOT(( has_xxx0< a2 > ));
     101    MPL_ASSERT_NOT(( has_xxx1< a2, int > ));
     102    MPL_ASSERT_NOT(( has_xxx2< a2, int, int > ));
     103    MPL_ASSERT_NOT(( has_yyy0< a2 > ));
     104    MPL_ASSERT_NOT(( has_yyy1< a2, int > ));
     105    MPL_ASSERT_NOT(( has_yyy2< a2, int, int > ));
     106
    52107    MPL_ASSERT_NOT(( has_xxx<a3> ));
     108    MPL_ASSERT_NOT(( has_xxx0< a3 > ));
     109    MPL_ASSERT_NOT(( has_xxx1< a3, int > ));
     110    MPL_ASSERT_NOT(( has_xxx2< a3, int, int > ));
     111    MPL_ASSERT_NOT(( has_yyy0< a3 > ));
     112    MPL_ASSERT_NOT(( has_yyy1< a3, int > ));
     113    MPL_ASSERT_NOT(( has_yyy2< a3, int, int > ));
     114
    53115    MPL_ASSERT_NOT(( has_xxx<a4> ));
     116    MPL_ASSERT_NOT(( has_xxx0< a4 > ));
     117    MPL_ASSERT_NOT(( has_xxx1< a4, int > ));
     118    MPL_ASSERT_NOT(( has_xxx2< a4, int, int > ));
     119    MPL_ASSERT_NOT(( has_yyy0< a4 > ));
     120    MPL_ASSERT_NOT(( has_yyy1< a4, int > ));
     121    MPL_ASSERT_NOT(( has_yyy2< a4, int, int > ));
     122
    54123#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202))
    55124    MPL_ASSERT_NOT(( has_xxx<a5> ));
    56125#endif
    57126    MPL_ASSERT_NOT(( has_xxx< enum_ > ));
     127    MPL_ASSERT_NOT(( has_xxx0< enum_ > ));
     128    MPL_ASSERT_NOT(( has_xxx1< enum_, int > ));
     129    MPL_ASSERT_NOT(( has_xxx2< enum_, int, int > ));
     130    MPL_ASSERT_NOT(( has_yyy0< enum_ > ));
     131    MPL_ASSERT_NOT(( has_yyy1< enum_, int > ));
     132    MPL_ASSERT_NOT(( has_yyy2< enum_, int, int > ));
    58133#endif
     134
    59135    MPL_ASSERT_NOT(( has_xxx<a1> ));
     136    MPL_ASSERT_NOT(( has_xxx0< a1 > ));
     137    MPL_ASSERT_NOT(( has_xxx1< a1, int > ));
     138    MPL_ASSERT_NOT(( has_xxx2< a1, int, int > ));
     139    MPL_ASSERT_NOT(( has_yyy0< a1 > ));
     140    MPL_ASSERT_NOT(( has_yyy1< a1, int > ));
     141    MPL_ASSERT_NOT(( has_yyy2< a1, int, int > ));
     142
    60143    MPL_ASSERT_NOT(( has_xxx< outer< inner<int> > > ));
     144    MPL_ASSERT_NOT(( has_xxx0< outer< inner<int> > > ));
     145    MPL_ASSERT_NOT(( has_xxx1< outer< inner<int> >, int > ));
     146    MPL_ASSERT_NOT(( has_xxx2< outer< inner<int> >, int, int > ));
     147    MPL_ASSERT_NOT(( has_yyy0< outer< inner<int> > > ));
     148    MPL_ASSERT_NOT(( has_yyy1< outer< inner<int> >, int > ));
     149    MPL_ASSERT_NOT(( has_yyy2< outer< inner<int> >, int, int > ));
     150
    61151    MPL_ASSERT_NOT(( has_xxx< incomplete > ));
     152    MPL_ASSERT_NOT(( has_xxx0< incomplete > ));
     153    MPL_ASSERT_NOT(( has_xxx1< incomplete, int > ));
     154    MPL_ASSERT_NOT(( has_xxx2< incomplete, int, int > ));
     155    MPL_ASSERT_NOT(( has_yyy0< incomplete > ));
     156    MPL_ASSERT_NOT(( has_yyy1< incomplete, int > ));
     157    MPL_ASSERT_NOT(( has_yyy2< incomplete, int, int > ));
     158
    62159    MPL_ASSERT_NOT(( has_xxx< abstract > ));
     160    MPL_ASSERT_NOT(( has_xxx0< abstract > ));
     161    MPL_ASSERT_NOT(( has_xxx1< abstract, int > ));
     162    MPL_ASSERT_NOT(( has_xxx2< abstract, int, int > ));
     163    MPL_ASSERT_NOT(( has_yyy0< abstract > ));
     164    MPL_ASSERT_NOT(( has_yyy1< abstract, int > ));
     165    MPL_ASSERT_NOT(( has_yyy2< abstract, int, int > ));
     166
    63167    MPL_ASSERT_NOT(( has_xxx< noncopyable > ));
     168    MPL_ASSERT_NOT(( has_xxx0< noncopyable > ));
     169    MPL_ASSERT_NOT(( has_xxx1< noncopyable, int > ));
     170    MPL_ASSERT_NOT(( has_xxx2< noncopyable, int, int > ));
     171    MPL_ASSERT_NOT(( has_yyy0< noncopyable > ));
     172    MPL_ASSERT_NOT(( has_yyy1< noncopyable, int > ));
     173    MPL_ASSERT_NOT(( has_yyy2< noncopyable, int, int > ));
    64174
     175#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308))
     176    MPL_ASSERT_NOT(( has_xxx0< b1 > ));
     177    MPL_ASSERT_NOT(( has_xxx1< b1, int > ));
     178    MPL_ASSERT_NOT(( has_xxx2< b1, int, int > ));
     179    MPL_ASSERT_NOT(( has_yyy0< b1 > ));
     180    MPL_ASSERT_NOT(( has_yyy1< b1, int > ));
     181    MPL_ASSERT_NOT(( has_yyy2< b1, int, int > ));
     182
     183    MPL_ASSERT_NOT(( has_xxx0< b2 > ));
     184    MPL_ASSERT_NOT(( has_xxx1< b2, int > ));
     185    MPL_ASSERT_NOT(( has_xxx2< b2, int, int > ));
     186    MPL_ASSERT_NOT(( has_yyy0< b2 > ));
     187    MPL_ASSERT_NOT(( has_yyy1< b2, int > ));
     188    MPL_ASSERT_NOT(( has_yyy2< b2, int, int > ));
     189
     190    MPL_ASSERT_NOT(( has_xxx0< b3 > ));
     191    MPL_ASSERT_NOT(( has_xxx1< b3, int > ));
     192    MPL_ASSERT_NOT(( has_xxx2< b3, int, int > ));
     193    MPL_ASSERT_NOT(( has_yyy0< b3 > ));
     194    MPL_ASSERT_NOT(( has_yyy1< b3, int > ));
     195    MPL_ASSERT_NOT(( has_yyy2< b3, int, int > ));
     196
     197    MPL_ASSERT_NOT(( has_xxx0< b4 > ));
     198    MPL_ASSERT_NOT(( has_xxx1< b4, int > ));
     199    MPL_ASSERT_NOT(( has_xxx2< b4, int, int > ));
     200    MPL_ASSERT_NOT(( has_yyy0< b4 > ));
     201    MPL_ASSERT_NOT(( has_yyy1< b4, int > ));
     202    MPL_ASSERT_NOT(( has_yyy2< b4, int, int > ));
     203
     204    MPL_ASSERT_NOT(( has_xxx0< b5 > ));
     205    MPL_ASSERT_NOT(( has_xxx1< b5, int > ));
     206    MPL_ASSERT_NOT(( has_xxx2< b5, int, int > ));
     207    MPL_ASSERT_NOT(( has_yyy0< b5 > ));
     208    MPL_ASSERT_NOT(( has_yyy1< b5, int > ));
     209    MPL_ASSERT_NOT(( has_yyy2< b5, int, int > ));
     210
     211    MPL_ASSERT_NOT(( has_xxx0< b6 > ));
     212    MPL_ASSERT_NOT(( has_xxx1< b6, int > ));
     213    MPL_ASSERT_NOT(( has_xxx2< b6, int, int > ));
     214    MPL_ASSERT_NOT(( has_yyy0< b6 > ));
     215    MPL_ASSERT_NOT(( has_yyy1< b6, int > ));
     216    MPL_ASSERT_NOT(( has_yyy2< b6, int, int > ));
     217
     218    MPL_ASSERT_NOT(( has_xxx0< b7 > ));
     219    MPL_ASSERT_NOT(( has_xxx1< b7, int > ));
     220    MPL_ASSERT_NOT(( has_xxx2< b7, int, int > ));
     221    MPL_ASSERT_NOT(( has_yyy0< b7 > ));
     222    MPL_ASSERT_NOT(( has_yyy1< b7, int > ));
     223    MPL_ASSERT_NOT(( has_yyy2< b7, int, int > ));
     224#endif
     225
     226    // Same name, different args.
     227    //   Note: has_xxx0 is not test here because it's impossible to
     228    //   declare a template with no arguments (only no required
     229    //   arguments), so there is no zero argument substitute template
     230    //   to reject n-ary member templates.
     231#if (!BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303) \
     232     && !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)))
     233    MPL_ASSERT_NOT(( has_xxx1<c2, int> ));
     234    MPL_ASSERT_NOT(( has_xxx2<c0, int, int> ));
     235    MPL_ASSERT_NOT(( has_xxx2<c1, int, int> ));
     236#endif
     237
     238    // Different name, same args.
     239    MPL_ASSERT_NOT(( has_xxx0<c3> ));
     240    MPL_ASSERT_NOT(( has_xxx1<c4, int> ));
     241    MPL_ASSERT_NOT(( has_xxx2<c5, int, int> ));
     242
     243    // Different name, different args.
     244    MPL_ASSERT_NOT(( has_xxx0<c4> ));
     245    MPL_ASSERT_NOT(( has_xxx1<c5, int> ));
     246    MPL_ASSERT_NOT(( has_xxx2<c3, int, int> ));
     247    MPL_ASSERT_NOT(( has_xxx2<c4, int, int> ));
     248
    65249    MPL_ASSERT(( has_xxx<b1,true_> ));
    66250    MPL_ASSERT(( has_xxx<b2,true_> ));
    67251    MPL_ASSERT(( has_xxx<b3,true_> ));
     
    70254    MPL_ASSERT(( has_xxx<b6,true_> ));
    71255    MPL_ASSERT(( has_xxx<b7,true_> ));
    72256
     257#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, >= 1500)
     258    MPL_ASSERT(( has_xxx0<c0, true_> ));
     259    MPL_ASSERT(( has_yyy0<c3, true_> ));
     260#endif
     261    MPL_ASSERT(( has_xxx1<c1, int, true_> ));
     262    MPL_ASSERT(( has_xxx2<c2, int, int, true_> ));
     263    MPL_ASSERT(( has_yyy1<c4, int, true_> ));
     264    MPL_ASSERT(( has_yyy2<c5, int, int, true_> ));
     265
    73266#if !defined(HAS_XXX_ASSERT)
    74267#   define HAS_XXX_ASSERT(x) MPL_ASSERT(x)
    75268#endif
     
    81274    HAS_XXX_ASSERT(( has_xxx<b5> ));
    82275    HAS_XXX_ASSERT(( has_xxx<b6> ));
    83276    HAS_XXX_ASSERT(( has_xxx<b7> ));
     277
     278#if !defined(HAS_XXX_TEMPLATE_ASSERT)
     279#   define HAS_XXX_TEMPLATE_ASSERT(x) MPL_ASSERT(x)
     280#endif
     281
     282#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, >= 1500)
     283    HAS_XXX_TEMPLATE_ASSERT(( has_xxx0<c0> ));
     284    HAS_XXX_TEMPLATE_ASSERT(( has_yyy0<c3> ));
     285#endif
     286    HAS_XXX_TEMPLATE_ASSERT(( has_xxx1<c1, int> ));
     287    HAS_XXX_TEMPLATE_ASSERT(( has_xxx2<c2, int, int> ));
     288    HAS_XXX_TEMPLATE_ASSERT(( has_yyy1<c4, int> ));
     289    HAS_XXX_TEMPLATE_ASSERT(( has_yyy2<c5, int, int> ));
    84290}
  • libs/mpl/test/no_has_xxx.cpp

     
    2323#   define HAS_XXX_ASSERT(x) MPL_ASSERT_NOT(x)
    2424#endif
    2525
     26#if defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
     27#   define HAS_XXX_TEMPLATE_ASSERT(x) MPL_ASSERT_NOT(x)
     28#endif
     29
    2630#include "has_xxx.cpp"
  • libs/mpl/doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst

     
     1.. Macros/Configuration//BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE |20
     2
     3.. Copyright Daniel Walker 2007.
     4.. Distributed under the Boost
     5.. Software License, Version 1.0. (See accompanying
     6.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     7
     8BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
     9=================================
     10
     11Synopsis
     12--------
     13
     14.. parsed-literal::
     15
     16    // #define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
     17
     18
     19Description
     20-----------
     21
     22``BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE`` is a boolean configuration
     23macro signaling availability of the |BOOST_MPL_HAS_XXX_TEMPLATE_DEF| /
     24|BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| introspection macros'
     25functionality on a particular compiler.
     26
     27
     28See also
     29--------
     30
     31|Macros|, |Configuration|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF|
     32
  • libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst

    Property changes on: libs\mpl\doc\src\refmanual\CFG_NO_HAS_XXX_TEMPLATE.rst
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    Added: svn:keywords
       + Id
    Added: svn:eol-style
       + native
    
     
     1.. Macros/Introspection//BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF
     2
     3.. Copyright Daniel Walker 2007.
     4.. Distributed under the Boost
     5.. Software License, Version 1.0. (See accompanying
     6.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     7
     8BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF
     9====================================
     10
     11Synopsis
     12--------
     13
     14.. parsed-literal::
     15
     16    #define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default\_) \\
     17        |unspecified-token-seq| \\
     18    /\*\*/
     19
     20
     21Description
     22-----------
     23
     24Expands into the definition of a boolean n-ary |Metafunction| ``trait``
     25such that for any types ``x, a1, a2, ..., an`` ``trait<x, a1, ...,
     26an>::value == true`` if and only if ``x`` is a class type and has a
     27nested template member ``x::template name<a1, ..., an>``.
     28
     29On deficient compilers not capable of performing the detection,
     30``trait<x, a1, ..., an>::value`` always returns a fallback value
     31``default_``.  A boolean configuration macro,
     32|BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is provided to signal or override
     33the "deficient" status of a particular compiler.  |Note:| The fallback
     34value can also be provided at the point of the metafunction
     35invocation; see the `Expression semantics` section for details |-- end
     36note|
     37
     38
     39Header
     40------
     41
     42.. parsed-literal::
     43   
     44    #include <boost/mpl/has_xxx.hpp>
     45
     46
     47Parameters
     48----------
     49
     50+---------------+-------------------------------+---------------------------------------------------+
     51| Parameter     | Requirement                   | Description                                       |
     52+===============+===============================+===================================================+
     53| ``trait``     | A legal identifier token      | A name of the metafunction to be generated.       |
     54+---------------+-------------------------------+---------------------------------------------------+
     55| ``name``      | A legal identifier token      | A name of the member being detected.              |
     56+---------------+-------------------------------+---------------------------------------------------+
     57| ``n``         | An integral constant >= 0     | The arity of the template member being detected.  |
     58+---------------+-------------------------------+---------------------------------------------------+
     59| ``default_``  | An boolean constant           | A fallback value for the deficient compilers.     |
     60+---------------+-------------------------------+---------------------------------------------------+
     61
     62
     63Expression semantics
     64--------------------
     65
     66For any legal C++ identifiers ``trait`` and ``name``, integral
     67constant expression ``n`` greater than or equal to 0, boolean constant
     68expression ``c1``, boolean |Integral Constant| ``c2``, and arbitrary
     69type ``x``:
     70
     71.. parsed-literal::
     72
     73    BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, c1)
     74
     75:Precondition:
     76    Appears at namespace scope.
     77
     78:Return type:
     79    None.
     80
     81:Semantics:
     82    Expands into an equivalent of the following class template
     83    definition
     84
     85    .. parsed-literal::
     86
     87        template<
     88            typename X
     89          , typename A1, ..., typename An
     90          , typename fallback = boost::mpl::bool\_<c1>
     91        >
     92        struct trait
     93        {
     94            // |unspecified|
     95            // ...
     96        };
     97   
     98    where ``trait`` is a boolean |Metafunction| with the following
     99    semantics:
     100   
     101    .. parsed-literal::
     102
     103        typedef trait<x, a1, ..., an>::type r;
     104
     105    :Return type:
     106        |Integral Constant|.
     107
     108    :Semantics:
     109        If |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| is defined, ``r::value
     110        == c1``; otherwise, ``r::value == true`` if and only if ``x``
     111        is a class type that has a nested type member ``x::template
     112        name<a1, ..., an>``.
     113   
     114   
     115    .. parsed-literal::
     116
     117        typedef trait< x, a1, ..., an, c2 >::type r;
     118
     119    :Return type:
     120        |Integral Constant|.
     121
     122    :Semantics:
     123        If |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| is defined, ``r::value
     124        == c2::value``; otherwise, equivalent to
     125
     126        .. parsed-literal::
     127
     128            typedef trait<x, a1, ..., an>::type r;
     129
     130
     131Example
     132-------
     133
     134.. parsed-literal::
     135   
     136    BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(
     137        has_xxx, xxx, 1, false
     138    )
     139
     140    struct test1  {};
     141    struct test2  { void xxx(); };
     142    struct test3  { int xxx; };
     143    struct test4  { static int xxx(); };
     144    struct test5  { typedef int xxx; };
     145    struct test6  { struct xxx; };
     146    struct test7  { typedef void (\*xxx)(); };
     147    struct test8  { typedef void (xxx)(); };
     148    struct test9  { template< class T > struct xxx {}; };
     149
     150    BOOST_MPL_ASSERT_NOT(( has_xxx<test1, int> ));
     151    BOOST_MPL_ASSERT_NOT(( has_xxx<test2, int> ));
     152    BOOST_MPL_ASSERT_NOT(( has_xxx<test3, int> ));
     153    BOOST_MPL_ASSERT_NOT(( has_xxx<test4, int> ));
     154    BOOST_MPL_ASSERT_NOT(( has_xxx<test5, int> ));
     155    BOOST_MPL_ASSERT_NOT(( has_xxx<test6, int> ));
     156    BOOST_MPL_ASSERT_NOT(( has_xxx<test7, int> ));
     157    BOOST_MPL_ASSERT_NOT(( has_xxx<test8, int> ));
     158
     159    #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
     160    BOOST_MPL_ASSERT(( has_xxx<test9, int> ));
     161    #endif
     162
     163    BOOST_MPL_ASSERT(( has_xxx<test9, int, true\_> ));
     164
     165
     166See also
     167--------
     168
     169|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|
     170
  • libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst

    Property changes on: libs\mpl\doc\src\refmanual\HAS_XXX_TEMPLATE_NAMED_DEF.rst
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    Added: svn:keywords
       + Id
    Added: svn:eol-style
       + native
    
     
     1.. Macros/Introspection//BOOST_MPL_HAS_XXX_TEMPLATE_DEF
     2
     3.. Copyright Daniel Walker 2007.
     4.. Distributed under the Boost
     5.. Software License, Version 1.0. (See accompanying
     6.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     7
     8BOOST_MPL_HAS_XXX_TEMPLATE_DEF
     9==============================
     10
     11Synopsis
     12--------
     13
     14.. parsed-literal::
     15
     16    #define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \\
     17        |unspecified-token-seq| \\
     18    /\*\*/
     19
     20
     21Description
     22-----------
     23
     24Expands into the definition of a boolean n-ary |Metafunction|
     25``has_name`` such that for any types ``x, a1, a2, ..., an``
     26``has_name<x, a1, ..., an>::value == true`` if and only if ``x`` is a
     27class type and has a nested template member ``x::template name<a1,
     28..., an>``.
     29
     30On deficient compilers not capable of performing the detection,
     31``has_name<x, a1, ..., an>::value`` always returns ``false``. A
     32boolean configuration macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is
     33provided to signal or override the "deficient" status of a particular
     34compiler.
     35
     36|Note:| |BOOST_MPL_HAS_XXX_TEMPLATE_DEF| is a simplified front end to
     37the |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| introspection macro |-- end
     38note|
     39
     40
     41Header
     42------
     43
     44.. parsed-literal::
     45   
     46    #include <boost/mpl/has_xxx.hpp>
     47
     48
     49Parameters
     50----------
     51
     52
     53+---------------+-------------------------------+---------------------------------------------------+
     54| Parameter     | Requirement                   | Description                                       |
     55+===============+===============================+===================================================+
     56| ``name``      | A legal identifier token      | A name of the template member being detected.     |
     57+---------------+-------------------------------+---------------------------------------------------+
     58| ``n``         | An integral constant >= 0     | The arity of the template member being detected.  |
     59+---------------+-------------------------------+---------------------------------------------------+
     60
     61
     62Expression semantics
     63--------------------
     64
     65For any legal C++ identifier ``name`` and integral constant expression
     66``n`` greater than or equal to 0:
     67
     68.. parsed-literal::
     69
     70    BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n)
     71
     72:Precondition:
     73    Appears at namespace scope.
     74
     75:Return type:
     76    None.
     77
     78:Semantics:
     79    Equivalent to
     80
     81    .. parsed-literal::
     82
     83        BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(
     84              BOOST_PP_CAT(has\_,name), name, n, false
     85            )
     86
     87
     88Example
     89-------
     90
     91.. parsed-literal::
     92   
     93    BOOST_MPL_HAS_XXX_TEMPLATE_DEF(xxx, 1)
     94   
     95    struct test1  {};
     96    struct test2  { void xxx(); };
     97    struct test3  { int xxx; };
     98    struct test4  { static int xxx(); };
     99    struct test5  { typedef int xxx; };
     100    struct test6  { struct xxx; };
     101    struct test7  { typedef void (\*xxx)(); };
     102    struct test8  { typedef void (xxx)(); };
     103    struct test9  { template< class T > struct xxx {}; };
     104   
     105    BOOST_MPL_ASSERT_NOT(( has_xxx<test1, int> ));
     106    BOOST_MPL_ASSERT_NOT(( has_xxx<test2, int> ));
     107    BOOST_MPL_ASSERT_NOT(( has_xxx<test3, int> ));
     108    BOOST_MPL_ASSERT_NOT(( has_xxx<test4, int> ));
     109    BOOST_MPL_ASSERT_NOT(( has_xxx<test5, int> ));
     110    BOOST_MPL_ASSERT_NOT(( has_xxx<test6, int> ));
     111    BOOST_MPL_ASSERT_NOT(( has_xxx<test7, int> ));
     112    BOOST_MPL_ASSERT_NOT(( has_xxx<test8, int> ));
     113   
     114    #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
     115    BOOST_MPL_ASSERT(( has_xxx<test9, int> ));
     116    #endif
     117   
     118    BOOST_MPL_ASSERT(( has_xxx<test9, int, true\_> ));
     119
     120
     121See also
     122--------
     123
     124|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|
     125