1 /* 2 3 @Copyright Barrett Adair 2015-2017 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_DETAIL_UTILITY_HPP 10 #define BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP 11 12 #include <boost/callable_traits/detail/config.hpp> 13 #include <boost/callable_traits/detail/sfinae_errors.hpp> 14 #include <boost/callable_traits/detail/qualifier_flags.hpp> 15 16 namespace boost { namespace callable_traits { namespace detail { 17 18 struct cdecl_tag{}; 19 struct stdcall_tag{}; 20 struct fastcall_tag{}; 21 struct pascal_tag{}; 22 23 struct invalid_type { invalid_type() = delete; }; 24 struct reference_error { reference_error() = delete; }; 25 26 template<typename T> 27 using error_type = typename std::conditional< 28 std::is_reference<T>::value, reference_error, invalid_type>::type; 29 30 #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS 31 struct abominable_functions_not_supported_on_this_compiler{}; 32 #endif 33 34 // used to convey "this type doesn't matter" in code 35 struct dummy {}; 36 37 // used as return type in failed SFINAE tests 38 struct substitution_failure : std::false_type{}; 39 40 template<bool Value> 41 using bool_type = std::integral_constant<bool, Value>; 42 43 // shorthand for std::tuple_element 44 template<std::size_t I, typename Tup> 45 using at = typename std::tuple_element<I, Tup>::type; 46 47 template<typename T, typename Class> 48 using add_member_pointer = T Class::*; 49 50 template<typename L, typename R, typename ErrorType> 51 using fail_when_same = fail_if<std::is_same<L, R>::value, ErrorType>; 52 53 template<typename T, typename ErrorType, 54 typename U = typename std::remove_reference<T>::type> 55 using try_but_fail_if_invalid = sfinae_try<T, 56 fail_when_same<U, invalid_type, ErrorType>, 57 fail_when_same<U, reference_error, 58 reference_type_not_supported_by_this_metafunction>>; 59 60 template<typename T, typename ErrorType, 61 typename U = typename std::remove_reference<T>::type, 62 bool is_reference_error = std::is_same<reference_error, U>::value> 63 using fail_if_invalid = fail_if< 64 std::is_same<U, invalid_type>::value || is_reference_error, 65 typename std::conditional<is_reference_error, 66 reference_type_not_supported_by_this_metafunction, ErrorType>::type>; 67 68 template<typename T, typename Fallback> 69 using fallback_if_invalid = typename std::conditional< 70 std::is_same<T, invalid_type>::value, Fallback, T>::type; 71 72 template<typename T, template<class> class Alias, typename U = Alias<T>> 73 struct force_sfinae { 74 using type = U; 75 }; 76 77 template<typename T> 78 using shallow_decay = typename std::remove_cv< 79 typename std::remove_reference<T>::type>::type; 80 81 template<typename T> 82 struct is_reference_wrapper_t { 83 using type = std::false_type; 84 }; 85 86 template<typename T> 87 struct is_reference_wrapper_t<std::reference_wrapper<T>> { 88 using type = std::true_type; 89 }; 90 91 template<typename T> 92 using is_reference_wrapper = 93 typename is_reference_wrapper_t<shallow_decay<T>>::type; 94 95 template<typename T, typename = std::true_type> 96 struct unwrap_reference_t { 97 using type = T; 98 }; 99 100 template<typename T> 101 struct unwrap_reference_t<T, is_reference_wrapper<T>> { 102 using type = decltype(std::declval<T>().get()); 103 }; 104 105 // removes std::reference_wrapper 106 template<typename T> 107 using unwrap_reference = typename unwrap_reference_t<T>::type; 108 109 }}} // namespace boost::callable_traits::detail 110 111 #endif // #ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP 112