1 // -*- C++ -*- 2 //===-------------------------- type_traits -------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef _LIBCPP_EXPERIMENTAL_TYPE_TRAITS 12 #define _LIBCPP_EXPERIMENTAL_TYPE_TRAITS 13 14 /** 15 experimental/type_traits synopsis 16 17 // C++1y 18 #include <type_traits> 19 20 namespace std { 21 namespace experimental { 22 inline namespace fundamentals_v1 { 23 24 // 3.3.2, Other type transformations 25 template <class> class invocation_type; // not defined 26 template <class F, class... ArgTypes> class invocation_type<F(ArgTypes...)>; 27 template <class> class raw_invocation_type; // not defined 28 template <class F, class... ArgTypes> class raw_invocation_type<F(ArgTypes...)>; 29 30 template <class T> 31 using invocation_type_t = typename invocation_type<T>::type; 32 template <class T> 33 using raw_invocation_type_t = typename raw_invocation_type<T>::type; 34 35 // 3.3.4, Detection idiom 36 template <class...> using void_t = void; 37 38 struct nonesuch { 39 nonesuch() = delete; 40 ~nonesuch() = delete; 41 nonesuch(nonesuch const&) = delete; 42 void operator=(nonesuch const&) = delete; 43 }; 44 45 template <template<class...> class Op, class... Args> 46 using is_detected = see below; 47 template <template<class...> class Op, class... Args> 48 constexpr bool is_detected_v = is_detected<Op, Args...>::value; 49 template <template<class...> class Op, class... Args> 50 using detected_t = see below; 51 template <class Default, template<class...> class Op, class... Args> 52 using detected_or = see below; 53 template <class Default, template<class...> class Op, class... Args> 54 using detected_or_t = typename detected_or<Default, Op, Args...>::type; 55 template <class Expected, template<class...> class Op, class... Args> 56 using is_detected_exact = is_same<Expected, detected_t<Op, Args...>>; 57 template <class Expected, template<class...> class Op, class... Args> 58 constexpr bool is_detected_exact_v 59 = is_detected_exact<Expected, Op, Args...>::value; 60 template <class To, template<class...> class Op, class... Args> 61 using is_detected_convertible = is_convertible<detected_t<Op, Args...>, To>; 62 template <class To, template<class...> class Op, class... Args> 63 constexpr bool is_detected_convertible_v 64 = is_detected_convertible<To, Op, Args...>::value; 65 66 } // namespace fundamentals_v1 67 } // namespace experimental 68 } // namespace std 69 70 */ 71 72 #include <experimental/__config> 73 74 #if _LIBCPP_STD_VER > 11 75 76 #include <type_traits> 77 78 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 79 #pragma GCC system_header 80 #endif 81 82 _LIBCPP_BEGIN_NAMESPACE_LFTS 83 84 // 3.3.2, Other type transformations 85 /* 86 template <class> 87 class _LIBCPP_TEMPLATE_VIS raw_invocation_type; 88 89 template <class _Fn, class ..._Args> 90 class _LIBCPP_TEMPLATE_VIS raw_invocation_type<_Fn(_Args...)>; 91 92 template <class> 93 class _LIBCPP_TEMPLATE_VIS invokation_type; 94 95 template <class _Fn, class ..._Args> 96 class _LIBCPP_TEMPLATE_VIS invokation_type<_Fn(_Args...)>; 97 98 template <class _Tp> 99 using invokation_type_t = typename invokation_type<_Tp>::type; 100 101 template <class _Tp> 102 using raw_invocation_type_t = typename raw_invocation_type<_Tp>::type; 103 */ 104 105 // 3.3.4, Detection idiom 106 template <class...> using void_t = void; 107 108 struct nonesuch { 109 nonesuch() = delete; 110 ~nonesuch() = delete; 111 nonesuch (nonesuch const&) = delete; 112 void operator=(nonesuch const&) = delete; 113 }; 114 115 template <class _Default, class _AlwaysVoid, template <class...> class _Op, class... _Args> 116 struct _DETECTOR { 117 using value_t = false_type; 118 using type = _Default; 119 }; 120 121 template <class _Default, template <class...> class _Op, class... _Args> 122 struct _DETECTOR<_Default, void_t<_Op<_Args...>>, _Op, _Args...> { 123 using value_t = true_type; 124 using type = _Op<_Args...>; 125 }; 126 127 128 template <template<class...> class _Op, class... _Args> 129 using is_detected = typename _DETECTOR<nonesuch, void, _Op, _Args...>::value_t; 130 template <template<class...> class _Op, class... _Args> 131 using detected_t = typename _DETECTOR<nonesuch, void, _Op, _Args...>::type; 132 template <template<class...> class _Op, class... _Args> 133 _LIBCPP_CONSTEXPR bool is_detected_v = is_detected<_Op, _Args...>::value; 134 135 template <class Default, template<class...> class _Op, class... _Args> 136 using detected_or = _DETECTOR<Default, void, _Op, _Args...>; 137 template <class Default, template<class...> class _Op, class... _Args> 138 using detected_or_t = typename detected_or<Default, _Op, _Args...>::type; 139 140 template <class Expected, template<class...> class _Op, class... _Args> 141 using is_detected_exact = is_same<Expected, detected_t<_Op, _Args...>>; 142 template <class Expected, template<class...> class _Op, class... _Args> 143 _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<Expected, _Op, _Args...>::value; 144 145 template <class To, template<class...> class _Op, class... _Args> 146 using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, To>; 147 template <class To, template<class...> class _Op, class... _Args> 148 _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<To, _Op, _Args...>::value; 149 150 151 _LIBCPP_END_NAMESPACE_LFTS 152 153 #endif /* _LIBCPP_STD_VER > 11 */ 154 155 #endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */ 156