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