Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r63518 - in branches/release: . boost boost/algorithm/string boost/archive boost/bimap boost/config boost/detail boost/filesystem boost/functional/hash boost/fusion boost/gil boost/graph boost/integer boost/interprocess boost/intrusive boost/iostreams boost/mpl boost/mpl/aux_/config boost/msm boost/numeric/ublas boost/program_options boost/property_tree boost/python boost/range boost/serialization boost/signals boost/signals2 boost/spirit boost/spirit/home boost/spirit/home/karma boost/spirit/home/support boost/statechart boost/system boost/thread boost/utility boost/uuid boost/variant boost/wave libs libs/array/test libs/bimap libs/filesystem libs/functional/hash libs/fusion libs/graph_parallel libs/integer libs/interprocess libs/intrusive libs/mpl/doc/refmanual libs/mpl/doc/src/refmanual libs/mpl/test libs/msm libs/numeric/ublas libs/numeric/ublas/doc libs/program_options libs/property_tree libs/python libs/range libs/range/doc libs/serialization libs/signals libs/signals2 libs/spirit libs/spirit/classic/example libs/spirit/doc libs/spirit/example libs/spirit/phoenix libs/spirit/test libs/spirit/test/qi libs/statechart libs/static_assert libs/system libs/thread libs/timer libs/utility libs/utility/swap/test libs/uuid libs/wave more tools tools/bcp tools/build/v2 tools/build/v2/tools tools/jam tools/regression tools/release tools/wave
From: agurtovoy_at_[hidden]
Date: 2010-07-02 14:57:06


Author: agurtovoy
Date: 2010-07-02 04:32:03 EDT (Fri, 02 Jul 2010)
New Revision: 63518
URL: http://svn.boost.org/trac/boost/changeset/63518

Log:
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
........

Added:
   branches/release/libs/mpl/doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst
      - copied unchanged from r62579, /trunk/libs/mpl/doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst
   branches/release/libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst
      - copied unchanged from r62579, /trunk/libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst
   branches/release/libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst
      - copied unchanged from r62579, /trunk/libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst
Properties modified:
   branches/release/ (props changed)
   branches/release/INSTALL (props changed)
   branches/release/Jamroot (props changed)
   branches/release/LICENSE_1_0.txt (props changed)
   branches/release/boost/ (props changed)
   branches/release/boost-build.jam (props changed)
   branches/release/boost.css (props changed)
   branches/release/boost.png (props changed)
   branches/release/boost/algorithm/string/ (props changed)
   branches/release/boost/archive/ (props changed)
   branches/release/boost/bimap/ (props changed)
   branches/release/boost/config/ (props changed)
   branches/release/boost/config.hpp (props changed)
   branches/release/boost/detail/ (props changed)
   branches/release/boost/detail/endian.hpp (props changed)
   branches/release/boost/filesystem/ (props changed)
   branches/release/boost/functional/hash/ (props changed)
   branches/release/boost/fusion/ (props changed)
   branches/release/boost/gil/ (props changed)
   branches/release/boost/graph/ (props changed)
   branches/release/boost/integer/ (props changed)
   branches/release/boost/interprocess/ (props changed)
   branches/release/boost/intrusive/ (props changed)
   branches/release/boost/iostreams/ (props changed)
   branches/release/boost/msm/ (props changed)
   branches/release/boost/numeric/ublas/ (props changed)
   branches/release/boost/program_options/ (props changed)
   branches/release/boost/property_tree/ (props changed)
   branches/release/boost/python/ (props changed)
   branches/release/boost/range/ (props changed)
   branches/release/boost/serialization/ (props changed)
   branches/release/boost/serialization/factory.hpp (props changed)
   branches/release/boost/signals/ (props changed)
   branches/release/boost/signals2/ (props changed)
   branches/release/boost/spirit/ (props changed)
   branches/release/boost/spirit/home/ (props changed)
   branches/release/boost/spirit/home/karma/ (props changed)
   branches/release/boost/spirit/home/support/attributes.hpp (props changed)
   branches/release/boost/statechart/ (props changed)
   branches/release/boost/system/ (props changed)
   branches/release/boost/thread/ (props changed)
   branches/release/boost/thread.hpp (props changed)
   branches/release/boost/utility/ (props changed)
   branches/release/boost/utility/value_init.hpp (props changed)
   branches/release/boost/uuid/ (props changed)
   branches/release/boost/variant/ (props changed)
   branches/release/boost/version.hpp (props changed)
   branches/release/boost/wave/ (props changed)
   branches/release/bootstrap.bat (props changed)
   branches/release/bootstrap.sh (props changed)
   branches/release/index.htm (props changed)
   branches/release/libs/ (props changed)
   branches/release/libs/array/test/array0.cpp (props changed)
   branches/release/libs/bimap/ (props changed)
   branches/release/libs/filesystem/ (props changed)
   branches/release/libs/functional/hash/ (props changed)
   branches/release/libs/fusion/ (props changed)
   branches/release/libs/graph_parallel/ (props changed)
   branches/release/libs/integer/ (props changed)
   branches/release/libs/interprocess/ (props changed)
   branches/release/libs/intrusive/ (props changed)
   branches/release/libs/mpl/doc/refmanual/broken-compiler-workarounds.html (props changed)
   branches/release/libs/mpl/doc/refmanual/categorized-index-concepts.html (props changed)
   branches/release/libs/mpl/doc/refmanual/cfg-no-preprocessed-headers.html (props changed)
   branches/release/libs/mpl/doc/refmanual/composition-and-argument-binding.html (props changed)
   branches/release/libs/mpl/doc/refmanual/data-types-concepts.html (props changed)
   branches/release/libs/mpl/doc/refmanual/data-types-miscellaneous.html (props changed)
   branches/release/libs/mpl/doc/refmanual/extensible-associative-sequence.html (props changed)
   branches/release/libs/mpl/doc/refmanual/inserter-class.html (props changed)
   branches/release/libs/mpl/doc/refmanual/tag-dispatched-metafunction.html (props changed)
   branches/release/libs/mpl/doc/refmanual/trivial-metafunctions-summary.html (props changed)
   branches/release/libs/mpl/doc/src/refmanual/Iterators-Iterator.rst (props changed)
   branches/release/libs/msm/ (props changed)
   branches/release/libs/numeric/ublas/ (props changed)
   branches/release/libs/numeric/ublas/doc/ (props changed)
   branches/release/libs/program_options/ (props changed)
   branches/release/libs/property_tree/ (props changed)
   branches/release/libs/python/ (props changed)
   branches/release/libs/range/ (props changed)
   branches/release/libs/range/doc/ (props changed)
   branches/release/libs/serialization/ (props changed)
   branches/release/libs/signals/ (props changed)
   branches/release/libs/signals2/ (props changed)
   branches/release/libs/spirit/ (props changed)
   branches/release/libs/spirit/classic/example/ (props changed)
   branches/release/libs/spirit/doc/ (props changed)
   branches/release/libs/spirit/example/ (props changed)
   branches/release/libs/spirit/phoenix/ (props changed)
   branches/release/libs/spirit/test/ (props changed)
   branches/release/libs/spirit/test/qi/optional.cpp (props changed)
   branches/release/libs/statechart/ (props changed)
   branches/release/libs/static_assert/ (props changed)
   branches/release/libs/system/ (props changed)
   branches/release/libs/thread/ (props changed)
   branches/release/libs/timer/ (props changed)
   branches/release/libs/utility/ (props changed)
   branches/release/libs/utility/swap.html (props changed)
   branches/release/libs/utility/swap/test/std_bitset.cpp (props changed)
   branches/release/libs/utility/value_init.htm (props changed)
   branches/release/libs/utility/value_init_test.cpp (props changed)
   branches/release/libs/uuid/ (props changed)
   branches/release/libs/wave/ (props changed)
   branches/release/more/ (props changed)
   branches/release/rst.css (props changed)
   branches/release/tools/ (props changed)
   branches/release/tools/bcp/ (props changed)
   branches/release/tools/build/v2/ (props changed)
   branches/release/tools/build/v2/tools/ (props changed)
   branches/release/tools/jam/ (props changed)
   branches/release/tools/regression/ (props changed)
   branches/release/tools/release/ (props changed)
   branches/release/tools/wave/ (props changed)
Text files modified:
   branches/release/boost/mpl/aux_/config/has_xxx.hpp | 1
   branches/release/boost/mpl/has_xxx.hpp | 557 ++++++++++++++++++++++++++++++++++++++++
   branches/release/libs/mpl/test/has_xxx.cpp | 206 ++++++++++++++
   branches/release/libs/mpl/test/no_has_xxx.cpp | 4
   4 files changed, 768 insertions(+), 0 deletions(-)

Modified: branches/release/boost/mpl/aux_/config/has_xxx.hpp
==============================================================================
--- branches/release/boost/mpl/aux_/config/has_xxx.hpp (original)
+++ branches/release/boost/mpl/aux_/config/has_xxx.hpp 2010-07-02 04:32:03 EDT (Fri, 02 Jul 2010)
@@ -27,6 +27,7 @@
         )
 
 # define BOOST_MPL_CFG_NO_HAS_XXX
+# define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
 
 #endif
 

Modified: branches/release/boost/mpl/has_xxx.hpp
==============================================================================
--- branches/release/boost/mpl/has_xxx.hpp (original)
+++ branches/release/boost/mpl/has_xxx.hpp 2010-07-02 04:32:03 EDT (Fri, 02 Jul 2010)
@@ -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 @@
     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

Modified: branches/release/libs/mpl/test/has_xxx.cpp
==============================================================================
--- branches/release/libs/mpl/test/has_xxx.cpp (original)
+++ branches/release/libs/mpl/test/has_xxx.cpp 2010-07-02 04:32:03 EDT (Fri, 02 Jul 2010)
@@ -1,5 +1,6 @@
 
 // Copyright Aleksey Gurtovoy 2000-2004
+// Copyright Daniel Walker 2007
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -16,6 +17,12 @@
 #include <boost/mpl/aux_/test.hpp>
 
 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)
 
 struct a1 {};
 struct a2 { void xxx(); };
@@ -31,6 +38,13 @@
 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 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 {}; };
+
 template< typename T > struct outer;
 template< typename T > struct inner { typedef typename T::type type; };
 
@@ -42,25 +56,195 @@
 MPL_TEST_CASE()
 {
     MPL_ASSERT_NOT(( has_xxx<int> ));
+ 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 > ));
+
 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
     MPL_ASSERT_NOT(( has_xxx<int&> ));
+ 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<int*> ));
+ 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<int[]> ));
+ 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<int (*)()> ));
+ 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<a2> ));
+ 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<a3> ));
+ 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<a4> ));
+ 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 > ));
+
 #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202))
     MPL_ASSERT_NOT(( has_xxx<a5> ));
 #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 > ));
 #endif
+
     MPL_ASSERT_NOT(( has_xxx<a1> ));
+ 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< outer< inner<int> > > ));
+ MPL_ASSERT_NOT(( has_xxx0< outer< inner<int> > > ));
+ MPL_ASSERT_NOT(( has_xxx1< outer< inner<int> >, int > ));
+ MPL_ASSERT_NOT(( has_xxx2< outer< inner<int> >, int, int > ));
+ MPL_ASSERT_NOT(( has_yyy0< outer< inner<int> > > ));
+ MPL_ASSERT_NOT(( has_yyy1< outer< inner<int> >, int > ));
+ MPL_ASSERT_NOT(( has_yyy2< outer< inner<int> >, int, int > ));
+
     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< 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< 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 > ));
+
+#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 > ));
+#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<c2, int> ));
+ MPL_ASSERT_NOT(( has_xxx2<c0, int, int> ));
+ MPL_ASSERT_NOT(( has_xxx2<c1, int, int> ));
+#endif
+
+ // Different name, same args.
+ MPL_ASSERT_NOT(( has_xxx0<c3> ));
+ MPL_ASSERT_NOT(( has_xxx1<c4, int> ));
+ MPL_ASSERT_NOT(( has_xxx2<c5, int, int> ));
+
+ // Different name, different args.
+ MPL_ASSERT_NOT(( has_xxx0<c4> ));
+ MPL_ASSERT_NOT(( has_xxx1<c5, int> ));
+ MPL_ASSERT_NOT(( has_xxx2<c3, int, int> ));
+ MPL_ASSERT_NOT(( has_xxx2<c4, int, int> ));
 
     MPL_ASSERT(( has_xxx<b1,true_> ));
     MPL_ASSERT(( has_xxx<b2,true_> ));
@@ -70,6 +254,15 @@
     MPL_ASSERT(( has_xxx<b6,true_> ));
     MPL_ASSERT(( has_xxx<b7,true_> ));
 
+#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, >= 1500)
+ MPL_ASSERT(( has_xxx0<c0, true_> ));
+ MPL_ASSERT(( has_yyy0<c3, true_> ));
+#endif
+ MPL_ASSERT(( has_xxx1<c1, int, true_> ));
+ MPL_ASSERT(( has_xxx2<c2, int, int, true_> ));
+ MPL_ASSERT(( has_yyy1<c4, int, true_> ));
+ MPL_ASSERT(( has_yyy2<c5, int, int, true_> ));
+
 #if !defined(HAS_XXX_ASSERT)
 # define HAS_XXX_ASSERT(x) MPL_ASSERT(x)
 #endif
@@ -81,4 +274,17 @@
     HAS_XXX_ASSERT(( has_xxx<b5> ));
     HAS_XXX_ASSERT(( has_xxx<b6> ));
     HAS_XXX_ASSERT(( has_xxx<b7> ));
+
+#if !defined(HAS_XXX_TEMPLATE_ASSERT)
+# 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<c0> ));
+ HAS_XXX_TEMPLATE_ASSERT(( has_yyy0<c3> ));
+#endif
+ HAS_XXX_TEMPLATE_ASSERT(( has_xxx1<c1, int> ));
+ HAS_XXX_TEMPLATE_ASSERT(( has_xxx2<c2, int, int> ));
+ HAS_XXX_TEMPLATE_ASSERT(( has_yyy1<c4, int> ));
+ HAS_XXX_TEMPLATE_ASSERT(( has_yyy2<c5, int, int> ));
 }

Modified: branches/release/libs/mpl/test/no_has_xxx.cpp
==============================================================================
--- branches/release/libs/mpl/test/no_has_xxx.cpp (original)
+++ branches/release/libs/mpl/test/no_has_xxx.cpp 2010-07-02 04:32:03 EDT (Fri, 02 Jul 2010)
@@ -23,4 +23,8 @@
 # define HAS_XXX_ASSERT(x) MPL_ASSERT_NOT(x)
 #endif
 
+#if defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
+# define HAS_XXX_TEMPLATE_ASSERT(x) MPL_ASSERT_NOT(x)
+#endif
+
 #include "has_xxx.cpp"


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk