• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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