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 20namespace std { 21namespace experimental { 22inline 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/* 86template <class> 87class _LIBCPP_TEMPLATE_VIS raw_invocation_type; 88 89template <class _Fn, class ..._Args> 90class _LIBCPP_TEMPLATE_VIS raw_invocation_type<_Fn(_Args...)>; 91 92template <class> 93class _LIBCPP_TEMPLATE_VIS invokation_type; 94 95template <class _Fn, class ..._Args> 96class _LIBCPP_TEMPLATE_VIS invokation_type<_Fn(_Args...)>; 97 98template <class _Tp> 99using invokation_type_t = typename invokation_type<_Tp>::type; 100 101template <class _Tp> 102using raw_invocation_type_t = typename raw_invocation_type<_Tp>::type; 103*/ 104 105// 3.3.4, Detection idiom 106template <class...> using void_t = void; 107 108struct nonesuch { 109 nonesuch() = delete; 110 ~nonesuch() = delete; 111 nonesuch (nonesuch const&) = delete; 112 void operator=(nonesuch const&) = delete; 113 }; 114 115template <class _Default, class _AlwaysVoid, template <class...> class _Op, class... _Args> 116struct _DETECTOR { 117 using value_t = false_type; 118 using type = _Default; 119 }; 120 121template <class _Default, template <class...> class _Op, class... _Args> 122struct _DETECTOR<_Default, void_t<_Op<_Args...>>, _Op, _Args...> { 123 using value_t = true_type; 124 using type = _Op<_Args...>; 125 }; 126 127 128template <template<class...> class _Op, class... _Args> 129 using is_detected = typename _DETECTOR<nonesuch, void, _Op, _Args...>::value_t; 130template <template<class...> class _Op, class... _Args> 131 using detected_t = typename _DETECTOR<nonesuch, void, _Op, _Args...>::type; 132template <template<class...> class _Op, class... _Args> 133 _LIBCPP_CONSTEXPR bool is_detected_v = is_detected<_Op, _Args...>::value; 134 135template <class Default, template<class...> class _Op, class... _Args> 136 using detected_or = _DETECTOR<Default, void, _Op, _Args...>; 137template <class Default, template<class...> class _Op, class... _Args> 138 using detected_or_t = typename detected_or<Default, _Op, _Args...>::type; 139 140template <class Expected, template<class...> class _Op, class... _Args> 141 using is_detected_exact = is_same<Expected, detected_t<_Op, _Args...>>; 142template <class Expected, template<class...> class _Op, class... _Args> 143 _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<Expected, _Op, _Args...>::value; 144 145template <class To, template<class...> class _Op, class... _Args> 146 using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, To>; 147template <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