////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2011-2013. 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. // ////////////////////////////////////////////////////////////////////////////// //Just for BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED #include #include #include namespace boost{ namespace intrusive{ namespace intrusive_detail{ namespace has_member_function_callable_with { struct dont_care { dont_care(...); }; template struct make_dontcare { typedef 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; struct no_type{ char dummy[2]; }; template no_type is_private_type(T const &); yes_type is_private_type(private_type const &); }}}} namespace boost{ namespace intrusive{ namespace intrusive_detail{ template class has_member_function_named_func { struct BaseMixin { void func(); }; struct Base : public ::boost::intrusive::detail::remove_cv::type, public BaseMixin {}; template class Helper{}; template static has_member_function_callable_with::no_type deduce (U*, Helper* = 0); static has_member_function_callable_with::yes_type deduce(...); public: static const bool value = sizeof(has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); }; }}} #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) namespace boost{ namespace intrusive{ namespace intrusive_detail{ template struct has_member_function_callable_with_func_impl; template struct has_member_function_callable_with_func_impl { static const bool value = false; }; }}} namespace boost{ namespace intrusive{ namespace intrusive_detail{ #if !defined(_MSC_VER) || (_MSC_VER < 1600) #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) template().func(), 0)> struct zeroarg_checker_func { has_member_function_callable_with::yes_type dummy; zeroarg_checker_func(int); }; //For buggy compilers like MSVC 7.1, ((F*)0)->func() does not //fail but sizeof yields to 0. template struct zeroarg_checker_func { has_member_function_callable_with::no_type dummy; zeroarg_checker_func(int); }; template struct has_member_function_callable_with_func_impl { template static zeroarg_checker_func Test(zeroarg_checker_func*); template static has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(has_member_function_callable_with::yes_type); }; #else template struct has_member_function_callable_with_func_impl { //GCC [3.4-4.3) gives ICE when instantiating the 0 arg version so it is not supported. static const bool value = true; }; #endif #else template struct has_member_function_callable_with_func_impl { template static decltype(boost::move_detail::declval().func(), has_member_function_callable_with::yes_type()) Test(U* f); template static has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test((Fun*)0)) == sizeof(has_member_function_callable_with::yes_type); }; #endif }}} namespace boost{ namespace intrusive{ namespace intrusive_detail{ template struct has_member_function_callable_with_func_impl { struct FunWrap : Fun { using Fun::func; has_member_function_callable_with::private_type func( has_member_function_callable_with::dont_care) const; }; static bool const value = (sizeof(has_member_function_callable_with::no_type) == sizeof(has_member_function_callable_with::is_private_type ( (::boost::move_detail::declval< FunWrap >().func( ::boost::move_detail::declval() ), 0) ) ) ); }; }}} namespace boost{ namespace intrusive{ namespace intrusive_detail{ template struct has_member_function_callable_with_func_impl { struct FunWrap: Fun { using Fun::func; has_member_function_callable_with::private_type func( has_member_function_callable_with::dont_care , has_member_function_callable_with::dont_care) const; }; static bool const value = (sizeof(has_member_function_callable_with::no_type) == sizeof(has_member_function_callable_with::is_private_type ( (::boost::move_detail::declval< FunWrap >(). func( ::boost::move_detail::declval() , ::boost::move_detail::declval() ) , 0) ) ) ); }; }}} namespace boost{ namespace intrusive{ namespace intrusive_detail{ template struct has_member_function_callable_with_func_impl { struct FunWrap: Fun { using Fun::func; has_member_function_callable_with::private_type func( has_member_function_callable_with::dont_care , has_member_function_callable_with::dont_care , has_member_function_callable_with::dont_care) const; }; static bool const value = (sizeof(has_member_function_callable_with::no_type) == sizeof(has_member_function_callable_with::is_private_type ( (::boost::move_detail::declval< FunWrap >(). func( ::boost::move_detail::declval() , ::boost::move_detail::declval() , ::boost::move_detail::declval() ) , 0) ) ) ); }; template struct has_member_function_callable_with_func : public has_member_function_callable_with_func_impl ::value, P0 , P1 , P2 > {}; }}} #else //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) namespace boost{ namespace intrusive{ namespace intrusive_detail{ template struct has_member_function_callable_with_func_impl; template struct has_member_function_callable_with_func_impl { static const bool value = false; }; }}} namespace boost{ namespace intrusive{ namespace intrusive_detail{ #ifdef BOOST_NO_CXX11_DECLTYPE template().func(), 0)> struct zeroarg_checker_func { has_member_function_callable_with::yes_type dummy; zeroarg_checker_func(int); }; //For buggy compilers like MSVC 7.1, ((F*)0)->func() does not //fail but sizeof yields to 0. template struct zeroarg_checker_func { has_member_function_callable_with::no_type dummy; zeroarg_checker_func(int); }; #endif //BOOST_NO_CXX11_DECLTYPE template struct has_member_function_callable_with_func_impl { #ifndef BOOST_NO_CXX11_DECLTYPE template().func()) > static boost_intrusive_has_member_function_callable_with::yes_type Test(U*); #else template static zeroarg_checker_func Test(zeroarg_checker_func*); #endif template static has_member_function_callable_with::no_type Test(...); static const bool value = sizeof(Test< Fun >(0)) == sizeof(has_member_function_callable_with::yes_type); }; }}} namespace boost{ namespace intrusive{ namespace intrusive_detail{ template struct has_member_function_callable_with_func_impl { template struct FunWrapTmpl : Fun { using Fun::func; has_member_function_callable_with::private_type func(DontCares...) const; }; typedef FunWrapTmpl::type...> FunWrap; static bool const value = (sizeof(has_member_function_callable_with::no_type) == sizeof(has_member_function_callable_with::is_private_type ( (::boost::move_detail::declval< FunWrap >().func( ::boost::move_detail::declval()... ), 0) ) ) ); }; template struct has_member_function_callable_with_func : public has_member_function_callable_with_func_impl ::value, Args... > {}; }}} #endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) struct functor { void func(); void func(const int&); void func(const int&, const int&); void func(const int&, const int&, const int&); }; struct functor2 { void func(char*); void func(int, char*); void func(int, char*, double); void func(const int&, char*, void *); }; struct functor3 { }; struct functor4 { void func(...); template void func(int, const T &); template void func(const T &); template void func(int, const T &, const U &); }; int main() { using namespace boost::intrusive::intrusive_detail; #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) { int check1[ has_member_function_callable_with_func::value ? 1 : -1]; int check2[!has_member_function_callable_with_func::value ? 1 : -1]; int check3[!has_member_function_callable_with_func::value ? 1 : -1]; int check4[ has_member_function_callable_with_func::value ? 1 : -1]; (void)check1; (void)check2; (void)check3; (void)check4; } #endif { int check1[ has_member_function_callable_with_func::value ? 1 : -1]; int check2[!has_member_function_callable_with_func::value ? 1 : -1]; int check3[!has_member_function_callable_with_func::value ? 1 : -1]; int check4[ has_member_function_callable_with_func::value ? 1 : -1]; int check5[!has_member_function_callable_with_func::value ? 1 : -1]; int check6[!has_member_function_callable_with_func::value ? 1 : -1]; int check7[ has_member_function_callable_with_func::value ? 1 : -1]; int check8[ has_member_function_callable_with_func::value ? 1 : -1]; (void)check1; (void)check2; (void)check3; (void)check4; (void)check5; (void)check6; (void)check7; (void)check8; } { int check1[ has_member_function_callable_with_func::value ? 1 : -1]; int check2[!has_member_function_callable_with_func::value ? 1 : -1]; int check3[!has_member_function_callable_with_func::value ? 1 : -1]; int check4[ has_member_function_callable_with_func::value ? 1 : -1]; int check5[!has_member_function_callable_with_func::value ? 1 : -1]; int check6[!has_member_function_callable_with_func::value ? 1 : -1]; int check7[ has_member_function_callable_with_func::value ? 1 : -1]; (void)check1; (void)check2; (void)check3; (void)check4; (void)check5; (void)check6; (void)check7; } { int check1[ has_member_function_callable_with_func::value ? 1 : -1]; int check2[!has_member_function_callable_with_func::value ? 1 : -1]; int check3[!has_member_function_callable_with_func::value ? 1 : -1]; int check4[ has_member_function_callable_with_func::value ? 1 : -1]; int check5[!has_member_function_callable_with_func::value ? 1 : -1]; int check6[!has_member_function_callable_with_func::value ? 1 : -1]; int check7[ has_member_function_callable_with_func::value ? 1 : -1]; (void)check1; (void)check2; (void)check3; (void)check4; (void)check5; (void)check6; (void)check7; } return 0; }