summaryrefslogtreecommitdiff
path: root/boost/intrusive/detail/has_member_function_callable_with.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/intrusive/detail/has_member_function_callable_with.hpp')
-rw-r--r--boost/intrusive/detail/has_member_function_callable_with.hpp575
1 files changed, 267 insertions, 308 deletions
diff --git a/boost/intrusive/detail/has_member_function_callable_with.hpp b/boost/intrusive/detail/has_member_function_callable_with.hpp
index ca96f15a19..30bef56c2b 100644
--- a/boost/intrusive/detail/has_member_function_callable_with.hpp
+++ b/boost/intrusive/detail/has_member_function_callable_with.hpp
@@ -1,372 +1,331 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2011-2014. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2014-2014. 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/intrusive for documentation.
+// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-// sample.h
+#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP
-#if !defined(BOOST_PP_IS_ITERATING)
+//Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and
+//wrong SFINAE for GCC 4.2/4.3
+#if defined(__GNUC__) && !defined(__clang__) && ((__GNUC__*100 + __GNUC_MINOR__*10) >= 340) && ((__GNUC__*100 + __GNUC_MINOR__*10) <= 430)
+ #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
+#elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200 )
+ #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
+#endif
+#include <cstddef>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/detail/fwd_macros.hpp>
- #ifndef BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
- #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
+namespace boost_intrusive_hmfcw {
- #include <boost/intrusive/detail/preprocessor.hpp>
- #include <boost/intrusive/detail/mpl.hpp>
- #include <boost/move/utility_core.hpp>
+typedef char yes_type;
+struct no_type{ char dummy[2]; };
+#if defined(BOOST_NO_CXX11_DECLTYPE)
- //Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and
- //wrong SFINAE for GCC 4.2/4.3
- #if defined(__GNUC__) && !defined(__clang__) && ((__GNUC__*100 + __GNUC_MINOR__*10) >= 340) && ((__GNUC__*100 + __GNUC_MINOR__*10) <= 430)
- #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
- #elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200 )
- #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
- #endif
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- namespace boost_intrusive_has_member_function_callable_with {
+template<class T>
+struct make_dontcare
+{
+ typedef dont_care type;
+};
- struct dont_care
- {
- dont_care(...);
- };
+#endif
- template<class T>
- struct make_dontcare
- {
- typedef boost_intrusive_has_member_function_callable_with::dont_care type;
- };
+struct dont_care
+{
+ dont_care(...);
+};
- struct private_type
- {
- static private_type p;
- private_type const &operator,(int) const;
- };
+struct private_type
+{
+ static private_type p;
+ private_type const &operator,(int) const;
+};
- typedef char yes_type; // sizeof(yes_type) == 1
- struct no_type{ char dummy[2]; }; // sizeof(no_type) == 2
+template<typename T>
+no_type is_private_type(T const &);
+yes_type is_private_type(private_type const &);
- template<typename T>
- no_type is_private_type(T const &);
- yes_type is_private_type(private_type const &);
+#endif //#if defined(BOOST_NO_CXX11_DECLTYPE)
- } //boost_intrusive_has_member_function_callable_with
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_SINGLE_ITERATION
- #endif
+template<typename T> struct remove_cv { typedef T type; };
+template<typename T> struct remove_cv<const T> { typedef T type; };
+template<typename T> struct remove_cv<const volatile T> { typedef T type; };
+template<typename T> struct remove_cv<volatile T> { typedef T type; };
+
+#endif
+
+} //namespace boost_intrusive_hmfcw {
+
+#endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP
+
+#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
+ #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME before including this header!"
+#endif
+
+#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN
+ #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN before including this header!"
+#endif
- #endif //BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
+#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX
+ #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX before including this header!"
+#endif
-#else //!BOOST_PP_IS_ITERATING
+#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX < BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN
+ #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX value MUST be greater or equal than BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN!"
+#endif
- #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
- #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME not defined!"
- #endif
+#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX == 0
+ #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF
+#else
+ #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF ,
+#endif
- #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
- #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN not defined!"
- #endif
+#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG
+ #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG not defined!"
+#endif
- #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
+#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!"
- #endif
+#endif
+
+BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
+ //With decltype and variadic templaes, things are pretty easy
+ template<typename Fun, class ...Args>
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+ {
+ template<class U>
+ static decltype(boost::move_detail::declval<U>().
+ BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval<Args>()...)
+ , boost_intrusive_hmfcw::yes_type()) Test(U* f);
+ template<class U>
+ static boost_intrusive_hmfcw::no_type Test(...);
+ static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);
+ };
+
+#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE)
+
+ /////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////
+ //
+ // has_member_function_callable_with_impl_XXX
+ // declaration, special case and 0 arg specializaton
+ //
+ /////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////
- #if BOOST_PP_ITERATION_START() > BOOST_PP_ITERATION_FINISH()
- #error "BOOST_PP_ITERATION_START() must be <= BOOST_PP_ITERATION_FINISH()"
- #endif
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ /////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////
+ //
+ // has_member_function_callable_with_impl_XXX for 1 to N arguments
+ //
+ /////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////
+
+ //defined(BOOST_NO_CXX11_DECLTYPE) must be true
+ template<class Fun, class ...DontCares>
+ struct FunWrapTmpl : Fun
+ {
+ using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
+ boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(DontCares...) const;
+ };
- #if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START()
+ template<typename Fun, class ...Args>
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, Args...>
+ {
+ typedef FunWrapTmpl<typename boost_intrusive_hmfcw::make_dontcare<Args>::type...> FunWrap;
+
+ static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) ==
+ sizeof(boost_intrusive_hmfcw::is_private_type
+ ( (::boost::move_detail::declval< FunWrap<Fun> >().
+ BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval<Args>()...), 0) )
+ )
+ );
+ };
+ #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
+ //Preprocessor must be used to generate specializations instead of variadic templates
template <typename Type>
- class BOOST_PP_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+ class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
{
struct BaseMixin
{
void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME();
};
- struct Base : public ::boost::intrusive::detail::remove_cv<Type>::type, public BaseMixin { Base(); };
+ struct Base : public boost_intrusive_hmfcw::remove_cv<Type>::type, public BaseMixin {};
template <typename T, T t> class Helper{};
template <typename U>
- static boost_intrusive_has_member_function_callable_with::no_type deduce
+ static boost_intrusive_hmfcw::no_type deduce
(U*, Helper<void (BaseMixin::*)(), &U::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME>* = 0);
- static boost_intrusive_has_member_function_callable_with::yes_type deduce(...);
+ static boost_intrusive_hmfcw::yes_type deduce(...);
public:
- static const bool value =
- sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0)));
+ static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0));
};
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- template<typename Fun, bool HasFunc
- BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION_FINISH(), BOOST_INTRUSIVE_PP_TEMPLATE_PARAM_VOID_DEFAULT, _)>
- struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl);
- //!
-
- template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), class P)>
- struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
- <Fun, false BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), P)>
- {
- static const bool value = false;
- };
- //!
-
- #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- template<typename Fun, bool HasFunc, class ...Args>
- struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl);
-
- template<typename Fun, class ...Args>
- struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
- <Fun, false, Args...>
- {
- static const bool value = false;
- };
-
- #ifdef BOOST_NO_CXX11_DECLTYPE
-
- //Special case for 0 args
- template< class F
- , std::size_t N =
- sizeof((boost::move_detail::declval<F>().
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))>
- struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
- {
- boost_intrusive_has_member_function_callable_with::yes_type dummy;
- BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
- };
-
- //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not
- //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0.
- template<class F>
- struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<F, 0>
- {
- boost_intrusive_has_member_function_callable_with::no_type dummy;
- BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
- };
-
- #endif //#ifdef BOOST_NO_CXX11_DECLTYPE
-
- template<typename Fun>
- struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
- <Fun, true>
- {
- #ifndef BOOST_NO_CXX11_DECLTYPE
- template<class U, class V = decltype(boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()) >
- static boost_intrusive_has_member_function_callable_with::yes_type Test(U*);
- #else
- template<class U>
- static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
- <U> Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*);
- #endif
-
- template <class U>
- static boost_intrusive_has_member_function_callable_with::no_type Test(...);
-
- static const bool value = sizeof(Test< Fun >(0))
- == sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
- };
-
- template<typename Fun, class ...Args>
- struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
- <Fun, true , Args...>
- {
-
- template<class ...DontCares>
- struct FunWrapTmpl : Fun
- {
- FunWrapTmpl();
- using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
-
- boost_intrusive_has_member_function_callable_with::private_type
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
- ( DontCares...) const;
- };
-
- typedef FunWrapTmpl<typename boost_intrusive_has_member_function_callable_with::make_dontcare<Args>::type...> FunWrap;
-
- static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) ==
- sizeof(boost_intrusive_has_member_function_callable_with::is_private_type
- ( (::boost::move_detail::declval< FunWrap >().
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
- ( ::boost::move_detail::declval<Args>()... ), 0) )
- )
- );
- };
+ /////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////
+ //
+ // has_member_function_callable_with_impl_XXX specializations
+ //
+ /////////////////////////////////////////////////////////
- template<typename Fun, class ...Args>
- struct BOOST_PP_CAT( has_member_function_callable_with_
- , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
- : public BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
- , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
- < Fun
- , BOOST_PP_CAT( has_member_function_named_
- , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )<Fun>::value
- , Args... >
- {};
+ template<typename Fun, bool HasFunc BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASSDFLT,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME);
- #endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
-
- #endif //BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START()
-
- #if BOOST_PP_ITERATION() == 0
-
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
-
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- #if !defined(_MSC_VER) || (_MSC_VER < 1600)
-
- #if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
-
- template<typename Fun>
- struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
- <Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
- {
- //Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and
- //wrong SFINAE for GCC 4.2/4.3
- static const bool value = true;
- };
-
- #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
-
- //Special case for 0 args
- template< class F
- , std::size_t N =
- sizeof((boost::move_detail::declval<F>().
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))>
- struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
- {
- boost_intrusive_has_member_function_callable_with::yes_type dummy;
- BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
- };
-
- //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not
- //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0.
- template<class F>
- struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<F, 0>
- {
- boost_intrusive_has_member_function_callable_with::no_type dummy;
- BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
- };
-
- template<typename Fun>
- struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
- <Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
- {
- template<class U>
- static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>
- Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*);
-
- template <class U>
- static boost_intrusive_has_member_function_callable_with::no_type Test(...);
+ //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization
+ template<typename Fun BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASS,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+ <Fun, false BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
+ {
+ static const bool value = false;
+ };
- static const bool value = sizeof(Test< Fun >(0))
- == sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
- };
- #endif //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
+ #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0
+ //0 arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present
+ #if !defined(BOOST_NO_CXX11_DECLTYPE)
- #else //#if !defined(_MSC_VER) || (_MSC_VER < 1600)
template<typename Fun>
- struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
- <Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true>
{
template<class U>
- static decltype( boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
- , boost_intrusive_has_member_function_callable_with::yes_type())
- Test(U*);
+ static decltype(boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
+ , boost_intrusive_hmfcw::yes_type()) Test(U* f);
template<class U>
- static boost_intrusive_has_member_function_callable_with::no_type Test(...);
-
- static const bool value = sizeof(Test<Fun>(0))
- == sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
+ static boost_intrusive_hmfcw::no_type Test(...);
+ static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);
};
- #endif //#if !defined(_MSC_VER) || (_MSC_VER < 1600)
-
- #else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #endif //#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ #else //defined(BOOST_NO_CXX11_DECLTYPE)
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
+ #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
- #else //BOOST_PP_ITERATION() == 0
+ template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)>
+ struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+ { boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; };
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
-
- template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), class P)>
- struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
- , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
- <Fun, true
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), P)
- BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION())
- , BOOST_INTRUSIVE_PP_IDENTITY
- , void)>
- {
- struct FunWrap : Fun
+ template<typename Fun>
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true>
{
- FunWrap();
-
- using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
- boost_intrusive_has_member_function_callable_with::private_type
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
- ( BOOST_PP_ENUM(BOOST_PP_ITERATION()
- , BOOST_INTRUSIVE_PP_IDENTITY
- , boost_intrusive_has_member_function_callable_with::dont_care)) const;
+ template<class U> static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>
+ Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*);
+ template<class U> static boost_intrusive_hmfcw::no_type Test(...);
+ static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type);
};
- static bool const value =
- (sizeof(boost_intrusive_has_member_function_callable_with::no_type) ==
- sizeof(boost_intrusive_has_member_function_callable_with::is_private_type
- ( (boost::move_detail::declval<FunWrap>().
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
- ( BOOST_PP_ENUM( BOOST_PP_ITERATION(), BOOST_INTRUSIVE_PP_DECLVAL, _) ), 0
- )
- )
- )
- );
- };
-
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
- #endif //#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- #endif //BOOST_PP_ITERATION() == 0
-
- #if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH()
-
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
-
- template<typename Fun
- BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION_FINISH(), BOOST_INTRUSIVE_PP_TEMPLATE_PARAM_VOID_DEFAULT, _)>
- struct BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
- : public BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
- <Fun, BOOST_PP_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun>::value
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), P) >
- {};
-
- BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
-
- #endif //#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
- #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
- #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
-
- #endif //#if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH()
+ #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
-#endif //!BOOST_PP_IS_ITERATING
+ template<typename Fun>
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true>
+ {//GCC [3.4-4.3) gives ICE when instantiating the 0 arg version so it is not supported.
+ static const bool value = true;
+ };
+
+ #endif//!defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
+ #endif //!defined(BOOST_NO_CXX11_DECLTYPE)
+ #endif //#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0
+
+ #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0
+ //1 to N arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present
+ #if defined(BOOST_NO_CXX11_DECLTYPE)
+ #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\
+ template<class Fun> struct BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) : Fun\
+ {\
+ using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;\
+ boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME\
+ (BOOST_MOVE_REPEAT##N(boost_intrusive_hmfcw::dont_care)) const;\
+ };\
+ \
+ template<typename Fun, BOOST_MOVE_CLASS##N>\
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true, BOOST_MOVE_TARG##N>\
+ {\
+ static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type\
+ ( (::boost::move_detail::declval\
+ < BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun> >().\
+ BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N), 0) )\
+ )\
+ );\
+ };\
+ //
+ #else
+ #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\
+ template<typename Fun, BOOST_MOVE_CLASS##N>\
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\
+ <Fun, true, BOOST_MOVE_TARG##N>\
+ {\
+ template<class U>\
+ static decltype(boost::move_detail::declval<U>().\
+ BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N)\
+ , boost_intrusive_hmfcw::yes_type()) Test(U* f);\
+ template<class U>\
+ static boost_intrusive_hmfcw::no_type Test(...);\
+ static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);\
+ };\
+ //
+ #endif
+ ////////////////////////////////////
+ // Build and invoke BOOST_MOVE_ITERATE_NTOM macrofunction, note that N has to be at least 1
+ ////////////////////////////////////
+ #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0
+ #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN 1
+ #else
+ #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN
+ #endif
+ BOOST_MOVE_CAT
+ (BOOST_MOVE_CAT(BOOST_MOVE_CAT(BOOST_MOVE_ITERATE_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN), TO)
+ ,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)
+ (BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION)
+ #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION
+ #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN
+ ////////////////////////////////////
+ // End of BOOST_MOVE_ITERATE_NTOM
+ ////////////////////////////////////
+ #endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0
+
+ /////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////
+ //
+ // has_member_function_callable_with_FUNC
+ //
+ /////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////
+
+ //Otherwise use the preprocessor
+ template<typename Fun BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASSDFLT,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
+ struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+ : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+ <Fun
+ , BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun>::value
+ BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
+ {};
+ #endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#endif
+
+BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
+
+//Undef local macros
+#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF
+
+//Undef user defined macros
+#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
+#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN
+#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX
+#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG
+#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END