sfinae_errors.hpp 3.4 KB

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