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#include <experimental/__config> 72 73#if _LIBCPP_STD_VER >= 14 74 75# include <initializer_list> 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...> 107using void_t = void; 108 109struct nonesuch : private __nat { // make nonesuch "not an aggregate" 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 127template <template <class...> class _Op, class... _Args> 128using is_detected = typename _DETECTOR<nonesuch, void, _Op, _Args...>::value_t; 129template <template <class...> class _Op, class... _Args> 130using detected_t = typename _DETECTOR<nonesuch, void, _Op, _Args...>::type; 131template <template <class...> class _Op, class... _Args> 132constexpr bool is_detected_v = is_detected<_Op, _Args...>::value; 133 134template <class _Default, template <class...> class _Op, class... _Args> 135using detected_or = _DETECTOR<_Default, void, _Op, _Args...>; 136template <class _Default, template <class...> class _Op, class... _Args> 137using detected_or_t = typename detected_or<_Default, _Op, _Args...>::type; 138 139template <class _Expected, template <class...> class _Op, class... _Args> 140using is_detected_exact = is_same<_Expected, detected_t<_Op, _Args...>>; 141template <class _Expected, template <class...> class _Op, class... _Args> 142constexpr bool is_detected_exact_v = is_detected_exact<_Expected, _Op, _Args...>::value; 143 144template <class _To, template <class...> class _Op, class... _Args> 145using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, _To>; 146template <class _To, template <class...> class _Op, class... _Args> 147constexpr bool is_detected_convertible_v = is_detected_convertible<_To, _Op, _Args...>::value; 148 149_LIBCPP_END_NAMESPACE_LFTS 150 151#endif /* _LIBCPP_STD_VER >= 14 */ 152 153#endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */ 154