////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2011. 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 !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 #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(...); }; 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 #include #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() != 0 #error "BOOST_PP_ITERATION_START() must be zero (0)" #endif #if BOOST_PP_ITERATION() == 0 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 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_INTRUSIVE_PERFECT_FORWARDING) 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; }; //! #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 //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 #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(Fun*); 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_INTRUSIVE_PERFECT_FORWARDING) 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; }; //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); }; template struct BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME ) : Fun { BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )(); 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; }; template struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) { template struct make_dontcare { typedef boost_intrusive_has_member_function_callable_with::dont_care type; }; typedef BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME ) ::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 //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END #else //BOOST_PP_ITERATION() == 0 #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN template struct BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION()) , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)) : Fun { BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION()) , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME))(); 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 struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_ , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) { typedef BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION()) , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)) 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(). 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_INTRUSIVE_PERFECT_FORWARDING) #endif //BOOST_PP_ITERATION() == 0 #if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH() #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) 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_INTRUSIVE_PERFECT_FORWARDING) #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