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