Merged revisions 62579 via svnmerge from
https://svn.boost.org/svn/boost/trunk ........ r62579 | steven_watanabe | 2010-06-08 09:24:55 -0500 (Tue, 08 Jun 2010) | 1 line Add BOOST_MPL_HAS_XXX_TEMPLATE_DEF. Fixes #861 ........ [SVN r63518]
This commit is contained in:
1 parent
e66d77051e
commit
ea638a4478
7 files changed
+1095
No files matched your search
@@ -27,6 +27,7 @@
|
||||
)
|
||||
|
||||
# define BOOST_MPL_CFG_NO_HAS_XXX
|
||||
# define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2002-2006
|
||||
// Copyright David Abrahams 2002-2003
|
||||
// Copyright Daniel Walker 2007
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -18,13 +19,18 @@
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/aux_/type_wrapper.hpp>
|
||||
#include <boost/mpl/aux_/yes_no.hpp>
|
||||
#include <boost/mpl/aux_/config/gcc.hpp>
|
||||
#include <boost/mpl/aux_/config/has_xxx.hpp>
|
||||
#include <boost/mpl/aux_/config/msvc_typename.hpp>
|
||||
#include <boost/mpl/aux_/config/msvc.hpp>
|
||||
#include <boost/mpl/aux_/config/static_constant.hpp>
|
||||
#include <boost/mpl/aux_/config/workaround.hpp>
|
||||
|
||||
#include <boost/preprocessor/array/elem.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) )
|
||||
# include <boost/type_traits/is_class.hpp>
|
||||
@@ -271,4 +277,555 @@ struct trait \
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \
|
||||
/**/
|
||||
|
||||
|
||||
#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.
|
||||
|
||||
# if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES)
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
|
||||
# define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1
|
||||
# endif
|
||||
# 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))
|
||||
# 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_ ) )
|
||||
|
||||
# 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_TEST_NAME(args) \
|
||||
BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _test) \
|
||||
/**/
|
||||
|
||||
// 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) { \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
# if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
|
||||
# define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
|
||||
template< typename V > \
|
||||
static boost::mpl::aux::no_tag \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
|
||||
/**/
|
||||
# else
|
||||
# define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
|
||||
static boost::mpl::aux::no_tag \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
|
||||
/**/
|
||||
# endif
|
||||
|
||||
# if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
|
||||
# define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
|
||||
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) \
|
||||
>* = 0 \
|
||||
); \
|
||||
/**/
|
||||
# else
|
||||
# define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
|
||||
template< typename V > \
|
||||
static boost::mpl::aux::yes_tag \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
|
||||
V const volatile* \
|
||||
, member_macro(args, V, T)* = 0 \
|
||||
); \
|
||||
/**/
|
||||
# endif
|
||||
|
||||
# if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
|
||||
# define BOOST_MPL_HAS_MEMBER_TEST(args) \
|
||||
sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \
|
||||
== sizeof(boost::mpl::aux::yes_tag) \
|
||||
/**/
|
||||
# else
|
||||
# if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
|
||||
# define BOOST_MPL_HAS_MEMBER_TEST(args) \
|
||||
sizeof( \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
|
||||
static_cast< boost::mpl::aux::type_wrapper< U >* >(0) \
|
||||
) \
|
||||
) == sizeof(boost::mpl::aux::yes_tag) \
|
||||
/**/
|
||||
# else
|
||||
# define BOOST_MPL_HAS_MEMBER_TEST(args) \
|
||||
sizeof( \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
|
||||
static_cast< U* >(0) \
|
||||
) \
|
||||
) == sizeof(boost::mpl::aux::yes_tag) \
|
||||
/**/
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# define BOOST_MPL_HAS_MEMBER_INTROSPECT( \
|
||||
args, substitute_macro, member_macro \
|
||||
) \
|
||||
template< typename U > \
|
||||
struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \
|
||||
BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
|
||||
BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
|
||||
BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
|
||||
BOOST_STATIC_CONSTANT( \
|
||||
bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \
|
||||
); \
|
||||
typedef boost::mpl::bool_< value > type; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
# define BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
|
||||
args, introspect_macro, substitute_macro, member_macro \
|
||||
) \
|
||||
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) > \
|
||||
> \
|
||||
class BOOST_PP_ARRAY_ELEM(0, args) { \
|
||||
introspect_macro(args, substitute_macro, member_macro) \
|
||||
public: \
|
||||
static const bool value \
|
||||
= BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \
|
||||
typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \
|
||||
T \
|
||||
>::type type; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
// 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;
|
||||
// };
|
||||
# define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
|
||||
args, substitute_macro, member_macro \
|
||||
) \
|
||||
BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
|
||||
args \
|
||||
, BOOST_MPL_HAS_MEMBER_INTROSPECT \
|
||||
, substitute_macro \
|
||||
, member_macro \
|
||||
) \
|
||||
/**/
|
||||
|
||||
# if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
|
||||
|
||||
# if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE)
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
|
||||
# define BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE
|
||||
# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
|
||||
args \
|
||||
) \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \
|
||||
/**/
|
||||
# else
|
||||
# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
|
||||
args \
|
||||
) \
|
||||
BOOST_PP_CAT( \
|
||||
boost_mpl_has_xxx_ \
|
||||
, BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \
|
||||
) \
|
||||
/**/
|
||||
# endif
|
||||
|
||||
# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \
|
||||
args \
|
||||
) \
|
||||
BOOST_PP_CAT( \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
|
||||
args \
|
||||
) \
|
||||
, _tag \
|
||||
) \
|
||||
/**/
|
||||
|
||||
# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
|
||||
args, substitute_macro \
|
||||
) \
|
||||
typedef void \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \
|
||||
template< substitute_macro(args, U) > \
|
||||
struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
|
||||
args \
|
||||
) { \
|
||||
typedef \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
|
||||
type; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
# 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) \
|
||||
> \
|
||||
struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \
|
||||
BOOST_STATIC_CONSTANT(bool, value = false); \
|
||||
typedef boost::mpl::bool_< value > type; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
# define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \
|
||||
args, member_macro \
|
||||
) \
|
||||
template< \
|
||||
typename U \
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS( \
|
||||
BOOST_PP_ARRAY_ELEM(2, args), typename U \
|
||||
) \
|
||||
> \
|
||||
struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \
|
||||
U BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), U) \
|
||||
, typename \
|
||||
BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
|
||||
args \
|
||||
)< \
|
||||
member_macro(args, U, U) \
|
||||
>::type \
|
||||
> { \
|
||||
BOOST_STATIC_CONSTANT(bool, value = true); \
|
||||
typedef boost::mpl::bool_< value > type; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
# define BOOST_MPL_HAS_MEMBER_BASIC_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 \
|
||||
) \
|
||||
> { \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
# 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;
|
||||
// };
|
||||
//
|
||||
// Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is
|
||||
// defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs
|
||||
// to be expanded at namespace level before
|
||||
// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used.
|
||||
# define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \
|
||||
args, substitute_macro, member_macro \
|
||||
) \
|
||||
BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
|
||||
args \
|
||||
, BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \
|
||||
, substitute_macro \
|
||||
, member_macro \
|
||||
) \
|
||||
/**/
|
||||
|
||||
# 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
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
|
||||
# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \
|
||||
BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
|
||||
( 4, ( trait, name, n, 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_ ) ) \
|
||||
, BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
|
||||
, BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC \
|
||||
) \
|
||||
/**/
|
||||
# endif
|
||||
|
||||
#else // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
|
||||
|
||||
// placeholder implementation
|
||||
|
||||
# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, 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); \
|
||||
typedef fallback_ type; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
|
||||
|
||||
# define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \
|
||||
BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \
|
||||
BOOST_PP_CAT(has_, name), name, n, false \
|
||||
) \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED
|
||||
Reference in new issue
Block a user