File indexing completed on 2025-01-18 09:30:27
0001
0002
0003
0004
0005 #ifndef BOOST_CONVERT_IS_CALLABLE_HPP
0006 #define BOOST_CONVERT_IS_CALLABLE_HPP
0007
0008 #include <boost/convert/detail/has_member.hpp>
0009
0010 namespace boost { namespace cnv { namespace detail
0011 {
0012 using yes_type = ::boost::type_traits::yes_type;
0013 using no_type = ::boost::type_traits:: no_type;
0014
0015 struct not_found {};
0016 struct void_return_substitute {};
0017
0018
0019
0020
0021 template<typename U> U const& operator, (U const&, void_return_substitute);
0022 template<typename U> U& operator, (U&, void_return_substitute);
0023
0024 template <typename src, typename dst> struct match_const { using type = dst; };
0025 template <typename src, typename dst> struct match_const<src const, dst> { using type = dst const; };
0026
0027 template<typename T, typename return_type>
0028 struct redirect
0029 {
0030 static no_type test (...);
0031 static yes_type test (return_type);
0032 };
0033
0034 template<typename T>
0035 struct redirect<T, void>
0036 {
0037 static yes_type test (...);
0038 static no_type test (not_found);
0039 };
0040 }}}
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #define BOOST_DECLARE_IS_CALLABLE(__trait_name__, __member_name__) \
0052 \
0053 template <typename __boost_is_callable_T__, typename __boost_is_callable_signature__> \
0054 class __trait_name__ \
0055 { \
0056 using class_type = __boost_is_callable_T__; \
0057 using signature = __boost_is_callable_signature__; \
0058 using not_found = boost::cnv::detail::not_found; \
0059 \
0060 BOOST_DECLARE_HAS_MEMBER(has_member, __member_name__); \
0061 \
0062 struct mixin : class_type \
0063 { \
0064 using class_type::__member_name__; \
0065 not_found __member_name__(...) const { return not_found(); } \
0066 }; \
0067 using mixin_ptr = typename boost::cnv::detail::match_const<class_type, mixin>::type*; \
0068 \
0069 template <bool has, typename F> struct check { static bool const value = false; }; \
0070 \
0071 template <typename Arg1, typename R> \
0072 struct check<true, R (Arg1)> \
0073 { \
0074 using a1 = typename boost::decay<Arg1>::type*; \
0075 \
0076 static bool BOOST_CONSTEXPR_OR_CONST value = \
0077 sizeof(boost::type_traits::yes_type) == \
0078 sizeof(boost::cnv::detail::redirect<class_type, R>::test( \
0079 (mixin_ptr(0)->__member_name__(*a1(0)), \
0080 boost::cnv::detail::void_return_substitute()))); \
0081 }; \
0082 template <typename Arg1, typename Arg2, typename R> \
0083 struct check<true, R (Arg1, Arg2)> \
0084 { \
0085 using a1 = typename boost::decay<Arg1>::type*; \
0086 using a2 = typename boost::decay<Arg2>::type*; \
0087 \
0088 static bool BOOST_CONSTEXPR_OR_CONST value = \
0089 sizeof(boost::type_traits::yes_type) == \
0090 sizeof(boost::cnv::detail::redirect<class_type, R>::test( \
0091 (mixin_ptr(0)->__member_name__(*a1(0), *a2(0)), \
0092 boost::cnv::detail::void_return_substitute()))); \
0093 }; \
0094 \
0095 public: \
0096 \
0097 \
0098 static bool BOOST_CONSTEXPR_OR_CONST value = check<has_member<class_type>::value, signature>::value; \
0099 }
0100
0101 #endif