• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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