type_traits.hpp
Go to the documentation of this file.
1 #ifndef CORE_TYPE_TRAITS_HPP
2 #define CORE_TYPE_TRAITS_HPP
3 
4 #include <type_traits>
5 #include <utility>
6 #include <tuple>
7 
8 #include "internal.hpp"
9 
10 namespace core {
11 inline namespace v2 {
12 namespace impl {
13 
14 /* union used for variant<Ts...> and implementing aligned_union, which is
15  * not provided by gcc 4.8.x, but is provided by clang. (aligned_union_t is
16  * the only alias missing from <type_traits>)
17  */
18 template <class... Ts> union discriminate;
19 template <> union discriminate<> { };
20 template <class T, class... Ts>
21 union discriminate<T, Ts...> {
22  T value;
24 };
25 
26 } /* namespace impl */
27 
28 /* custom type traits and types */
29 template <class T> using identity_t = typename meta::identity<T>::type;
30 template <class T> using identity = meta::identity<T>;
31 
32 /* extracts the class of a member function ponter */
33 template <class T> using class_of_t = impl::class_of_t<T>;
34 template <class T> using class_of = impl::class_of<T>;
35 
36 template <::std::size_t I, class T>
37 using tuple_element_t = typename ::std::tuple_element<I, T>::type;
38 template <class T> using tuple_size_t = typename ::std::tuple_size<T>::type;
39 
40 /* Implementation of N4389 */
41 template <bool B> using bool_constant = ::std::integral_constant<bool, B>;
42 
43 template <class...> struct conjunction;
44 template <class...> struct disjunction;
45 template <class...> struct negation;
46 
47 template <class T, class... Ts>
48 struct conjunction<T, Ts...> :
49  bool_constant<T::value and conjunction<Ts...>::value>
50 { };
51 template <> struct conjunction<> : ::std::true_type { };
52 
53 template <class T, class... Ts>
54 struct disjunction<T, Ts...> :
55  bool_constant<T::value or disjunction<Ts...>::value>
56 { };
57 template <> struct disjunction<> : ::std::false_type { };
58 
59 template <class T, class... Ts>
60 struct negation<T, Ts...> :
61  bool_constant<not T::value and negation<Ts...>::value>
62 { };
63 template <> struct negation<> : ::std::false_type { };
64 
65 /* C++ Library Fundamentals V2 TS detection idiom */
66 template <class... Ts> using void_t = meta::deduce<Ts...>;
67 
68 struct nonesuch {
69  nonesuch (nonesuch const&) = delete;
70  nonesuch () = delete;
71  ~nonesuch () = delete;
72  void operator = (nonesuch const&) = delete;
73 };
74 
75 template <class T, template <class...> class U, class... Args>
76 using detected_or = impl::make_detect<T, void, U, Args...>;
77 
78 template <template <class...> class T, class... Args>
79 using detected_t = typename detected_or<nonesuch, T, Args...>::type;
80 
81 template <class T, template <class...> class U, class... Args>
82 using detected_or_t = typename detected_or<T, U, Args...>::type;
83 
84 template <class To, template <class...> class T, class... Args>
85 using is_detected_convertible = ::std::is_convertible<
86  detected_t<T, Args...>,
87  To
88 >;
89 
90 template <class T, template <class...> class U, class... Args>
91 using is_detected_same = ::std::is_same<T, detected_t<U, Args...>>;
92 
93 template <class T, template<class...> class U, class... Args>
94 using is_detected_convertible = ::std::is_convertible<
95  detected_t<U, Args...>,
96  T
97 >;
98 
99 template <template <class...> class T, class... Args>
100 using is_detected = typename detected_or<nonesuch, T, Args...>::value_t;
101 
102 /* forward declaration */
103 template <::std::size_t, class...> struct aligned_union;
104 template <class...> struct invokable;
105 template <class...> struct invoke_of;
106 template <class T> struct result_of; /* SFINAE result_of */
107 
108 /* C++14 style aliases for standard traits */
109 template <class T>
110 using remove_volatile_t = typename ::std::remove_volatile<T>::type;
111 
112 template <class T>
113 using remove_const_t = typename ::std::remove_const<T>::type;
114 template <class T> using remove_cv_t = typename ::std::remove_cv<T>::type;
115 
116 template <class T>
117 using add_volatile_t = typename ::std::add_volatile<T>::type;
118 template <class T> using add_const_t = typename ::std::add_const<T>::type;
119 template <class T> using add_cv_t = typename ::std::add_cv<T>::type;
120 
121 template <class T>
122 using add_lvalue_reference_t = typename ::std::add_lvalue_reference<T>::type;
123 
124 template <class T>
125 using add_rvalue_reference_t = typename ::std::add_rvalue_reference<T>::type;
126 
127 template <class T>
128 using remove_reference_t = typename ::std::remove_reference<T>::type;
129 
130 template <class T>
131 using remove_pointer_t = typename ::std::remove_pointer<T>::type;
132 
133 template <class T> using add_pointer_t = typename ::std::add_pointer<T>::type;
134 
135 template <class T>
136 using make_unsigned_t = typename ::std::make_unsigned<T>::type;
137 template <class T> using make_signed_t = typename ::std::make_signed<T>::type;
138 
139 template <class T>
140 using remove_extent_t = typename ::std::remove_extent<T>::type;
141 
142 template <class T>
143 using remove_all_extents_t = typename ::std::remove_all_extents<T>::type;
144 
145 template <
146  ::std::size_t Len,
147  ::std::size_t Align = alignof(typename ::std::aligned_storage<Len>::type)
148 > using aligned_storage_t = typename ::std::aligned_storage<Len, Align>::type;
149 
150 template <::std::size_t Len, class... Types>
151 using aligned_union_t = typename aligned_union<Len, Types...>::type;
152 
153 template <class T> using decay_t = impl::decay_t<T>;
154 
155 template <bool B, class T = void>
156 using enable_if_t = typename ::std::enable_if<B, T>::type;
157 
158 template <bool B, class T, class F>
159 using conditional_t = typename ::std::conditional<B, T, F>::type;
160 
161 template <class T>
162 using underlying_type_t = typename ::std::underlying_type<T>::type;
163 
164 template <::std::size_t Len, class... Types>
165 struct aligned_union {
166  using union_type = impl::discriminate<Types...>;
167  static constexpr ::std::size_t size () noexcept {
168  return Len > sizeof(union_type) ? Len : sizeof(union_type);
169  }
170 
171  static constexpr ::std::size_t alignment_value = alignof(
172  impl::discriminate<Types...>
173  );
174 
175  using type = aligned_storage_t<
176  (Len > sizeof(union_type) ? Len : sizeof(union_type)),
177  alignment_value
178  >;
179 };
180 
181 /* custom type trait specializations */
182 template <class... Args> using invoke_of_t = typename invoke_of<Args...>::type;
183 
184 template <class... Args>
185 struct invokable : meta::none_t<
186  std::is_same<
187  decltype(impl::INVOKE(::std::declval<Args>()...)),
188  impl::undefined
189  >::value
190 > { };
191 
192 template <class... Args> struct invoke_of :
193  impl::invoke_of<invokable<Args...>::value, Args...>
194 { };
195 
196 template <class F, class... Args>
197 struct result_of<F(Args...)> : invoke_of<F, Args...> { };
198 
199 template <class T> using result_of_t = typename result_of<T>::type;
200 
201 template <class... Ts> struct common_type;
202 
203 template <class T> struct common_type<T> : identity<decay_t<T>> { };
204 template <class T, class U>
205 struct common_type<T, U> : identity<
206  decay_t<decltype(true ? ::std::declval<T>() : ::std::declval<U>())>
207 > { };
208 
209 template <class T, class U, class... Ts>
210 struct common_type<T, U, Ts...> : identity<
211  typename common_type<
212  typename common_type<T, U>::type,
213  Ts...
214  >::type
215 > { };
216 
217 template <class... T> using common_type_t = typename common_type<T...>::type;
218 
219 /* is_null_pointer */
220 template <class T> struct is_null_pointer : ::std::false_type { };
221 
222 template <>
223 struct is_null_pointer<add_cv_t<::std::nullptr_t>> : ::std::true_type { };
224 template <>
225 struct is_null_pointer<::std::nullptr_t volatile> : ::std::true_type { };
226 template <>
227 struct is_null_pointer<::std::nullptr_t const> : ::std::true_type { };
228 template <>
229 struct is_null_pointer<::std::nullptr_t> : ::std::true_type { };
230 
231 /* is_nothrow_swappable - N4426 (implemented before paper was proposed) */
232 template <class T, class U=T>
234 
235 /* propagates const or volatile without using the name propagate :) */
236 template <class T, class U>
237 struct transmit_volatile : ::std::conditional<
238  ::std::is_volatile<T>::value,
239  add_volatile_t<U>,
240  U
241 > { };
242 
243 template <class T, class U>
244 struct transmit_const : ::std::conditional<
245  ::std::is_const<T>::value,
246  add_const_t<U>,
247  U
248 > { };
249 
250 template <class T, class U>
252  T, typename transmit_const<T, U>::type
253 > { };
254 
255 template <class T, class U>
257 
258 template <class T, class U>
260 
261 template <class T, class U>
263 
264 }} /* namespace core::v2 */
265 
266 #endif /* CORE_TYPE_TRAITS_HPP */
aligned_storage_t<(Len > sizeof(union_type) ? Len :sizeof(union_type)), alignment_value > type
typename ::std::remove_cv< T >::type remove_cv_t
typename ::std::remove_pointer< T >::type remove_pointer_t
typename invoke_of< Args... >::type invoke_of_t
::std::integral_constant< bool, B > bool_constant
Definition: type_traits.hpp:41
typename ::std::add_cv< T >::type add_cv_t
Copyright © 2013 - 2015 MNMLSTC.
Definition: algorithm.hpp:23
typename transmit_const< T, U >::type transmit_const_t
typename ::std::remove_reference< T >::type remove_reference_t
::std::is_convertible< detected_t< T, Args... >, To > is_detected_convertible
Definition: type_traits.hpp:88
typename ::std::add_lvalue_reference< T >::type add_lvalue_reference_t
typename ::std::remove_all_extents< T >::type remove_all_extents_t
typename class_of< T >::type class_of_t
Definition: internal.hpp:50
typename ::std::remove_volatile< T >::type remove_volatile_t
typename transmit_cv< T, U >::type transmit_cv_t
typename result_of< T >::type result_of_t
typename ::std::add_volatile< T >::type add_volatile_t
typename detected_or< T, U, Args... >::type detected_or_t
Definition: type_traits.hpp:82
typename meta::identity< T >::type identity_t
Definition: type_traits.hpp:29
::std::is_same< T, detected_t< U, Args... > > is_detected_same
Definition: type_traits.hpp:91
typename ::std::remove_const< T >::type remove_const_t
typename ::std::make_unsigned< T >::type make_unsigned_t
typename ::std::add_const< T >::type add_const_t
typename ::std::underlying_type< T >::type underlying_type_t
typename ::std::decay< T >::type decay_t
Definition: internal.hpp:51
typename ::std::conditional< B, T, F >::type conditional_t
typename aligned_union< Len, Types... >::type aligned_union_t
typename ::std::make_signed< T >::type make_signed_t
typename ::std::add_pointer< T >::type add_pointer_t
typename detected_or< nonesuch, T, Args... >::type detected_t
Definition: type_traits.hpp:79
typename ::std::add_rvalue_reference< T >::type add_rvalue_reference_t
typename common_type< T... >::type common_type_t
impl::class_of_t< T > class_of_t
Definition: type_traits.hpp:33
impl::decay_t< T > decay_t
typename impl::deduce< Ts... > deduce
Definition: meta.hpp:212
typename detected_or< nonesuch, T, Args... >::value_t is_detected
typename ::std::enable_if< B, T >::type enable_if_t
meta::deduce< Ts... > void_t
Definition: type_traits.hpp:66
typename ::std::tuple_size< T >::type tuple_size_t
Definition: type_traits.hpp:38
typename ::std::remove_extent< T >::type remove_extent_t
typename transmit_volatile< T, U >::type transmit_volatile_t
typename ::std::tuple_element< I, T >::type tuple_element_t
Definition: type_traits.hpp:37
typename ::std::aligned_storage< Len, Align >::type aligned_storage_t
static constexpr ::std::size_t size() noexcept