Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:27

0001 // Copyright (c) 2009-2020 Vladimir Batov.
0002 // Use, modification and distribution are subject to the Boost Software License,
0003 // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
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     // The overloaded comma operator only kicks in for U != void essentially short-circuiting
0019     // itself ineffective. Otherwise, when U=void, the standard op,() kicks in and returns
0020     // 'void_return_substitute'.
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 // No-args case needs to be implemented differently and has not been implemented yet.
0043 //        template <typename R>
0044 //        struct check<true, R ()>
0045 
0046 // C1. Need to find some unique/ugly names so that they do not clash if this macro is
0047 //     used inside some other template class;
0048 // C2. Body of the function is not actually used anywhere.
0049 //     However, Intel C++ compiler treats it as an error. So, we provide the body.
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__; /*C1*/                                      \
0057     using  signature = __boost_is_callable_signature__; /*C1*/                              \
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(); /*C2*/}                  \
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     /* Check the existence of __member_name__ first, then the signature. */                 \
0098     static bool BOOST_CONSTEXPR_OR_CONST value = check<has_member<class_type>::value, signature>::value;   \
0099 }
0100 
0101 #endif // BOOST_CONVERT_IS_CALLABLE_HPP