////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-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. // ////////////////////////////////////////////////////////////////////////////// // sample.h #if !defined(BOOST_PP_IS_ITERATING) #ifndef BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED #include #include #include //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 namespace boost_intrusive_has_member_function_callable_with { struct dont_care { dont_care(...); }; template struct make_dontcare { typedef boost_intrusive_has_member_function_callable_with::dont_care type; }; 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 no_type is_private_type(T const &); yes_type is_private_type(private_type const &); } //boost_intrusive_has_member_function_callable_with #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_SINGLE_ITERATION #endif #endif //BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED #else //!BOOST_PP_IS_ITERATING #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME not defined!" #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_END #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!" #endif #if BOOST_PP_ITERATION_START() > BOOST_PP_ITERATION_FINISH() #error "BOOST_PP_ITERATION_START() must be <= BOOST_PP_ITERATION_FINISH()" #endif #if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START() BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN template class BOOST_PP_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, public BaseMixin { Base(); }; template class Helper{}; template static boost_intrusive_has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl); //! template struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) { static const bool value = false; }; //! #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl); template struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) { 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(). 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 struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) { 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 struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) { #ifndef BOOST_NO_CXX11_DECLTYPE template().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()) > static boost_intrusive_has_member_function_callable_with::yes_type Test(U*); #else template static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); #endif template 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 struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) { template 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::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()... ), 0) ) ) ); }; template 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 )::value , Args... > {}; #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 struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) { //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(). 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 struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) { 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 struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) { template static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); template 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); }; #endif //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) #else //#if !defined(_MSC_VER) || (_MSC_VER < 1600) template struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) { template static decltype( boost::move_detail::declval().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() , boost_intrusive_has_member_function_callable_with::yes_type()) Test(U*); template static boost_intrusive_has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test(0)) == sizeof(boost_intrusive_has_member_function_callable_with::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) BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END #else //BOOST_PP_ITERATION() == 0 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN template struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_ , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) { struct FunWrap : Fun { 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; }; 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(). 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 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) ::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() #endif //!BOOST_PP_IS_ITERATING