From c1de64359f2a46c4dd0e66bbbfb74f615c8db04e Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Wed, 19 Aug 2009 22:52:27 +0000 Subject: [PATCH 01/26] Provide definitions for the dummy structs used by has_push_back_impl and has_push_front_impl so that they work with Fusion containers. Fixes #3337. [SVN r55672] --- include/boost/mpl/aux_/push_back_impl.hpp | 2 +- include/boost/mpl/aux_/push_front_impl.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/mpl/aux_/push_back_impl.hpp b/include/boost/mpl/aux_/push_back_impl.hpp index 3ece711..27e7a60 100644 --- a/include/boost/mpl/aux_/push_back_impl.hpp +++ b/include/boost/mpl/aux_/push_back_impl.hpp @@ -25,7 +25,7 @@ namespace boost { namespace mpl { -struct has_push_back_arg; +struct has_push_back_arg {}; // agurt 05/feb/04: no default implementation; the stub definition is needed // to enable the default 'has_push_back' implementation below diff --git a/include/boost/mpl/aux_/push_front_impl.hpp b/include/boost/mpl/aux_/push_front_impl.hpp index 4010532..5b83ee7 100644 --- a/include/boost/mpl/aux_/push_front_impl.hpp +++ b/include/boost/mpl/aux_/push_front_impl.hpp @@ -25,7 +25,7 @@ namespace boost { namespace mpl { -struct has_push_front_arg; +struct has_push_front_arg {}; // agurt 05/feb/04: no default implementation; the stub definition is needed // to enable the default 'has_push_front' implementation below From d38f271fae14063cfa6a8b7e69a0e870a01a61ce Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Sun, 23 Aug 2009 04:42:25 +0000 Subject: [PATCH 02/26] Use order instead of size to find the next order in the non-typeof implementation of mpl::insert for mpl::map. Fixes #2042. [SVN r55727] --- include/boost/mpl/map/aux_/insert_impl.hpp | 2 +- test/map.cpp | 23 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/boost/mpl/map/aux_/insert_impl.hpp b/include/boost/mpl/map/aux_/insert_impl.hpp index 42232a2..fb61ed9 100644 --- a/include/boost/mpl/map/aux_/insert_impl.hpp +++ b/include/boost/mpl/map/aux_/insert_impl.hpp @@ -39,7 +39,7 @@ struct map_insert_impl > #else , m_item< - next< typename Map::size >::type::value + Map::order::value , typename Pair::first , typename Pair::second , Map diff --git a/test/map.cpp b/test/map.cpp index aaa44b8..17ad99d 100644 --- a/test/map.cpp +++ b/test/map.cpp @@ -194,3 +194,26 @@ MPL_TEST_CASE() test(); test(); } + +MPL_TEST_CASE() +{ + typedef mpl::erase_key< + mpl::map< + mpl::pair + , mpl::pair + > + , char + >::type int_to_float_map; + + typedef mpl::insert< + int_to_float_map + , mpl::pair + >::type with_char_too; + + BOOST_MPL_ASSERT(( + boost::is_same< + mpl::at::type + , long + > + )); +} From b74cf94d0441df84edd0eae358c9e68547e30ac4 Mon Sep 17 00:00:00 2001 From: Aleksey Gurtovoy Date: Sat, 29 Aug 2009 08:48:11 +0000 Subject: [PATCH 03/26] MPL refmanual: for_each doc fixes (thanks to Emil Dotchevski) [SVN r55858] --- doc/refmanual/for-each.html | 4 ++-- doc/src/refmanual/for_each.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/refmanual/for-each.html b/doc/refmanual/for-each.html index 28b5d54..8761b4a 100644 --- a/doc/refmanual/for-each.html +++ b/doc/refmanual/for-each.html @@ -123,7 +123,7 @@ typedef next<in>:: Postcondition:

Equivalent to

-for_each< tranform_view<s,op> >( f );
+for_each< transform_view<s,op> >( f );
 
@@ -141,7 +141,7 @@ struct value_printer { template< typename U > void operator()(U x) { - std::cout << x << 'n'; + std::cout << x << '\n'; } }; diff --git a/doc/src/refmanual/for_each.rst b/doc/src/refmanual/for_each.rst index f2fce9c..6385605 100644 --- a/doc/src/refmanual/for_each.rst +++ b/doc/src/refmanual/for_each.rst @@ -103,7 +103,7 @@ For any |Forward Sequence| ``s``, |Lambda Expression| ``op`` , and an .. parsed-literal:: - for_each< tranform_view >( f ); + for_each< transform_view >( f ); Complexity @@ -121,7 +121,7 @@ Example { template< typename U > void operator()(U x) { - std::cout << x << '\n'; + std::cout << x << '\\n'; } }; From ae88433250cb5db46c543c466bf151ad4d02b4f0 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Sat, 17 Oct 2009 02:07:38 +0000 Subject: [PATCH 04/26] rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back [SVN r56942] --- CMakeLists.txt | 28 ------------- module.cmake | 1 - test/CMakeLists.txt | 97 --------------------------------------------- 3 files changed, 126 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 module.cmake delete mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index ea43e88..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -#---------------------------------------------------------------------------- -# This file was automatically generated from the original CMakeLists.txt file -# Add a variable to hold the headers for the library -set (lib_headers - mpl -) - -# Add a library target to the build system -boost_library_project( - mpl - # SRCDIRS - TESTDIRS test - HEADERS ${lib_headers} - # DOCDIRS - DESCRIPTION "A general-purpose, high-level C++ template metaprogramming framework of compile-time algorithms, sequences and metafunctions. It provides a conceptual foundation and an extensive set of powerful and coherent tools that make doing explict metaprogramming in C++ as easy and enjoyable as possible within the current language." - MODULARIZED - AUTHORS "Aleksey Gurtovoy " - "David Abrahams " - # MAINTAINERS -) - - diff --git a/module.cmake b/module.cmake deleted file mode 100644 index afa88fd..0000000 --- a/module.cmake +++ /dev/null @@ -1 +0,0 @@ -boost_module(mpl DEPENDS preprocessor config detail) \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index e8b182b..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,97 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -boost_additional_test_dependencies(mpl BOOST_DEPENDS test bind) - -boost_test_compile(largest_int aux_/largest_int.cpp) -boost_test_compile(msvc_is_class aux_/msvc_is_class.cpp) -boost_test_compile(template_arity aux_/template_arity.cpp) - -boost_test_compile(advance) -boost_test_compile(always) -boost_test_compile(apply) -boost_test_compile(apply_wrap) -boost_test_compile(arithmetic) -boost_test_compile(as_sequence) -boost_test_compile(assert) -boost_test_compile(at) -boost_test_compile(back) -boost_test_compile(bind) -boost_test_compile(bitwise) -boost_test_run(bool) -boost_test_compile(comparison) -boost_test_compile(contains) -boost_test_compile(copy) -boost_test_compile(copy_if) -boost_test_compile(count) -boost_test_compile(count_if) -boost_test_compile(deque) -boost_test_compile(distance) -boost_test_compile(empty) -boost_test_compile(equal) -boost_test_compile(erase) -boost_test_compile(erase_range) -boost_test_compile(eval_if) -boost_test_compile(filter_view) -boost_test_compile(find) -boost_test_compile(find_if) -boost_test_compile(fold) -boost_test_run(for_each) -boost_test_compile(front) -boost_test_compile(has_xxx) -boost_test_compile(identity) -boost_test_compile(if) -boost_test_compile(index_of) -boost_test_compile(inherit) -boost_test_compile(insert) -boost_test_compile(insert_range) -boost_test_run(int) -boost_test_run(integral_c) -boost_test_compile(is_placeholder) -boost_test_compile(is_sequence) -boost_test_compile(iterator_tags) -boost_test_compile(joint_view) -boost_test_compile(lambda) -boost_test_compile(lambda_args) -boost_test_compile(list) -boost_test_compile(list_c) -boost_test_compile(logical) -boost_test_compile(lower_bound) -boost_test_compile(map) -boost_test_compile(max_element) -boost_test_compile(min_max) -boost_test_compile(multiset) -boost_test_compile(next) -boost_test_compile(no_has_xxx) -boost_test_compile(numeric_ops) -boost_test_compile(pair_view) -boost_test_compile(partition) -boost_test_compile(pop_front) -boost_test_compile(push_front) -boost_test_compile(quote) -boost_test_compile(range_c) -boost_test_compile(remove) -boost_test_compile(remove_if) -boost_test_compile(replace) -boost_test_compile(replace_if) -boost_test_compile(reverse) -boost_test_compile(same_as) -boost_test_compile(set) -boost_test_compile(set_c) -boost_test_compile(single_view) -boost_test_compile(size) -boost_test_run(size_t) -boost_test_compile(sizeof) -boost_test_compile(sort) -boost_test_compile(stable_partition) -boost_test_compile(transform) -boost_test_compile(transform_view) -boost_test_compile(unique) -boost_test_compile(unpack_args) -boost_test_compile(upper_bound) -boost_test_compile(vector) -boost_test_compile(vector_c) -boost_test_compile(zip_view) From 9e7f06d29bdc6531a38bb3a0a22f750fa29c3c16 Mon Sep 17 00:00:00 2001 From: Aleksey Gurtovoy Date: Thu, 3 Dec 2009 10:44:05 +0000 Subject: [PATCH 05/26] Fix bogus protect example [SVN r58111] --- doc/src/refmanual/protect.rst | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/doc/src/refmanual/protect.rst b/doc/src/refmanual/protect.rst index cf4f967..1ede413 100644 --- a/doc/src/refmanual/protect.rst +++ b/doc/src/refmanual/protect.rst @@ -81,25 +81,22 @@ Example .. parsed-literal:: - FIXME - struct f { template< typename T1, typename T2 > struct apply { - // |...| + typedef T2 type; }; }; - - typedef bind<_1, protect< bind > > - - typedef apply_wrap0< f0 >::type r1; - typedef apply_wrap0< g0 >::type r2; - typedef apply_wrap2< f2,int,char >::type r3; - + + typedef bind< quote\ ``3``\,_1,_2,bind > b1; + typedef bind< quote\ ``3``\,_1,_2,protect< bind > > b2; + + typedef apply_wrap\ ``2``\< b1,false\_,char >::type r1; + typedef apply_wrap\ ``2``\< b2,false\_,char >::type r2; + BOOST_MPL_ASSERT(( is_same )); - BOOST_MPL_ASSERT(( is_same )); - BOOST_MPL_ASSERT(( is_same )); + BOOST_MPL_ASSERT(( is_same > > )); See also From 38e0d6157fcabbc3149cc5ad2fe96e2fe43bc8f8 Mon Sep 17 00:00:00 2001 From: Aleksey Gurtovoy Date: Sun, 24 Jan 2010 05:45:36 +0000 Subject: [PATCH 06/26] Fix bitand/bitor conflicts with iso64.h header [SVN r59248] --- include/boost/mpl/bitand.hpp | 24 +++++++++++++++++++++++- include/boost/mpl/bitor.hpp | 24 +++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/include/boost/mpl/bitand.hpp b/include/boost/mpl/bitand.hpp index 2d6790d..0e9f1c8 100644 --- a/include/boost/mpl/bitand.hpp +++ b/include/boost/mpl/bitand.hpp @@ -2,7 +2,7 @@ #ifndef BOOST_MPL_BITAND_HPP_INCLUDED #define BOOST_MPL_BITAND_HPP_INCLUDED -// Copyright Aleksey Gurtovoy 2000-2004 +// Copyright Aleksey Gurtovoy 2000-2009 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. @@ -15,9 +15,31 @@ // $Date$ // $Revision$ +// agurt, 23/jan/10: workaround a conflict with header's +// macros, see http://tinyurl.com/ycwdxco; 'defined(bitand)' +// has to be checked in a separate condition, otherwise GCC complains +// about 'bitand' being an alternative token +#if defined(_MSC_VER) +#ifndef __GCCXML__ +#if defined(bitand) +# pragma push_macro("bitand") +# undef bitand +# define bitand(x) +#endif +#endif +#endif + #define AUX778076_OP_NAME bitand_ #define AUX778076_OP_PREFIX bitand #define AUX778076_OP_TOKEN & #include +#if defined(_MSC_VER) +#ifndef __GCCXML__ +#if defined(bitand) +# pragma pop_macro("bitand") +#endif +#endif +#endif + #endif // BOOST_MPL_BITAND_HPP_INCLUDED diff --git a/include/boost/mpl/bitor.hpp b/include/boost/mpl/bitor.hpp index 2a401ab..4333253 100644 --- a/include/boost/mpl/bitor.hpp +++ b/include/boost/mpl/bitor.hpp @@ -2,7 +2,7 @@ #ifndef BOOST_MPL_BITOR_HPP_INCLUDED #define BOOST_MPL_BITOR_HPP_INCLUDED -// Copyright Aleksey Gurtovoy 2000-2004 +// Copyright Aleksey Gurtovoy 2000-2009 // Copyright Jaap Suter 2003 // // Distributed under the Boost Software License, Version 1.0. @@ -15,9 +15,31 @@ // $Date$ // $Revision$ +// agurt, 23/jan/10: workaround a conflict with header's +// macros, see http://tinyurl.com/ycwdxco; 'defined(bitor)' +// has to be checked in a separate condition, otherwise GCC complains +// about 'bitor' being an alternative token +#if defined(_MSC_VER) +#ifndef __GCCXML__ +#if defined(bitor) +# pragma push_macro("bitor") +# undef bitor +# define bitor(x) +#endif +#endif +#endif + #define AUX778076_OP_NAME bitor_ #define AUX778076_OP_PREFIX bitor #define AUX778076_OP_TOKEN | #include +#if defined(_MSC_VER) +#ifndef __GCCXML__ +#if defined(bitor) +# pragma pop_macro("bitor") +#endif +#endif +#endif + #endif // BOOST_MPL_BITOR_HPP_INCLUDED From 4678423fee4f6746c2d8d463d660a0df236b5db0 Mon Sep 17 00:00:00 2001 From: Aleksey Gurtovoy Date: Sun, 28 Mar 2010 14:23:38 +0000 Subject: [PATCH 07/26] Fix for #1992 [SVN r60888] --- include/boost/mpl/zip_view.hpp | 3 ++- test/zip_view.cpp | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/boost/mpl/zip_view.hpp b/include/boost/mpl/zip_view.hpp index 4dc2d84..d709230 100644 --- a/include/boost/mpl/zip_view.hpp +++ b/include/boost/mpl/zip_view.hpp @@ -2,7 +2,7 @@ #ifndef BOOST_MPL_ZIP_VIEW_HPP_INCLUDED #define BOOST_MPL_ZIP_VIEW_HPP_INCLUDED -// Copyright Aleksey Gurtovoy 2000-2002 +// Copyright Aleksey Gurtovoy 2000-2010 // Copyright David Abrahams 2000-2002 // // Distributed under the Boost Software License, Version 1.0. @@ -53,6 +53,7 @@ struct zip_view public: typedef nested_begin_end_tag tag; + typedef zip_view type; typedef zip_iterator begin; typedef zip_iterator end; }; diff --git a/test/zip_view.cpp b/test/zip_view.cpp index c235034..a8d9b03 100644 --- a/test/zip_view.cpp +++ b/test/zip_view.cpp @@ -1,5 +1,5 @@ -// Copyright Aleksey Gurtovoy 2002-2004 +// Copyright Aleksey Gurtovoy 2002-2010 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -25,6 +25,8 @@ #include +#include + MPL_TEST_CASE() { @@ -38,4 +40,6 @@ MPL_TEST_CASE() , filter_view< range_c, is_even<_> > , equal_to<_,_> > )); + + MPL_ASSERT(( boost::is_same< zip_view >, zip_view >::type > )); } From cc82b7a9241636f4869245195d680907c2d0d56c Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Wed, 21 Apr 2010 17:19:06 +0000 Subject: [PATCH 08/26] MPL: fixed #4061: gcc-4.5 compilation problems related to arity_helper, applied attached patch to the main aux_/template_arity.hpp and regenerated the corresponding file preprocessed/gcc/template_arity.hpp. No other preprocessed files are affected. This patch seemed to be fine as all it does is to qualify an internal name in order to avoid it being looked up through ADL. This appears to be reasonably safe as this name is internal and not supposed to be found using ADL in the first place. [SVN r61467] --- .../boost/mpl/aux_/preprocessed/gcc/template_arity.hpp | 8 ++------ include/boost/mpl/aux_/template_arity.hpp | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/include/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp b/include/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp index 3e7bfba..daec4b8 100644 --- a/include/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp +++ b/include/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp @@ -6,11 +6,10 @@ // http://www.boost.org/LICENSE_1_0.txt) // -// Preprocessed version of "boost/mpl/aux_/template_arity.hpp" header +// *Preprocessed* version of the main "template_arity.hpp" header // -- DO NOT modify by hand! namespace boost { namespace mpl { namespace aux { - template< int N > struct arity_tag { typedef char (&type)[N + 1]; @@ -23,7 +22,6 @@ struct max_arity { BOOST_STATIC_CONSTANT(int, value = ( C6 > 0 ? C6 : ( C5 > 0 ? C5 : ( C4 > 0 ? C4 : ( C3 > 0 ? C3 : ( C2 > 0 ? C2 : ( C1 > 0 ? C1 : -1 ) ) ) ) ) ) - ); }; @@ -83,7 +81,7 @@ template< typename F, int N > struct template_arity_impl { BOOST_STATIC_CONSTANT(int, value = - sizeof(arity_helper(type_wrapper(), arity_tag())) - 1 + sizeof(::boost::mpl::aux::arity_helper(type_wrapper(), arity_tag())) - 1 ); }; @@ -92,9 +90,7 @@ struct template_arity { BOOST_STATIC_CONSTANT(int, value = ( max_arity< template_arity_impl< F,1 >::value, template_arity_impl< F,2 >::value, template_arity_impl< F,3 >::value, template_arity_impl< F,4 >::value, template_arity_impl< F,5 >::value, template_arity_impl< F,6 >::value >::value - )); - typedef mpl::int_ type; }; diff --git a/include/boost/mpl/aux_/template_arity.hpp b/include/boost/mpl/aux_/template_arity.hpp index 18cc49f..f011159 100644 --- a/include/boost/mpl/aux_/template_arity.hpp +++ b/include/boost/mpl/aux_/template_arity.hpp @@ -98,7 +98,7 @@ template< typename F, BOOST_MPL_AUX_NTTP_DECL(int, N) > struct template_arity_impl { BOOST_STATIC_CONSTANT(int, value = - sizeof(arity_helper(type_wrapper(),arity_tag())) - 1 + sizeof(::boost::mpl::aux::arity_helper(type_wrapper(),arity_tag())) - 1 ); }; From b6e98cdd5a01e8c82ee818710102ad3e2d941441 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Tue, 11 May 2010 18:30:04 +0000 Subject: [PATCH 09/26] Fixed defect that showed up with Visual C++ 10. This has been affecting numerous libraries as a knock-on effect. [SVN r61916] --- include/boost/mpl/eval_if.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/mpl/eval_if.hpp b/include/boost/mpl/eval_if.hpp index 442194f..18d6a64 100644 --- a/include/boost/mpl/eval_if.hpp +++ b/include/boost/mpl/eval_if.hpp @@ -39,6 +39,7 @@ struct eval_if #else : if_::type { + typedef typename if_::type type; #endif BOOST_MPL_AUX_LAMBDA_SUPPORT(3,eval_if,(C,F1,F2)) }; @@ -61,6 +62,7 @@ struct eval_if_c #else : if_c::type { + typedef typename if_c::type type; #endif }; From 52d8442055e1fad72baa7acc7ff8d9fc1a82c766 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Tue, 11 May 2010 22:20:19 +0000 Subject: [PATCH 10/26] Improve compatibility with compilers other than GCC. [SVN r61922] --- include/boost/mpl/eval_if.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/boost/mpl/eval_if.hpp b/include/boost/mpl/eval_if.hpp index 18d6a64..e892703 100644 --- a/include/boost/mpl/eval_if.hpp +++ b/include/boost/mpl/eval_if.hpp @@ -4,8 +4,8 @@ // Copyright Aleksey Gurtovoy 2000-2004 // -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/mpl for documentation. @@ -39,12 +39,11 @@ struct eval_if #else : if_::type { - typedef typename if_::type type; #endif BOOST_MPL_AUX_LAMBDA_SUPPORT(3,eval_if,(C,F1,F2)) }; -// (almost) copy & paste in order to save one more +// (almost) copy & paste in order to save one more // recursively nested template instantiation to user template< bool C @@ -62,7 +61,6 @@ struct eval_if_c #else : if_c::type { - typedef typename if_c::type type; #endif }; From 360322e894f9009b48770bd675223486ef96b282 Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Tue, 8 Jun 2010 14:24:55 +0000 Subject: [PATCH 11/26] Add BOOST_MPL_HAS_XXX_TEMPLATE_DEF. Fixes #861 [SVN r62579] --- doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst | 32 + doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst | 125 ++++ .../refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst | 170 ++++++ include/boost/mpl/aux_/config/has_xxx.hpp | 1 + include/boost/mpl/has_xxx.hpp | 557 ++++++++++++++++++ test/has_xxx.cpp | 206 +++++++ test/no_has_xxx.cpp | 4 + 7 files changed, 1095 insertions(+) create mode 100644 doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst create mode 100644 doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst create mode 100644 doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst diff --git a/doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst b/doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst new file mode 100644 index 0000000..7f2b38e --- /dev/null +++ b/doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst @@ -0,0 +1,32 @@ +.. Macros/Configuration//BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE |20 + +.. Copyright Daniel Walker 2007. +.. Distributed under the Boost +.. Software License, Version 1.0. (See accompanying +.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE +================================= + +Synopsis +-------- + +.. parsed-literal:: + + // #define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE + + +Description +----------- + +``BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE`` is a boolean configuration +macro signaling availability of the |BOOST_MPL_HAS_XXX_TEMPLATE_DEF| / +|BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| introspection macros' +functionality on a particular compiler. + + +See also +-------- + +|Macros|, |Configuration|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| + diff --git a/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst b/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst new file mode 100644 index 0000000..bcf19bb --- /dev/null +++ b/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst @@ -0,0 +1,125 @@ +.. Macros/Introspection//BOOST_MPL_HAS_XXX_TEMPLATE_DEF + +.. Copyright Daniel Walker 2007. +.. Distributed under the Boost +.. Software License, Version 1.0. (See accompanying +.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +BOOST_MPL_HAS_XXX_TEMPLATE_DEF +============================== + +Synopsis +-------- + +.. parsed-literal:: + + #define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \\ + |unspecified-token-seq| \\ + /\*\*/ + + +Description +----------- + +Expands into the definition of a boolean n-ary |Metafunction| +``has_name`` such that for any types ``x, a1, a2, ..., an`` +``has_name::value == true`` if and only if ``x`` is a +class type and has a nested template member ``x::template name``. + +On deficient compilers not capable of performing the detection, +``has_name::value`` always returns ``false``. A +boolean configuration macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is +provided to signal or override the "deficient" status of a particular +compiler. + +|Note:| |BOOST_MPL_HAS_XXX_TEMPLATE_DEF| is a simplified front end to +the |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| introspection macro |-- end +note| + + +Header +------ + +.. parsed-literal:: + + #include + + +Parameters +---------- + + ++---------------+-------------------------------+---------------------------------------------------+ +| Parameter | Requirement | Description | ++===============+===============================+===================================================+ +| ``name`` | A legal identifier token | A name of the template member being detected. | ++---------------+-------------------------------+---------------------------------------------------+ +| ``n`` | An integral constant >= 0 | The arity of the template member being detected. | ++---------------+-------------------------------+---------------------------------------------------+ + + +Expression semantics +-------------------- + +For any legal C++ identifier ``name`` and integral constant expression +``n`` greater than or equal to 0: + +.. parsed-literal:: + + BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) + +:Precondition: + Appears at namespace scope. + +:Return type: + None. + +:Semantics: + Equivalent to + + .. parsed-literal:: + + BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( + BOOST_PP_CAT(has\_,name), name, n, false + ) + + +Example +------- + +.. parsed-literal:: + + BOOST_MPL_HAS_XXX_TEMPLATE_DEF(xxx, 1) + + struct test1 {}; + struct test2 { void xxx(); }; + struct test3 { int xxx; }; + struct test4 { static int xxx(); }; + struct test5 { typedef int xxx; }; + struct test6 { struct xxx; }; + struct test7 { typedef void (\*xxx)(); }; + struct test8 { typedef void (xxx)(); }; + struct test9 { template< class T > struct xxx {}; }; + + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + + #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) + BOOST_MPL_ASSERT(( has_xxx )); + #endif + + BOOST_MPL_ASSERT(( has_xxx )); + + +See also +-------- + +|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| + diff --git a/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst b/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst new file mode 100644 index 0000000..93706d3 --- /dev/null +++ b/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst @@ -0,0 +1,170 @@ +.. Macros/Introspection//BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF + +.. Copyright Daniel Walker 2007. +.. Distributed under the Boost +.. Software License, Version 1.0. (See accompanying +.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF +==================================== + +Synopsis +-------- + +.. parsed-literal:: + + #define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default\_) \\ + |unspecified-token-seq| \\ + /\*\*/ + + +Description +----------- + +Expands into the definition of a boolean n-ary |Metafunction| ``trait`` +such that for any types ``x, a1, a2, ..., an`` ``trait::value == true`` if and only if ``x`` is a class type and has a +nested template member ``x::template name``. + +On deficient compilers not capable of performing the detection, +``trait::value`` always returns a fallback value +``default_``. A boolean configuration macro, +|BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is provided to signal or override +the "deficient" status of a particular compiler. |Note:| The fallback +value can also be provided at the point of the metafunction +invocation; see the `Expression semantics` section for details |-- end +note| + + +Header +------ + +.. parsed-literal:: + + #include + + +Parameters +---------- + ++---------------+-------------------------------+---------------------------------------------------+ +| Parameter | Requirement | Description | ++===============+===============================+===================================================+ +| ``trait`` | A legal identifier token | A name of the metafunction to be generated. | ++---------------+-------------------------------+---------------------------------------------------+ +| ``name`` | A legal identifier token | A name of the member being detected. | ++---------------+-------------------------------+---------------------------------------------------+ +| ``n`` | An integral constant >= 0 | The arity of the template member being detected. | ++---------------+-------------------------------+---------------------------------------------------+ +| ``default_`` | An boolean constant | A fallback value for the deficient compilers. | ++---------------+-------------------------------+---------------------------------------------------+ + + +Expression semantics +-------------------- + +For any legal C++ identifiers ``trait`` and ``name``, integral +constant expression ``n`` greater than or equal to 0, boolean constant +expression ``c1``, boolean |Integral Constant| ``c2``, and arbitrary +type ``x``: + +.. parsed-literal:: + + BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, c1) + +:Precondition: + Appears at namespace scope. + +:Return type: + None. + +:Semantics: + Expands into an equivalent of the following class template + definition + + .. parsed-literal:: + + template< + typename X + , typename A1, ..., typename An + , typename fallback = boost::mpl::bool\_ + > + struct trait + { + // |unspecified| + // ... + }; + + where ``trait`` is a boolean |Metafunction| with the following + semantics: + + .. parsed-literal:: + + typedef trait::type r; + + :Return type: + |Integral Constant|. + + :Semantics: + If |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| is defined, ``r::value + == c1``; otherwise, ``r::value == true`` if and only if ``x`` + is a class type that has a nested type member ``x::template + name``. + + + .. parsed-literal:: + + typedef trait< x, a1, ..., an, c2 >::type r; + + :Return type: + |Integral Constant|. + + :Semantics: + If |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| is defined, ``r::value + == c2::value``; otherwise, equivalent to + + .. parsed-literal:: + + typedef trait::type r; + + +Example +------- + +.. parsed-literal:: + + BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( + has_xxx, xxx, 1, false + ) + + struct test1 {}; + struct test2 { void xxx(); }; + struct test3 { int xxx; }; + struct test4 { static int xxx(); }; + struct test5 { typedef int xxx; }; + struct test6 { struct xxx; }; + struct test7 { typedef void (\*xxx)(); }; + struct test8 { typedef void (xxx)(); }; + struct test9 { template< class T > struct xxx {}; }; + + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + + #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) + BOOST_MPL_ASSERT(( has_xxx )); + #endif + + BOOST_MPL_ASSERT(( has_xxx )); + + +See also +-------- + +|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| + diff --git a/include/boost/mpl/aux_/config/has_xxx.hpp b/include/boost/mpl/aux_/config/has_xxx.hpp index b5ab90c..b0f2f8c 100644 --- a/include/boost/mpl/aux_/config/has_xxx.hpp +++ b/include/boost/mpl/aux_/config/has_xxx.hpp @@ -27,6 +27,7 @@ ) # define BOOST_MPL_CFG_NO_HAS_XXX +# define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE #endif diff --git a/include/boost/mpl/has_xxx.hpp b/include/boost/mpl/has_xxx.hpp index bd08279..4b201d8 100644 --- a/include/boost/mpl/has_xxx.hpp +++ b/include/boost/mpl/has_xxx.hpp @@ -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 #include #include +#include #include #include #include #include #include +#include #include +#include +#include +#include #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) ) # include @@ -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 diff --git a/test/has_xxx.cpp b/test/has_xxx.cpp index 0b42674..f755ae5 100644 --- a/test/has_xxx.cpp +++ b/test/has_xxx.cpp @@ -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_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 b5 { typedef int xxx[10]; }; struct b6 { typedef void (*xxx)(); }; struct b7 { typedef void (xxx)(); }; +struct c0 { template< typename T0 = int > struct xxx {}; }; +struct c1 { template< typename T1 > struct xxx {}; }; +struct 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 @@ template< typename T > struct xxx; MPL_TEST_CASE() { MPL_ASSERT_NOT(( has_xxx )); + MPL_ASSERT_NOT(( has_xxx0< int > )); + MPL_ASSERT_NOT(( has_xxx1< int, int > )); + MPL_ASSERT_NOT(( has_xxx2< int, int, int > )); + MPL_ASSERT_NOT(( has_yyy0< int > )); + MPL_ASSERT_NOT(( has_yyy1< int, int > )); + MPL_ASSERT_NOT(( has_yyy2< int, int, int > )); + #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) MPL_ASSERT_NOT(( has_xxx )); + MPL_ASSERT_NOT(( has_xxx0< int& > )); + MPL_ASSERT_NOT(( has_xxx1< int&, int > )); + MPL_ASSERT_NOT(( has_xxx2< int&, int, int > )); + MPL_ASSERT_NOT(( has_yyy0< int& > )); + MPL_ASSERT_NOT(( has_yyy1< int&, int > )); + MPL_ASSERT_NOT(( has_yyy2< int&, int, int > )); + MPL_ASSERT_NOT(( has_xxx )); + 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 )); + 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 )); + 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 )); + 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 )); + 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 )); + 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 )); #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 )); + 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 > > )); + MPL_ASSERT_NOT(( has_xxx0< outer< inner > > )); + MPL_ASSERT_NOT(( has_xxx1< outer< inner >, int > )); + MPL_ASSERT_NOT(( has_xxx2< outer< inner >, int, int > )); + MPL_ASSERT_NOT(( has_yyy0< outer< inner > > )); + MPL_ASSERT_NOT(( has_yyy1< outer< inner >, int > )); + MPL_ASSERT_NOT(( has_yyy2< outer< inner >, int, int > )); + MPL_ASSERT_NOT(( has_xxx< 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 )); + MPL_ASSERT_NOT(( has_xxx2 )); + MPL_ASSERT_NOT(( has_xxx2 )); +#endif + + // Different name, same args. + MPL_ASSERT_NOT(( has_xxx0 )); + MPL_ASSERT_NOT(( has_xxx1 )); + MPL_ASSERT_NOT(( has_xxx2 )); + + // Different name, different args. + MPL_ASSERT_NOT(( has_xxx0 )); + MPL_ASSERT_NOT(( has_xxx1 )); + MPL_ASSERT_NOT(( has_xxx2 )); + MPL_ASSERT_NOT(( has_xxx2 )); MPL_ASSERT(( has_xxx )); MPL_ASSERT(( has_xxx )); @@ -70,6 +254,15 @@ MPL_TEST_CASE() MPL_ASSERT(( has_xxx )); MPL_ASSERT(( has_xxx )); +#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, >= 1500) + MPL_ASSERT(( has_xxx0 )); + MPL_ASSERT(( has_yyy0 )); +#endif + MPL_ASSERT(( has_xxx1 )); + MPL_ASSERT(( has_xxx2 )); + MPL_ASSERT(( has_yyy1 )); + MPL_ASSERT(( has_yyy2 )); + #if !defined(HAS_XXX_ASSERT) # define HAS_XXX_ASSERT(x) MPL_ASSERT(x) #endif @@ -81,4 +274,17 @@ MPL_TEST_CASE() HAS_XXX_ASSERT(( has_xxx )); HAS_XXX_ASSERT(( has_xxx )); HAS_XXX_ASSERT(( has_xxx )); + +#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 )); + HAS_XXX_TEMPLATE_ASSERT(( has_yyy0 )); +#endif + HAS_XXX_TEMPLATE_ASSERT(( has_xxx1 )); + HAS_XXX_TEMPLATE_ASSERT(( has_xxx2 )); + HAS_XXX_TEMPLATE_ASSERT(( has_yyy1 )); + HAS_XXX_TEMPLATE_ASSERT(( has_yyy2 )); } diff --git a/test/no_has_xxx.cpp b/test/no_has_xxx.cpp index 1f525d5..53e4691 100644 --- a/test/no_has_xxx.cpp +++ b/test/no_has_xxx.cpp @@ -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" From a5ba97129732dad17542a6487231b70e60cb8a97 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Wed, 16 Jun 2010 17:57:41 +0000 Subject: [PATCH 12/26] make mpl::string work with mpl::transform [SVN r63024] --- include/boost/mpl/string.hpp | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/include/boost/mpl/string.hpp b/include/boost/mpl/string.hpp index 6a9481a..c62d8ab 100644 --- a/include/boost/mpl/string.hpp +++ b/include/boost/mpl/string.hpp @@ -240,6 +240,18 @@ namespace boost { namespace mpl }; }; + template + struct has_push_back_impl; + + template<> + struct has_push_back_impl + { + template + struct apply + : mpl::true_ + {}; + }; + template struct pop_back_impl; @@ -267,6 +279,18 @@ namespace boost { namespace mpl #undef M0 }; + template + struct has_pop_back_impl; + + template<> + struct has_pop_back_impl + { + template + struct apply + : mpl::true_ + {}; + }; + template struct push_front_impl; @@ -341,6 +365,18 @@ namespace boost { namespace mpl }; }; + template + struct has_push_front_impl; + + template<> + struct has_push_front_impl + { + template + struct apply + : mpl::true_ + {}; + }; + template struct pop_front_impl; @@ -375,6 +411,18 @@ namespace boost { namespace mpl }; }; + template + struct has_pop_front_impl; + + template<> + struct has_pop_front_impl + { + template + struct apply + : mpl::true_ + {}; + }; + template struct insert_range_impl; From ff2df79e35d4d77336e505b3cad0760e0623a8ad Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 7 Jul 2010 20:44:59 +0000 Subject: [PATCH 13/26] removed arity detection from has_xxx_template [SVN r63726] --- doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst | 53 ++- .../refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst | 67 ++- include/boost/mpl/has_xxx.hpp | 386 +++++------------- test/has_xxx.cpp | 224 +++------- 4 files changed, 200 insertions(+), 530 deletions(-) diff --git a/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst b/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst index bcf19bb..e6c8766 100644 --- a/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst +++ b/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst @@ -13,7 +13,7 @@ Synopsis .. parsed-literal:: - #define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \\ + #define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \\ |unspecified-token-seq| \\ /\*\*/ @@ -21,17 +21,16 @@ Synopsis Description ----------- -Expands into the definition of a boolean n-ary |Metafunction| -``has_name`` such that for any types ``x, a1, a2, ..., an`` -``has_name::value == true`` if and only if ``x`` is a -class type and has a nested template member ``x::template name``. +Expands into the definition of a boolean |Metafunction| ``has_name`` +such that for any type ``x`` ``has_name::value == true`` if and +only if ``x`` is a class type and has a nested template member +``x::template name`` with no more than +|BOOST_MPL_LIMIT_METAFUNCTION_ARITY| parameters. On deficient compilers not capable of performing the detection, -``has_name::value`` always returns ``false``. A -boolean configuration macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is -provided to signal or override the "deficient" status of a particular -compiler. +``has_name::value`` is always ``false``. A boolean configuration +macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is provided to signal or +override the "deficient" status of a particular compiler. |Note:| |BOOST_MPL_HAS_XXX_TEMPLATE_DEF| is a simplified front end to the |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| introspection macro |-- end @@ -55,19 +54,16 @@ Parameters +===============+===============================+===================================================+ | ``name`` | A legal identifier token | A name of the template member being detected. | +---------------+-------------------------------+---------------------------------------------------+ -| ``n`` | An integral constant >= 0 | The arity of the template member being detected. | -+---------------+-------------------------------+---------------------------------------------------+ Expression semantics -------------------- -For any legal C++ identifier ``name`` and integral constant expression -``n`` greater than or equal to 0: +For any legal C++ identifier ``name``: .. parsed-literal:: - BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) + BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) :Precondition: Appears at namespace scope. @@ -81,7 +77,7 @@ For any legal C++ identifier ``name`` and integral constant expression .. parsed-literal:: BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( - BOOST_PP_CAT(has\_,name), name, n, false + BOOST_PP_CAT(has\_,name), name, false ) @@ -90,7 +86,7 @@ Example .. parsed-literal:: - BOOST_MPL_HAS_XXX_TEMPLATE_DEF(xxx, 1) + BOOST_MPL_HAS_XXX_TEMPLATE_DEF(xxx) struct test1 {}; struct test2 { void xxx(); }; @@ -102,24 +98,25 @@ Example struct test8 { typedef void (xxx)(); }; struct test9 { template< class T > struct xxx {}; }; - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) - BOOST_MPL_ASSERT(( has_xxx )); + BOOST_MPL_ASSERT(( has_xxx )); #endif - BOOST_MPL_ASSERT(( has_xxx )); + BOOST_MPL_ASSERT(( has_xxx )); See also -------- -|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| +|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF|, +|BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, |BOOST_MPL_LIMIT_METAFUNCTION_ARITY| diff --git a/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst b/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst index 93706d3..b715cc0 100644 --- a/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst +++ b/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst @@ -13,7 +13,7 @@ Synopsis .. parsed-literal:: - #define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default\_) \\ + #define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default\_) \\ |unspecified-token-seq| \\ /\*\*/ @@ -21,19 +21,19 @@ Synopsis Description ----------- -Expands into the definition of a boolean n-ary |Metafunction| ``trait`` -such that for any types ``x, a1, a2, ..., an`` ``trait::value == true`` if and only if ``x`` is a class type and has a -nested template member ``x::template name``. +Expands into the definition of a boolean |Metafunction| ``trait`` such +that for any type ``x`` ``trait::value == true`` if and only if +``x`` is a class type and has a nested template member ``x::template +name`` with no more than |BOOST_MPL_LIMIT_METAFUNCTION_ARITY| +parameters. On deficient compilers not capable of performing the detection, -``trait::value`` always returns a fallback value -``default_``. A boolean configuration macro, -|BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is provided to signal or override -the "deficient" status of a particular compiler. |Note:| The fallback -value can also be provided at the point of the metafunction -invocation; see the `Expression semantics` section for details |-- end -note| +``trait::value`` always returns a fallback value ``default_``. A +boolean configuration macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is +provided to signal or override the "deficient" status of a particular +compiler. |Note:| The fallback value can also be provided at the +point of the metafunction invocation; see the `Expression semantics` +section for details |-- end note| Header @@ -54,8 +54,6 @@ Parameters +---------------+-------------------------------+---------------------------------------------------+ | ``name`` | A legal identifier token | A name of the member being detected. | +---------------+-------------------------------+---------------------------------------------------+ -| ``n`` | An integral constant >= 0 | The arity of the template member being detected. | -+---------------+-------------------------------+---------------------------------------------------+ | ``default_`` | An boolean constant | A fallback value for the deficient compilers. | +---------------+-------------------------------+---------------------------------------------------+ @@ -63,14 +61,13 @@ Parameters Expression semantics -------------------- -For any legal C++ identifiers ``trait`` and ``name``, integral -constant expression ``n`` greater than or equal to 0, boolean constant +For any legal C++ identifiers ``trait`` and ``name``, boolean constant expression ``c1``, boolean |Integral Constant| ``c2``, and arbitrary type ``x``: .. parsed-literal:: - BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, c1) + BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, c1) :Precondition: Appears at namespace scope. @@ -86,7 +83,6 @@ type ``x``: template< typename X - , typename A1, ..., typename An , typename fallback = boost::mpl::bool\_ > struct trait @@ -100,7 +96,7 @@ type ``x``: .. parsed-literal:: - typedef trait::type r; + typedef trait::type r; :Return type: |Integral Constant|. @@ -108,13 +104,13 @@ type ``x``: :Semantics: If |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| is defined, ``r::value == c1``; otherwise, ``r::value == true`` if and only if ``x`` - is a class type that has a nested type member ``x::template - name``. + is a class type that has a nested template member ``x::template + name`` with no more than |BOOST_MPL_LIMIT_METAFUNCTION_ARITY|. .. parsed-literal:: - typedef trait< x, a1, ..., an, c2 >::type r; + typedef trait< x, c2 >::type r; :Return type: |Integral Constant|. @@ -125,7 +121,7 @@ type ``x``: .. parsed-literal:: - typedef trait::type r; + typedef trait::type r; Example @@ -134,7 +130,7 @@ Example .. parsed-literal:: BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( - has_xxx, xxx, 1, false + has_xxx, xxx, false ) struct test1 {}; @@ -147,24 +143,25 @@ Example struct test8 { typedef void (xxx)(); }; struct test9 { template< class T > struct xxx {}; }; - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); - BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); + BOOST_MPL_ASSERT_NOT(( has_xxx )); #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) - BOOST_MPL_ASSERT(( has_xxx )); + BOOST_MPL_ASSERT(( has_xxx )); #endif - BOOST_MPL_ASSERT(( has_xxx )); + BOOST_MPL_ASSERT(( has_xxx )); See also -------- -|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| +|Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, +|BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, |BOOST_MPL_LIMIT_METAFUNCTION_ARITY| diff --git a/include/boost/mpl/has_xxx.hpp b/include/boost/mpl/has_xxx.hpp index 4b201d8..4ef0196 100644 --- a/include/boost/mpl/has_xxx.hpp +++ b/include/boost/mpl/has_xxx.hpp @@ -280,12 +280,11 @@ struct trait \ #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) -// Create boolean n-ary Metafunction to detect a nested template -// member with n template parameters. This implementation is based on -// a USENET newsgroup's posting by Aleksey Gurtovoy -// (comp.lang.c++.moderated, 2002-03-19), Rani Sharoni's USENET -// posting cited above, the non-template has_xxx implementations -// above, and discussion on the Boost mailing list. +// Create a boolean Metafunction to detect a nested template +// member. This implementation is based on a USENET newsgroup's +// posting by Aleksey Gurtovoy (comp.lang.c++.moderated, 2002-03-19), +// Rani Sharoni's USENET posting cited above, the non-template has_xxx +// implementations above, and discussion on the Boost mailing list. # if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) @@ -294,35 +293,27 @@ struct trait \ # endif # if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION) -# if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) \ - || BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303)) +# if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)) # define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1 # endif # endif -# if !defined(BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE) -# if BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303) -# define BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE 1 -# endif -# endif - # if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE) # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) # define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1 # endif # endif -// NOTE: All internal implementation macros take a Boost.Preprocessor -// array argument called args which contains the arguments passed to -// HAS_XXX_TEMPLATE_NAMED_DEF and is of the following form. -// ( 4, ( trait, name, n, default_ ) ) +// NOTE: Many internal implementation macros take a Boost.Preprocessor +// array argument called args which is of the following form. +// ( 4, ( trait, name, max_arity, default_ ) ) # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \ /**/ -# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ - BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute) \ +# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ + BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute), n) \ /**/ # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \ @@ -332,13 +323,23 @@ struct trait \ // Thanks to Guillaume Melquiond for pointing out the need for the // "substitute" template as an argument to the overloaded test // functions to get SFINAE to work for member templates with the -// correct name but incorrect arguments. -# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ - template< substitute_macro(args, V) > \ - struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) { \ +// correct name but different number of arguments. +# define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE(z, n, args) \ + template< \ + template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename V) > class V \ + > \ + struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) { \ }; \ /**/ +# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE \ + , args \ + ) \ + /**/ + # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ template< typename V > \ @@ -353,16 +354,23 @@ struct trait \ # endif # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES -# define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ +# define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \ template< typename V > \ static boost::mpl::aux::yes_tag \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ boost::mpl::aux::type_wrapper< V > const volatile* \ - , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) < \ - member_macro(args, V, T) \ + , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) < \ + V::template BOOST_PP_ARRAY_ELEM(1, args) \ >* = 0 \ ); \ /**/ +# define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT \ + , args \ + ) \ + /**/ # else # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ template< typename V > \ @@ -419,9 +427,6 @@ struct trait \ ) \ template< \ typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS( \ - BOOST_PP_ARRAY_ELEM(2, args), typename T \ - ) \ , typename fallback_ \ = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \ > \ @@ -436,45 +441,9 @@ struct trait \ }; \ /**/ -// For example, -// BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( -// (4, (has_xxx, xxx, 2, false)) -// , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER -// , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS -// ) -// expands to something like the following... -// -// template< -// typename T , typename T0 , typename T1 -// , typename fallback_ = boost::mpl::bool_< false > -// > -// class has_xxx { -// template< typename U > -// struct has_xxx_introspect { -// template< template< typename V0 , typename V1 > class V > -// struct has_xxx_substitute { -// }; -// -// template< typename V > -// static boost::mpl::aux::no_tag -// has_xxx_test(...); -// -// template< typename V > -// static boost::mpl::aux::yes_tag -// has_xxx_test( -// boost::mpl::aux::type_wrapper< V > const volatile* -// , has_xxx_substitute < V::template xxx >* = 0 -// ); -// -// static const bool value -// = sizeof(has_xxx_test< U >(0)) -// == sizeof(boost::mpl::aux::yes_tag); -// typedef boost::mpl::bool_< value > type; -// }; -// public: -// static const bool value = has_xxx_introspect< T >::value; -// typedef typename has_xxx_introspect< T >::type type; -// }; +// BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE expands to the full +// implementation of the function-based metafunction. Compile with -E +// to see the preprocessor output for this macro. # define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ args, substitute_macro, member_macro \ ) \ @@ -496,17 +465,17 @@ struct trait \ # if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, n \ ) \ - BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ /**/ # else # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, n \ ) \ BOOST_PP_CAT( \ boost_mpl_has_xxx_ \ - , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ + , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ ) \ /**/ # endif @@ -516,20 +485,20 @@ struct trait \ ) \ BOOST_PP_CAT( \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, 0 \ ) \ , _tag \ ) \ /**/ -# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro \ +# define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + z, n, args \ ) \ - typedef void \ - BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ - template< substitute_macro(args, U) > \ + template< \ + template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename U) > class U \ + > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, n \ ) { \ typedef \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ @@ -537,14 +506,23 @@ struct trait \ }; \ /**/ +# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + args, substitute_macro \ + ) \ + typedef void \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE \ + , args \ + ) \ + /**/ + # define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \ args, member_macro \ ) \ template< \ typename U \ - BOOST_PP_ENUM_TRAILING_PARAMS( \ - BOOST_PP_ARRAY_ELEM(2, args), typename U \ - ) \ , typename V \ = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ > \ @@ -554,22 +532,17 @@ struct trait \ }; \ /**/ -# define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \ - args, member_macro \ +# define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE( \ + z, n, args \ ) \ - template< \ - typename U \ - BOOST_PP_ENUM_TRAILING_PARAMS( \ - BOOST_PP_ARRAY_ELEM(2, args), typename U \ - ) \ - > \ + template< typename U > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ - U BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), U) \ + U \ , typename \ BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ - args \ + args, n \ )< \ - member_macro(args, U, U) \ + BOOST_MSVC_TYPENAME U::BOOST_PP_ARRAY_ELEM(1, args)< > \ >::type \ > { \ BOOST_STATIC_CONSTANT(bool, value = true); \ @@ -577,89 +550,30 @@ struct trait \ }; \ /**/ -# define BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ +# define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \ + args, member_macro \ + ) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE \ + , args \ + ) \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ args, substitute_macro, member_macro \ ) \ BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \ BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \ template< typename U > \ struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ - : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ - U \ - BOOST_PP_ENUM_TRAILING_PARAMS( \ - BOOST_PP_ARRAY_ELEM(2, args) \ - , T \ - ) \ - > { \ + : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U > { \ }; \ /**/ - -# if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE -# define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro, member_macro \ - ) \ - BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro \ - ) \ - BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro, member_macro \ - ) \ - /**/ -# else -# define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro, member_macro \ - ) \ - BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro, member_macro \ - ) \ - /**/ -# endif - -// For example, -// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( -// (4, (has_xxx, xxx, 2, false)) -// , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER -// , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS -// ) -// expands to something like the following... -// -// template< -// typename T , typename T0 , typename T1 -// , typename fallback_ = boost::mpl::bool_< false > -// > -// class has_xxx { -// typedef void has_xxx_substitute_tag; -// -// template< template< typename U0 , typename U1 > class U > -// struct has_xxx_substitute { -// typedef has_xxx_substitute_tag type; -// }; -// -// template< -// typename U , typename U0 , typename U1 -// , typename V = has_xxx_substitute_tag -// > -// struct has_xxx_test { -// static const bool value = false; -// typedef boost::mpl::bool_< value > type; -// }; -// -// template< typename U , typename U0 , typename U1 > -// struct has_xxx_test< -// U , U0 , U1 -// , typename has_xxx_substitute< U::template xxx >::type -// > { -// static const bool value = true; -// typedef boost::mpl::bool_< value > type; -// }; -// -// template< typename U > -// struct has_xxx_introspect : has_xxx_test< U , T0 , T1 > { -// }; -// public: -// static const bool value = has_xxx_introspect< T >::value; -// typedef typename has_xxx_introspect< T >::type type; -// }; + +// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE expands to the full +// implementation of the template-based metafunction. Compile with -E +// to see the preprocessor output for this macro. // // Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is // defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs @@ -668,6 +582,9 @@ struct trait \ # define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ args, substitute_macro, member_macro \ ) \ + BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + args, substitute_macro \ + ) \ BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ args \ , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \ @@ -678,130 +595,22 @@ struct trait \ # endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER( \ - args, param \ - ) \ - typename \ - /**/ - -# if !BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_SUBSTITUTE_PARAMETER( \ - args, param \ - ) \ - template< \ - BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), typename param) \ - > \ - class param\ - /**/ - -// See comment at BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS below. -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER(args, param) \ - BOOST_PP_IF( \ - BOOST_PP_ARRAY_ELEM(2, args) \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_SUBSTITUTE_PARAMETER \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER \ - ) ( args, param ) \ - /**/ -# else -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER(args, param) \ - BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER( \ - args, param \ - ) \ - /**/ -# endif - -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS( \ - args, class_type, param \ - ) \ - typename class_type::template BOOST_PP_ARRAY_ELEM(1, args)< \ - BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), param) \ - > \ - /**/ - -# if !BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_ACCESS( \ - args, class_type, param \ - ) \ - class_type::template BOOST_PP_ARRAY_ELEM(1, args) \ - /**/ - -// Note: to recognize templates with no required arguments use -// explicit access since a substitute template with no args cannot be -// declared. -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS(args, class_type, param) \ - BOOST_PP_IF( \ - BOOST_PP_ARRAY_ELEM(2, args) \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_ACCESS \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS \ - ) ( args, class_type, param ) \ - /**/ -# else -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS(args, class_type, param) \ - BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS( \ - args, class_type, param \ - ) \ - /**/ -# endif - -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) -// MSVC (7.1, 8.0) accepts the member template access syntax below -// regardless of the member template's arity. introspect will reject -// member templates with the wrong arity due to the substitute -// template. Note that using this syntax also enables MSVC -// template-based SFINAE to reject non-template members. This is -// important because explicitly passing the template args will match -// templates with the correct name and arguments but will cause ICE on -// non-template members. However, MSVC nullary template-based SFINAE -// (introspection for a member template with no required args) can not -// reject non-template members, but MSVC function-based SFINAE -// can. So, one of the two is chosen based on the number of required -// template parameters. -# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC( \ - args, class_type, param \ - ) \ - typename class_type::template BOOST_PP_ARRAY_ELEM(1, args)< > \ - /**/ -# else -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC( \ - args, class_type, param \ - ) \ - class_type::BOOST_PP_ARRAY_ELEM(1, agrs)< > \ - /**/ -# endif - -# define BOOST_MPL_HAS_MEMBER_TEMPLATE_MSVC( \ - args, substitute_macro, member_macro \ - ) \ - BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ - args, substitute_macro \ - ) \ - BOOST_PP_IF( \ - BOOST_PP_ARRAY_ELEM(2, args) \ - , BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE \ - , BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE \ - ) ( \ - args \ - , substitute_macro \ - , member_macro \ - ) \ - /**/ -# endif - +// Note: In the current implementation the parameter and access macros +// are no longer expanded. # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) -# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ - ( 4, ( trait, name, n, default_ ) ) \ + ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ ) \ /**/ # else -# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ - BOOST_MPL_HAS_MEMBER_TEMPLATE_MSVC( \ - ( 4, ( trait, name, n, default_ ) ) \ +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ + BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ + ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ - , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC \ + , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ ) \ /**/ # endif @@ -810,9 +619,8 @@ struct trait \ // placeholder implementation -# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ template< typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, typename U) \ , typename fallback_ = boost::mpl::bool_< default_ > > \ struct trait { \ BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \ @@ -822,9 +630,9 @@ struct trait \ #endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE -# define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \ +# define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \ BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \ - BOOST_PP_CAT(has_, name), name, n, false \ + BOOST_PP_CAT(has_, name), name, false \ ) \ /**/ diff --git a/test/has_xxx.cpp b/test/has_xxx.cpp index f755ae5..c466db2 100644 --- a/test/has_xxx.cpp +++ b/test/has_xxx.cpp @@ -17,12 +17,8 @@ #include BOOST_MPL_HAS_XXX_TRAIT_DEF(xxx) -BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx0, xxx, 0, false) -BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx1, xxx, 1, false) -BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx2, xxx, 2, false) -BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy0, 0) -BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy1, 1) -BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy2, 2) +BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx_template, xxx, false) +BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy) struct a1 {}; struct a2 { void xxx(); }; @@ -38,12 +34,13 @@ struct b5 { typedef int xxx[10]; }; struct b6 { typedef void (*xxx)(); }; struct b7 { typedef void (xxx)(); }; -struct c0 { template< typename T0 = int > struct xxx {}; }; -struct c1 { template< typename T1 > struct xxx {}; }; +struct c1 { template< typename T > struct xxx {}; }; struct c2 { template< typename T1, typename T2 > struct xxx {}; }; -struct c3 { template< typename T0 = int > struct yyy0 {}; }; -struct c4 { template< typename T1 > struct yyy1 {}; }; -struct c5 { template< typename T1, typename T2 > struct yyy2 {}; }; +struct c3 { template< typename T1, typename T2, typename T3 > struct xxx {}; }; +struct c4 { template< typename T1, typename T2, typename T3, typename T4 > struct xxx {}; }; +struct c5 { template< typename T1, typename T2, typename T3, typename T4, typename T5 > struct xxx {}; }; +struct c6 { template< typename T > struct yyy {}; }; +struct c7 { template< typename T1, typename T2 > struct yyy {}; }; template< typename T > struct outer; template< typename T > struct inner { typedef typename T::type type; }; @@ -56,195 +53,80 @@ template< typename T > struct xxx; MPL_TEST_CASE() { MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int > )); - MPL_ASSERT_NOT(( has_xxx1< int, int > )); - MPL_ASSERT_NOT(( has_xxx2< int, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int > )); - MPL_ASSERT_NOT(( has_yyy1< int, int > )); - MPL_ASSERT_NOT(( has_yyy2< int, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int& > )); - MPL_ASSERT_NOT(( has_xxx1< int&, int > )); - MPL_ASSERT_NOT(( has_xxx2< int&, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int& > )); - MPL_ASSERT_NOT(( has_yyy1< int&, int > )); - MPL_ASSERT_NOT(( has_yyy2< int&, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int* > )); - MPL_ASSERT_NOT(( has_xxx1< int*, int > )); - MPL_ASSERT_NOT(( has_xxx2< int*, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int* > )); - MPL_ASSERT_NOT(( has_yyy1< int*, int > )); - MPL_ASSERT_NOT(( has_yyy2< int*, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int[] > )); - MPL_ASSERT_NOT(( has_xxx1< int[], int > )); - MPL_ASSERT_NOT(( has_xxx2< int[], int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int[] > )); - MPL_ASSERT_NOT(( has_yyy1< int[], int > )); - MPL_ASSERT_NOT(( has_yyy2< int[], int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< int (*)() > )); - MPL_ASSERT_NOT(( has_xxx1< int (*)(), int > )); - MPL_ASSERT_NOT(( has_xxx2< int (*)(), int, int > )); - MPL_ASSERT_NOT(( has_yyy0< int (*)() > )); - MPL_ASSERT_NOT(( has_yyy1< int (*)(), int > )); - MPL_ASSERT_NOT(( has_yyy2< int (*)(), int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< a2 > )); - MPL_ASSERT_NOT(( has_xxx1< a2, int > )); - MPL_ASSERT_NOT(( has_xxx2< a2, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< a2 > )); - MPL_ASSERT_NOT(( has_yyy1< a2, int > )); - MPL_ASSERT_NOT(( has_yyy2< a2, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< a3 > )); - MPL_ASSERT_NOT(( has_xxx1< a3, int > )); - MPL_ASSERT_NOT(( has_xxx2< a3, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< a3 > )); - MPL_ASSERT_NOT(( has_yyy1< a3, int > )); - MPL_ASSERT_NOT(( has_yyy2< a3, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< a4 > )); - MPL_ASSERT_NOT(( has_xxx1< a4, int > )); - MPL_ASSERT_NOT(( has_xxx2< a4, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< a4 > )); - MPL_ASSERT_NOT(( has_yyy1< a4, int > )); - MPL_ASSERT_NOT(( has_yyy2< a4, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) MPL_ASSERT_NOT(( has_xxx )); + MPL_ASSERT(( has_xxx_template )); #endif MPL_ASSERT_NOT(( has_xxx< enum_ > )); - MPL_ASSERT_NOT(( has_xxx0< enum_ > )); - MPL_ASSERT_NOT(( has_xxx1< enum_, int > )); - MPL_ASSERT_NOT(( has_xxx2< enum_, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< enum_ > )); - MPL_ASSERT_NOT(( has_yyy1< enum_, int > )); - MPL_ASSERT_NOT(( has_yyy2< enum_, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< enum_ > )); #endif MPL_ASSERT_NOT(( has_xxx )); - MPL_ASSERT_NOT(( has_xxx0< a1 > )); - MPL_ASSERT_NOT(( has_xxx1< a1, int > )); - MPL_ASSERT_NOT(( has_xxx2< a1, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< a1 > )); - MPL_ASSERT_NOT(( has_yyy1< a1, int > )); - MPL_ASSERT_NOT(( has_yyy2< a1, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); MPL_ASSERT_NOT(( has_xxx< outer< inner > > )); - MPL_ASSERT_NOT(( has_xxx0< outer< inner > > )); - MPL_ASSERT_NOT(( has_xxx1< outer< inner >, int > )); - MPL_ASSERT_NOT(( has_xxx2< outer< inner >, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< outer< inner > > )); - MPL_ASSERT_NOT(( has_yyy1< outer< inner >, int > )); - MPL_ASSERT_NOT(( has_yyy2< outer< inner >, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< outer< inner > > )); MPL_ASSERT_NOT(( has_xxx< incomplete > )); - MPL_ASSERT_NOT(( has_xxx0< incomplete > )); - MPL_ASSERT_NOT(( has_xxx1< incomplete, int > )); - MPL_ASSERT_NOT(( has_xxx2< incomplete, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< incomplete > )); - MPL_ASSERT_NOT(( has_yyy1< incomplete, int > )); - MPL_ASSERT_NOT(( has_yyy2< incomplete, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< incomplete > )); MPL_ASSERT_NOT(( has_xxx< abstract > )); - MPL_ASSERT_NOT(( has_xxx0< abstract > )); - MPL_ASSERT_NOT(( has_xxx1< abstract, int > )); - MPL_ASSERT_NOT(( has_xxx2< abstract, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< abstract > )); - MPL_ASSERT_NOT(( has_yyy1< abstract, int > )); - MPL_ASSERT_NOT(( has_yyy2< abstract, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< abstract > )); MPL_ASSERT_NOT(( has_xxx< noncopyable > )); - MPL_ASSERT_NOT(( has_xxx0< noncopyable > )); - MPL_ASSERT_NOT(( has_xxx1< noncopyable, int > )); - MPL_ASSERT_NOT(( has_xxx2< noncopyable, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< noncopyable > )); - MPL_ASSERT_NOT(( has_yyy1< noncopyable, int > )); - MPL_ASSERT_NOT(( has_yyy2< noncopyable, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template< noncopyable > )); #if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) - MPL_ASSERT_NOT(( has_xxx0< b1 > )); - MPL_ASSERT_NOT(( has_xxx1< b1, int > )); - MPL_ASSERT_NOT(( has_xxx2< b1, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b1 > )); - MPL_ASSERT_NOT(( has_yyy1< b1, int > )); - MPL_ASSERT_NOT(( has_yyy2< b1, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b2 > )); - MPL_ASSERT_NOT(( has_xxx1< b2, int > )); - MPL_ASSERT_NOT(( has_xxx2< b2, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b2 > )); - MPL_ASSERT_NOT(( has_yyy1< b2, int > )); - MPL_ASSERT_NOT(( has_yyy2< b2, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b3 > )); - MPL_ASSERT_NOT(( has_xxx1< b3, int > )); - MPL_ASSERT_NOT(( has_xxx2< b3, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b3 > )); - MPL_ASSERT_NOT(( has_yyy1< b3, int > )); - MPL_ASSERT_NOT(( has_yyy2< b3, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b4 > )); - MPL_ASSERT_NOT(( has_xxx1< b4, int > )); - MPL_ASSERT_NOT(( has_xxx2< b4, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b4 > )); - MPL_ASSERT_NOT(( has_yyy1< b4, int > )); - MPL_ASSERT_NOT(( has_yyy2< b4, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b5 > )); - MPL_ASSERT_NOT(( has_xxx1< b5, int > )); - MPL_ASSERT_NOT(( has_xxx2< b5, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b5 > )); - MPL_ASSERT_NOT(( has_yyy1< b5, int > )); - MPL_ASSERT_NOT(( has_yyy2< b5, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b6 > )); - MPL_ASSERT_NOT(( has_xxx1< b6, int > )); - MPL_ASSERT_NOT(( has_xxx2< b6, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b6 > )); - MPL_ASSERT_NOT(( has_yyy1< b6, int > )); - MPL_ASSERT_NOT(( has_yyy2< b6, int, int > )); - - MPL_ASSERT_NOT(( has_xxx0< b7 > )); - MPL_ASSERT_NOT(( has_xxx1< b7, int > )); - MPL_ASSERT_NOT(( has_xxx2< b7, int, int > )); - MPL_ASSERT_NOT(( has_yyy0< b7 > )); - MPL_ASSERT_NOT(( has_yyy1< b7, int > )); - MPL_ASSERT_NOT(( has_yyy2< b7, int, int > )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); #endif // Same name, different args. - // Note: has_xxx0 is not test here because it's impossible to - // declare a template with no arguments (only no required - // arguments), so there is no zero argument substitute template - // to reject n-ary member templates. -#if (!BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303) \ - && !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308))) - MPL_ASSERT_NOT(( has_xxx1 )); - MPL_ASSERT_NOT(( has_xxx2 )); - MPL_ASSERT_NOT(( has_xxx2 )); -#endif - - // Different name, same args. - MPL_ASSERT_NOT(( has_xxx0 )); - MPL_ASSERT_NOT(( has_xxx1 )); - MPL_ASSERT_NOT(( has_xxx2 )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_xxx_template )); + MPL_ASSERT(( has_yyy )); + MPL_ASSERT(( has_yyy )); // Different name, different args. - MPL_ASSERT_NOT(( has_xxx0 )); - MPL_ASSERT_NOT(( has_xxx1 )); - MPL_ASSERT_NOT(( has_xxx2 )); - MPL_ASSERT_NOT(( has_xxx2 )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_xxx_template )); + MPL_ASSERT_NOT(( has_yyy )); + MPL_ASSERT_NOT(( has_yyy )); + MPL_ASSERT_NOT(( has_yyy )); + MPL_ASSERT_NOT(( has_yyy )); + MPL_ASSERT_NOT(( has_yyy )); MPL_ASSERT(( has_xxx )); MPL_ASSERT(( has_xxx )); @@ -254,14 +136,7 @@ MPL_TEST_CASE() MPL_ASSERT(( has_xxx )); MPL_ASSERT(( has_xxx )); -#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, >= 1500) - MPL_ASSERT(( has_xxx0 )); - MPL_ASSERT(( has_yyy0 )); -#endif - MPL_ASSERT(( has_xxx1 )); - MPL_ASSERT(( has_xxx2 )); - MPL_ASSERT(( has_yyy1 )); - MPL_ASSERT(( has_yyy2 )); + MPL_ASSERT(( has_xxx_template )); #if !defined(HAS_XXX_ASSERT) # define HAS_XXX_ASSERT(x) MPL_ASSERT(x) @@ -279,12 +154,5 @@ MPL_TEST_CASE() # define HAS_XXX_TEMPLATE_ASSERT(x) MPL_ASSERT(x) #endif -#if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, >= 1500) - HAS_XXX_TEMPLATE_ASSERT(( has_xxx0 )); - HAS_XXX_TEMPLATE_ASSERT(( has_yyy0 )); -#endif - HAS_XXX_TEMPLATE_ASSERT(( has_xxx1 )); - HAS_XXX_TEMPLATE_ASSERT(( has_xxx2 )); - HAS_XXX_TEMPLATE_ASSERT(( has_yyy1 )); - HAS_XXX_TEMPLATE_ASSERT(( has_yyy2 )); + HAS_XXX_TEMPLATE_ASSERT(( has_xxx_template )); } From 45d0bcadc2511bf27b7b2246515e5a129bb24eee Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Sun, 18 Jul 2010 23:59:27 +0000 Subject: [PATCH 14/26] fixed missing header dependency [SVN r64144] --- include/boost/mpl/has_xxx.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/mpl/has_xxx.hpp b/include/boost/mpl/has_xxx.hpp index 4ef0196..379bd0c 100644 --- a/include/boost/mpl/has_xxx.hpp +++ b/include/boost/mpl/has_xxx.hpp @@ -17,6 +17,7 @@ // $Revision$ #include +#include #include #include #include From 6f63e9d0c6110bf36e4a9385043a93ecd281a826 Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Mon, 9 Aug 2010 20:07:24 +0000 Subject: [PATCH 15/26] Update generated html docs for MPL. [SVN r64705] --- doc/refmanual.html | 22 +- doc/refmanual/accumulate.html | 4 +- doc/refmanual/acknowledgements.html | 4 +- doc/refmanual/advance.html | 8 +- doc/refmanual/algorithms-concepts.html | 8 +- doc/refmanual/algorithms.html | 16 +- doc/refmanual/always.html | 4 +- doc/refmanual/and.html | 4 +- doc/refmanual/apply-wrap.html | 4 +- doc/refmanual/apply.html | 4 +- doc/refmanual/arg.html | 4 +- doc/refmanual/arithmetic-operations.html | 16 +- doc/refmanual/assert-msg.html | 4 +- doc/refmanual/assert-not.html | 4 +- doc/refmanual/assert-relation.html | 4 +- doc/refmanual/assert.html | 4 +- doc/refmanual/asserts.html | 12 +- doc/refmanual/associative-sequence.html | 4 +- doc/refmanual/at-c.html | 4 +- doc/refmanual/at.html | 4 +- doc/refmanual/aux-lambda-support.html | 18 +- doc/refmanual/back-extensible-sequence.html | 4 +- doc/refmanual/back-inserter.html | 4 +- doc/refmanual/back.html | 4 +- doc/refmanual/begin.html | 4 +- doc/refmanual/bidirectional-iterator.html | 4 +- doc/refmanual/bidirectional-sequence.html | 4 +- doc/refmanual/bind.html | 4 +- doc/refmanual/bitand.html | 4 +- doc/refmanual/bitor.html | 4 +- doc/refmanual/bitwise-operations.html | 14 +- doc/refmanual/bitxor.html | 4 +- doc/refmanual/bool.html | 4 +- .../broken-compiler-workarounds.html | 6 +- doc/refmanual/c-str.html | 4 +- doc/refmanual/categorized-index-concepts.html | 6 +- doc/refmanual/categorized-index.html | 8 +- doc/refmanual/cfg-no-has-xxx-template.html | 39 ++ doc/refmanual/cfg-no-has-xxx.html | 20 +- .../cfg-no-preprocessed-headers.html | 10 +- doc/refmanual/char.html | 4 +- doc/refmanual/classes.html | 24 +- doc/refmanual/clear.html | 4 +- doc/refmanual/comparisons.html | 16 +- doc/refmanual/components.html | 7 +- .../composition-and-argument-binding.html | 16 +- doc/refmanual/concepts.html | 24 +- doc/refmanual/configuration.html | 23 +- doc/refmanual/contains.html | 4 +- doc/refmanual/copy-if.html | 4 +- doc/refmanual/copy.html | 4 +- doc/refmanual/count-if.html | 4 +- doc/refmanual/count.html | 4 +- doc/refmanual/data-types-concepts.html | 6 +- doc/refmanual/data-types-miscellaneous.html | 10 +- doc/refmanual/data-types.html | 10 +- doc/refmanual/deque.html | 6 +- doc/refmanual/deref.html | 4 +- doc/refmanual/distance.html | 4 +- doc/refmanual/divides.html | 4 +- doc/refmanual/empty-base.html | 4 +- doc/refmanual/empty-sequence.html | 4 +- doc/refmanual/empty.html | 4 +- doc/refmanual/end.html | 4 +- doc/refmanual/equal-to.html | 4 +- doc/refmanual/equal.html | 4 +- doc/refmanual/erase-key.html | 4 +- doc/refmanual/erase.html | 4 +- doc/refmanual/eval-if-c.html | 4 +- doc/refmanual/eval-if.html | 4 +- .../extensible-associative-sequence.html | 4 +- doc/refmanual/extensible-sequence.html | 4 +- doc/refmanual/filter-view.html | 4 +- doc/refmanual/find-if.html | 4 +- doc/refmanual/find.html | 4 +- doc/refmanual/fold.html | 4 +- doc/refmanual/for-each.html | 4 +- doc/refmanual/forward-iterator.html | 4 +- doc/refmanual/forward-sequence.html | 4 +- doc/refmanual/front-extensible-sequence.html | 4 +- doc/refmanual/front-inserter.html | 4 +- doc/refmanual/front.html | 4 +- doc/refmanual/greater-equal.html | 4 +- doc/refmanual/greater.html | 4 +- doc/refmanual/has-key.html | 4 +- doc/refmanual/has-xxx-template-def.html | 139 ++++++ doc/refmanual/has-xxx-template-named-def.html | 192 ++++++++ doc/refmanual/has-xxx-trait-def.html | 22 +- doc/refmanual/has-xxx-trait-named-def.html | 18 +- doc/refmanual/identity.html | 6 +- doc/refmanual/if-c.html | 4 +- doc/refmanual/if.html | 4 +- doc/refmanual/inherit-linearly.html | 4 +- doc/refmanual/inherit.html | 4 +- doc/refmanual/insert-range.html | 4 +- doc/refmanual/insert.html | 4 +- doc/refmanual/inserter-class.html | 4 +- doc/refmanual/inserter.html | 6 +- doc/refmanual/inserters.html | 10 +- doc/refmanual/int.html | 4 +- doc/refmanual/integral-c.html | 4 +- doc/refmanual/integral-constant.html | 4 +- doc/refmanual/integral-sequence-wrapper.html | 4 +- doc/refmanual/intrinsic-metafunctions.html | 54 +-- doc/refmanual/introspection.html | 20 +- doc/refmanual/invocation.html | 10 +- doc/refmanual/is-sequence.html | 4 +- doc/refmanual/iter-fold.html | 4 +- doc/refmanual/iteration-algorithms.html | 14 +- doc/refmanual/iterator-category.html | 4 +- doc/refmanual/iterator-metafunctions.html | 16 +- doc/refmanual/iterator-range.html | 4 +- doc/refmanual/iterators-concepts.html | 10 +- doc/refmanual/iterators.html | 8 +- doc/refmanual/joint-view.html | 4 +- doc/refmanual/key-type.html | 10 +- doc/refmanual/lambda-expression.html | 4 +- doc/refmanual/lambda.html | 4 +- doc/refmanual/less-equal.html | 4 +- doc/refmanual/less.html | 4 +- doc/refmanual/limit-list-size.html | 16 +- doc/refmanual/limit-map-size.html | 14 +- doc/refmanual/limit-metafunction-arity.html | 18 +- doc/refmanual/limit-set-size.html | 16 +- doc/refmanual/limit-string-size.html | 14 +- doc/refmanual/limit-unrolling.html | 14 +- doc/refmanual/limit-vector-size.html | 16 +- doc/refmanual/list-c.html | 4 +- doc/refmanual/list.html | 6 +- doc/refmanual/logical-operations.html | 10 +- doc/refmanual/long.html | 4 +- doc/refmanual/lower-bound.html | 4 +- doc/refmanual/macros.html | 12 +- doc/refmanual/map.html | 6 +- doc/refmanual/max-element.html | 4 +- doc/refmanual/max.html | 6 +- doc/refmanual/metafunction-class.html | 4 +- doc/refmanual/metafunction.html | 4 +- doc/refmanual/metafunctions-concepts.html | 18 +- doc/refmanual/metafunctions.html | 32 +- doc/refmanual/min-element.html | 4 +- doc/refmanual/min.html | 6 +- doc/refmanual/minus.html | 4 +- doc/refmanual/miscellaneous.html | 20 +- doc/refmanual/modulus.html | 4 +- doc/refmanual/negate.html | 4 +- doc/refmanual/next.html | 4 +- doc/refmanual/not-equal-to.html | 4 +- doc/refmanual/not.html | 4 +- doc/refmanual/numeric-cast.html | 4 +- doc/refmanual/numeric-metafunction.html | 4 +- doc/refmanual/numeric.html | 16 +- doc/refmanual/or.html | 4 +- doc/refmanual/order.html | 4 +- doc/refmanual/pair.html | 4 +- doc/refmanual/partition.html | 4 +- doc/refmanual/placeholder-expression.html | 4 +- doc/refmanual/placeholders.html | 4 +- doc/refmanual/plus.html | 4 +- doc/refmanual/pop-back.html | 4 +- doc/refmanual/pop-front.html | 4 +- doc/refmanual/prior.html | 4 +- doc/refmanual/protect.html | 19 +- doc/refmanual/push-back.html | 4 +- doc/refmanual/push-front.html | 4 +- doc/refmanual/querying-algorithms.html | 24 +- doc/refmanual/quote.html | 4 +- doc/refmanual/random-access-iterator.html | 4 +- doc/refmanual/random-access-sequence.html | 4 +- doc/refmanual/range-c.html | 4 +- doc/refmanual/refmanual_toc.html | 443 +++++++++--------- doc/refmanual/remove-if.html | 4 +- doc/refmanual/remove.html | 4 +- doc/refmanual/replace-if.html | 4 +- doc/refmanual/replace.html | 4 +- doc/refmanual/reverse-copy-if.html | 4 +- doc/refmanual/reverse-copy.html | 4 +- doc/refmanual/reverse-fold.html | 4 +- doc/refmanual/reverse-iter-fold.html | 4 +- doc/refmanual/reverse-partition.html | 4 +- doc/refmanual/reverse-remove-if.html | 4 +- doc/refmanual/reverse-remove.html | 4 +- doc/refmanual/reverse-replace-if.html | 4 +- doc/refmanual/reverse-replace.html | 4 +- doc/refmanual/reverse-stable-partition.html | 4 +- doc/refmanual/reverse-transform.html | 4 +- doc/refmanual/reverse-unique.html | 4 +- doc/refmanual/reverse.html | 4 +- doc/refmanual/reversible-algorithm.html | 4 +- doc/refmanual/runtime-algorithms.html | 6 +- doc/refmanual/sequence-tag.html | 6 +- doc/refmanual/sequences.html | 12 +- doc/refmanual/set-c.html | 4 +- doc/refmanual/set.html | 6 +- doc/refmanual/shift-left.html | 4 +- doc/refmanual/shift-right.html | 4 +- doc/refmanual/single-view.html | 4 +- doc/refmanual/size-t.html | 4 +- doc/refmanual/size.html | 4 +- doc/refmanual/sizeof.html | 4 +- doc/refmanual/sort.html | 4 +- doc/refmanual/stable-partition.html | 4 +- doc/refmanual/string-operations.html | 6 +- doc/refmanual/string.html | 6 +- .../tag-dispatched-metafunction.html | 6 +- doc/refmanual/terminology.html | 4 +- doc/refmanual/times.html | 4 +- doc/refmanual/transform-view.html | 4 +- doc/refmanual/transform.html | 4 +- doc/refmanual/transformation-algorithms.html | 48 +- doc/refmanual/trivial-metafunction.html | 6 +- .../trivial-metafunctions-summary.html | 4 +- doc/refmanual/trivial.html | 6 +- doc/refmanual/type-selection.html | 12 +- doc/refmanual/unique.html | 4 +- doc/refmanual/unpack-args.html | 4 +- doc/refmanual/upper-bound.html | 4 +- doc/refmanual/value-type.html | 10 +- doc/refmanual/variadic-sequence.html | 4 +- doc/refmanual/vector-c.html | 4 +- doc/refmanual/vector.html | 6 +- doc/refmanual/views.html | 18 +- doc/refmanual/void.html | 4 +- doc/refmanual/zip-view.html | 4 +- 224 files changed, 1374 insertions(+), 990 deletions(-) create mode 100644 doc/refmanual/cfg-no-has-xxx-template.html create mode 100644 doc/refmanual/has-xxx-template-def.html create mode 100644 doc/refmanual/has-xxx-template-named-def.html diff --git a/doc/refmanual.html b/doc/refmanual.html index 4c36069..ec6e2d5 100644 --- a/doc/refmanual.html +++ b/doc/refmanual.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual @@ -25,15 +25,15 @@ accompanying file LICENSE_1_0.txt @@ -42,7 +42,7 @@ accompanying file LICENSE_1_0.txt diff --git a/doc/refmanual/accumulate.html b/doc/refmanual/accumulate.html index f1667c1..74ce992 100644 --- a/doc/refmanual/accumulate.html +++ b/doc/refmanual/accumulate.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: accumulate @@ -12,7 +12,7 @@ Front Page / Algorithms / Iteration Algorithms / accumulate
-

accumulate

+

accumulate

Synopsis

diff --git a/doc/refmanual/acknowledgements.html b/doc/refmanual/acknowledgements.html
index 81b7bfd..e4eff30 100644
--- a/doc/refmanual/acknowledgements.html
+++ b/doc/refmanual/acknowledgements.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: Acknowledgements
 
 
@@ -12,7 +12,7 @@
 Front Page / Acknowledgements
 
-

Acknowledgements

+

Acknowledgements

The format and language of this reference documentation has been greatly influenced by the SGI's Standard Template Library Programmer's Guide.

diff --git a/doc/refmanual/advance.html b/doc/refmanual/advance.html index e99f57f..01accf4 100644 --- a/doc/refmanual/advance.html +++ b/doc/refmanual/advance.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: advance @@ -12,7 +12,7 @@ Front Page / Iterators / Iterator Metafunctions / advance
-

advance

+

advance

Synopsis

@@ -28,8 +28,8 @@ struct advance
 

Description

-

Moves Iterator by the distance N. For bidirectional and -random access iterators, the distance may be negative.

+

Moves Iterator by the distance N. For bidirectional and +random access iterators, the distance may be negative.

Header

diff --git a/doc/refmanual/algorithms-concepts.html b/doc/refmanual/algorithms-concepts.html index 041e697..021249b 100644 --- a/doc/refmanual/algorithms-concepts.html +++ b/doc/refmanual/algorithms-concepts.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: Concepts @@ -12,11 +12,11 @@ Front Page / Algorithms / Concepts
diff --git a/doc/refmanual/algorithms.html b/doc/refmanual/algorithms.html index df6834a..acc3fe5 100644 --- a/doc/refmanual/algorithms.html +++ b/doc/refmanual/algorithms.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: Algorithms @@ -12,7 +12,7 @@ Front Page / Algorithms
-

Algorithms

+

Algorithms

The MPL provides a broad range of fundamental algorithms aimed to satisfy the majority of sequential compile-time data processing needs. The algorithms include compile-time counterparts @@ -44,12 +44,12 @@ allowing for a wider range of efficient transformations — a common functionality documented by the Reversible Algorithm concept.

diff --git a/doc/refmanual/always.html b/doc/refmanual/always.html index 1cd8123..00273ce 100644 --- a/doc/refmanual/always.html +++ b/doc/refmanual/always.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: always @@ -12,7 +12,7 @@ Front Page / Metafunctions / Miscellaneous / always
-

always

+

always

Synopsis

diff --git a/doc/refmanual/and.html b/doc/refmanual/and.html
index 16536de..91e9650 100644
--- a/doc/refmanual/and.html
+++ b/doc/refmanual/and.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: and_
 
 
@@ -12,7 +12,7 @@
 Front Page / Metafunctions / Logical Operations / and_
 
-

and_

+

and_

Synopsis

diff --git a/doc/refmanual/apply-wrap.html b/doc/refmanual/apply-wrap.html
index d4d11a6..c455eb6 100644
--- a/doc/refmanual/apply-wrap.html
+++ b/doc/refmanual/apply-wrap.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: apply_wrap
 
 
@@ -12,7 +12,7 @@
 Front Page / Metafunctions / Invocation / apply_wrap
 
-

apply_wrap

+

apply_wrap

Synopsis

diff --git a/doc/refmanual/apply.html b/doc/refmanual/apply.html
index 7f03f73..4a286d0 100644
--- a/doc/refmanual/apply.html
+++ b/doc/refmanual/apply.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: apply
 
 
@@ -12,7 +12,7 @@
 Front Page / Metafunctions / Invocation / apply
 
-

apply

+

apply

Synopsis

diff --git a/doc/refmanual/arg.html b/doc/refmanual/arg.html
index f4ff6f4..3be78e9 100644
--- a/doc/refmanual/arg.html
+++ b/doc/refmanual/arg.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: arg
 
 
@@ -12,7 +12,7 @@
 Front Page / Metafunctions / Composition and Argument Binding / arg
 
-

arg

+

arg

Synopsis

diff --git a/doc/refmanual/arithmetic-operations.html b/doc/refmanual/arithmetic-operations.html
index d8f3d82..2736b8c 100644
--- a/doc/refmanual/arithmetic-operations.html
+++ b/doc/refmanual/arithmetic-operations.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: Arithmetic Operations
 
 
@@ -12,15 +12,15 @@
 Front Page / Metafunctions / Arithmetic Operations
 
diff --git a/doc/refmanual/assert-msg.html b/doc/refmanual/assert-msg.html index 2e7f8fa..6bd702d 100644 --- a/doc/refmanual/assert-msg.html +++ b/doc/refmanual/assert-msg.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: BOOST_MPL_ASSERT_MSG @@ -12,7 +12,7 @@ Front Page / Macros / Asserts / BOOST_MPL_ASSERT_MSG
-

BOOST_MPL_ASSERT_MSG

+

BOOST_MPL_ASSERT_MSG

Synopsis

diff --git a/doc/refmanual/assert-not.html b/doc/refmanual/assert-not.html
index ca1b005..5aebcd7 100644
--- a/doc/refmanual/assert-not.html
+++ b/doc/refmanual/assert-not.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: BOOST_MPL_ASSERT_NOT
 
 
@@ -12,7 +12,7 @@
 Front Page / Macros / Asserts / BOOST_MPL_ASSERT_NOT
 
-

BOOST_MPL_ASSERT_NOT

+

BOOST_MPL_ASSERT_NOT

Synopsis

diff --git a/doc/refmanual/assert-relation.html b/doc/refmanual/assert-relation.html
index e948c03..4597172 100644
--- a/doc/refmanual/assert-relation.html
+++ b/doc/refmanual/assert-relation.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: BOOST_MPL_ASSERT_RELATION
 
 
@@ -12,7 +12,7 @@
 Front Page / Macros / Asserts / BOOST_MPL_ASSERT_RELATION
 
-

BOOST_MPL_ASSERT_RELATION

+

BOOST_MPL_ASSERT_RELATION

Synopsis

diff --git a/doc/refmanual/assert.html b/doc/refmanual/assert.html
index 7992b52..a33319e 100644
--- a/doc/refmanual/assert.html
+++ b/doc/refmanual/assert.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: BOOST_MPL_ASSERT
 
 
@@ -12,7 +12,7 @@
 Front Page / Macros / Asserts / BOOST_MPL_ASSERT
 
-

BOOST_MPL_ASSERT

+

BOOST_MPL_ASSERT

Synopsis

diff --git a/doc/refmanual/asserts.html b/doc/refmanual/asserts.html
index ac4e869..3430de2 100644
--- a/doc/refmanual/asserts.html
+++ b/doc/refmanual/asserts.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: Asserts
 
 
@@ -12,17 +12,17 @@
 Front Page / Macros / Asserts
 
-

Asserts

+

Asserts

The MPL supplies a suite of static assertion macros that are specifically designed to generate maximally useful and informative error messages within the diagnostic capabilities of each compiler.

All assert macros can be used at class, function, or namespace scope.

diff --git a/doc/refmanual/associative-sequence.html b/doc/refmanual/associative-sequence.html index 84812bf..4478043 100644 --- a/doc/refmanual/associative-sequence.html +++ b/doc/refmanual/associative-sequence.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: Associative Sequence @@ -12,7 +12,7 @@ Front Page / Sequences / Concepts / Associative Sequence
-

Associative Sequence

+

Associative Sequence

Description

An Associative Sequence is a Forward Sequence that allows efficient retrieval of diff --git a/doc/refmanual/at-c.html b/doc/refmanual/at-c.html index fd7f73d..53a9589 100644 --- a/doc/refmanual/at-c.html +++ b/doc/refmanual/at-c.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: at_c @@ -12,7 +12,7 @@ Front Page / Sequences / Intrinsic Metafunctions / at_c

-

at_c

+

at_c

Synopsis

diff --git a/doc/refmanual/at.html b/doc/refmanual/at.html
index b342706..48dbc4a 100644
--- a/doc/refmanual/at.html
+++ b/doc/refmanual/at.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: at
 
 
@@ -12,7 +12,7 @@
 Front Page / Sequences / Intrinsic Metafunctions / at
 
-

at

+

at

Synopsis

diff --git a/doc/refmanual/aux-lambda-support.html b/doc/refmanual/aux-lambda-support.html
index 8f72f85..e74dd03 100644
--- a/doc/refmanual/aux-lambda-support.html
+++ b/doc/refmanual/aux-lambda-support.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: BOOST_MPL_AUX_LAMBDA_SUPPORT
 
 
@@ -12,8 +12,8 @@
 Front Page / Macros / Broken Compiler Workarounds / BOOST_MPL_AUX_LAMBDA_SUPPORT
 
-

BOOST_MPL_AUX_LAMBDA_SUPPORT

-
+

BOOST_MPL_AUX_LAMBDA_SUPPORT

+

Synopsis

 #define BOOST_MPL_AUX_LAMBDA_SUPPORT(arity, fun, params) \
@@ -21,19 +21,19 @@
 /**/
 
-
+

Description

Enables metafunction fun for the use in Lambda Expressions on compilers that don't support partial template specialization or/and template template parameters. Expands to nothing on conforming compilers.

-
+ -
+

Parameters

@@ -65,7 +65,7 @@ their original order, including the defaults.
-
+

Expression semantics

For any integral constant n, a Metafunction fun, and arbitrary types A1,... An:

@@ -93,7 +93,7 @@ expands to an unspecified token sequence enabling 
 
 
-
+

Example

 template< typename T, typename U = int > struct f
@@ -107,7 +107,7 @@ typedef apply<
 BOOST_MPL_ASSERT(( is_same< r, char[sizeof(long)] > ));
 
-
+ diff --git a/doc/refmanual/back-extensible-sequence.html b/doc/refmanual/back-extensible-sequence.html index 1cbbb29..a8302b6 100644 --- a/doc/refmanual/back-extensible-sequence.html +++ b/doc/refmanual/back-extensible-sequence.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: Back Extensible Sequence @@ -12,7 +12,7 @@ Front Page / Sequences / Concepts / Back Extensible Sequence
-

Back Extensible Sequence

+

Back Extensible Sequence

Description

A Back Extensible Sequence is an Extensible Sequence that supports amortized constant diff --git a/doc/refmanual/back-inserter.html b/doc/refmanual/back-inserter.html index 150a4f8..da825c1 100644 --- a/doc/refmanual/back-inserter.html +++ b/doc/refmanual/back-inserter.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: back_inserter @@ -12,7 +12,7 @@ Front Page / Algorithms / Inserters / back_inserter

-

back_inserter

+

back_inserter

Synopsis

diff --git a/doc/refmanual/back.html b/doc/refmanual/back.html
index f5146b1..4f67bdf 100644
--- a/doc/refmanual/back.html
+++ b/doc/refmanual/back.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: back
 
 
@@ -12,7 +12,7 @@
 Front Page / Sequences / Intrinsic Metafunctions / back
 
-

back

+

back

Synopsis

diff --git a/doc/refmanual/begin.html b/doc/refmanual/begin.html
index c42c277..9753362 100644
--- a/doc/refmanual/begin.html
+++ b/doc/refmanual/begin.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: begin
 
 
@@ -12,7 +12,7 @@
 Front Page / Sequences / Intrinsic Metafunctions / begin
 
-

begin

+

begin

Synopsis

diff --git a/doc/refmanual/bidirectional-iterator.html b/doc/refmanual/bidirectional-iterator.html
index 1df9bde..e144a55 100644
--- a/doc/refmanual/bidirectional-iterator.html
+++ b/doc/refmanual/bidirectional-iterator.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: Bidirectional Iterator
 
 
@@ -12,7 +12,7 @@
 Front Page / Iterators / Concepts / Bidirectional Iterator
 
-

Bidirectional Iterator

+

Bidirectional Iterator

Description

A Bidirectional Iterator is a Forward Iterator that provides a way to diff --git a/doc/refmanual/bidirectional-sequence.html b/doc/refmanual/bidirectional-sequence.html index 57e7bbb..522799f 100644 --- a/doc/refmanual/bidirectional-sequence.html +++ b/doc/refmanual/bidirectional-sequence.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: Bidirectional Sequence @@ -12,7 +12,7 @@ Front Page / Sequences / Concepts / Bidirectional Sequence

-

Bidirectional Sequence

+

Bidirectional Sequence

Description

A Bidirectional Sequence is a Forward Sequence whose iterators model diff --git a/doc/refmanual/bind.html b/doc/refmanual/bind.html index 0c0f9bf..34ceb92 100644 --- a/doc/refmanual/bind.html +++ b/doc/refmanual/bind.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: bind @@ -12,7 +12,7 @@ Front Page / Metafunctions / Composition and Argument Binding / bind

-

bind

+

bind

Synopsis

diff --git a/doc/refmanual/bitand.html b/doc/refmanual/bitand.html
index 6422c6e..3436830 100644
--- a/doc/refmanual/bitand.html
+++ b/doc/refmanual/bitand.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: bitand_
 
 
@@ -12,7 +12,7 @@
 Front Page / Metafunctions / Bitwise Operations / bitand_
 
-

bitand_

+

bitand_

Synopsis

diff --git a/doc/refmanual/bitor.html b/doc/refmanual/bitor.html
index 44388a1..8202356 100644
--- a/doc/refmanual/bitor.html
+++ b/doc/refmanual/bitor.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: bitor_
 
 
@@ -12,7 +12,7 @@
 Front Page / Metafunctions / Bitwise Operations / bitor_
 
-

bitor_

+

bitor_

Synopsis

diff --git a/doc/refmanual/bitwise-operations.html b/doc/refmanual/bitwise-operations.html
index 0bf1fc7..1f2962f 100644
--- a/doc/refmanual/bitwise-operations.html
+++ b/doc/refmanual/bitwise-operations.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: Bitwise Operations
 
 
@@ -12,14 +12,14 @@
 Front Page / Metafunctions / Bitwise Operations
 
diff --git a/doc/refmanual/bitxor.html b/doc/refmanual/bitxor.html index 84b1a5e..9a05d74 100644 --- a/doc/refmanual/bitxor.html +++ b/doc/refmanual/bitxor.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: bitxor_ @@ -12,7 +12,7 @@ Front Page / Metafunctions / Bitwise Operations / bitxor_
-

bitxor_

+

bitxor_

Synopsis

diff --git a/doc/refmanual/bool.html b/doc/refmanual/bool.html
index 86a41ae..b9f11c3 100644
--- a/doc/refmanual/bool.html
+++ b/doc/refmanual/bool.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: bool_
 
 
@@ -12,7 +12,7 @@
 Front Page / Data Types / Numeric / bool_
 
-

bool_

+

bool_

Synopsis

diff --git a/doc/refmanual/broken-compiler-workarounds.html b/doc/refmanual/broken-compiler-workarounds.html
index 26ccdc0..0b53e86 100644
--- a/doc/refmanual/broken-compiler-workarounds.html
+++ b/doc/refmanual/broken-compiler-workarounds.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: Broken Compiler Workarounds
 
 
@@ -12,10 +12,10 @@
 Front Page / Macros / Broken Compiler Workarounds
 
diff --git a/doc/refmanual/c-str.html b/doc/refmanual/c-str.html index 1bfba1e..3540773 100644 --- a/doc/refmanual/c-str.html +++ b/doc/refmanual/c-str.html @@ -3,7 +3,7 @@ - + The MPL Reference Manual: c_str @@ -12,7 +12,7 @@ Front Page / Metafunctions / String Operations / c_str
-

c_str

+

c_str

Synopsis

diff --git a/doc/refmanual/categorized-index-concepts.html b/doc/refmanual/categorized-index-concepts.html
index a7fc505..d70d362 100644
--- a/doc/refmanual/categorized-index-concepts.html
+++ b/doc/refmanual/categorized-index-concepts.html
@@ -3,7 +3,7 @@
 
 
 
-
+
 The MPL Reference Manual: Concepts
 
 
@@ -11,8 +11,8 @@
 
Front Page / Categorized Index / Concepts
-
-

Concepts

+
+

Concepts