xref: /llvm-project/libcxx/include/experimental/type_traits (revision b9a2658a3e8bd13b0f9e7a8a440832a95b377216)
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