1 /* 2 @Copyright Barrett Adair 2016-2017 3 4 Distributed under the Boost Software License, Version 1.0. 5 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 6 7 */ 8 9 #ifndef BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP 10 #define BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP 11 12 #include <boost/callable_traits/detail/config.hpp> 13 14 namespace boost { namespace callable_traits { namespace detail { 15 16 struct sfinae_error{}; 17 18 template<typename T> 19 struct success { 20 static constexpr bool value = true; 21 struct _ { using type = T; }; 22 }; 23 24 template<bool B, typename T> 25 struct fail_if : T { 26 static_assert(std::is_base_of<sfinae_error, T>::value, 27 "incorrect usage of fail_if"); 28 29 static constexpr bool value = B; 30 }; 31 32 template<typename T, typename... FailIfs> 33 using sfinae_try = typename BOOST_CLBL_TRTS_DISJUNCTION( 34 FailIfs..., success<T>)::_::type; 35 36 template<typename FailMsg, typename ForceTwoPhaseLookup> 37 struct fail { 38 using type = typename std::conditional<std::is_same<ForceTwoPhaseLookup, std::false_type>::value, 39 FailMsg, FailMsg>::type::_::type; 40 }; 41 42 }}} // namespace boost::callable_traits::detail 43 44 #define BOOST_CLBL_TRTS_PP_CAT_(x, y) x ## y 45 #define BOOST_CLBL_TRTS_PP_CAT(x, y) BOOST_CLBL_TRTS_PP_CAT_(x, y) 46 47 #define BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(origin) \ 48 namespace error { \ 49 template<typename ErrorMessage> \ 50 struct origin : \ 51 ::boost::callable_traits::detail::sfinae_error \ 52 { struct _ {}; }; \ 53 } \ 54 /**/ 55 56 #define BOOST_CLBL_TRTS_SFINAE_MSG(origin, name) \ 57 struct BOOST_CLBL_TRTS_PP_CAT(name, _ ){}; \ 58 struct name : error::origin< \ 59 BOOST_CLBL_TRTS_PP_CAT(name, _ )>{}; \ 60 /**/ 61 62 namespace boost { namespace callable_traits { 63 64 BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(parameters) 65 BOOST_CLBL_TRTS_SFINAE_MSG(parameters, index_out_of_range_for_parameter_list) 66 BOOST_CLBL_TRTS_SFINAE_MSG(parameters, cannot_determine_parameters_for_this_type) 67 68 BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(varargs) 69 BOOST_CLBL_TRTS_SFINAE_MSG(varargs, varargs_are_illegal_for_this_type) 70 71 BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(member_qualifiers) 72 BOOST_CLBL_TRTS_SFINAE_MSG(member_qualifiers, member_qualifiers_are_illegal_for_this_type) 73 BOOST_CLBL_TRTS_SFINAE_MSG(member_qualifiers, this_compiler_doesnt_support_abominable_function_types) 74 75 BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(transaction_safe_) 76 BOOST_CLBL_TRTS_SFINAE_MSG(transaction_safe_, transaction_safe_is_not_supported_by_this_configuration) 77 78 BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(expand_args) 79 BOOST_CLBL_TRTS_SFINAE_MSG(expand_args, cannot_expand_the_parameter_list_of_first_template_argument) 80 81 BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(member_pointer_required) 82 BOOST_CLBL_TRTS_SFINAE_MSG(member_pointer_required, type_is_not_a_member_pointer) 83 84 BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(reference_error) 85 BOOST_CLBL_TRTS_SFINAE_MSG(reference_error, reference_type_not_supported_by_this_metafunction) 86 87 }} // namespace boost::callable_traits 88 89 #endif // #ifndef BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP 90