19 #ifndef CORE_TYPE_TRAITS_HPP
20 #define CORE_TYPE_TRAITS_HPP
22 #include <type_traits>
34 template <
class U>
using tuple_size_t = typename ::std::tuple_size<U>::type;
35 template <
class U>
static void check (tuple_size_t<U>*) noexcept;
36 template <
class>
static void check (...) noexcept(
false);
38 static constexpr
bool value = noexcept(check<T>(
nullptr));
45 static auto check (U* u) noexcept -> decltype(u->at(0ul),
void());
46 template <
class>
static void check (...) noexcept(
false);
48 static constexpr
bool value = noexcept(check<T>(
nullptr));
52 template <
class T>
struct class_of {
using type = T; };
53 template <
class Signature,
class Type>
54 struct class_of<Signature Type::*> {
using type = Type; };
57 template <
class... Args>
struct invokable;
58 template <
class... Args>
struct invoke_of;
63 using remove_volatile_t = typename ::std::remove_volatile<T>::type;
66 using remove_const_t = typename ::std::remove_const<T>::type;
67 template <
class T>
using remove_cv_t = typename ::std::remove_cv<T>::type;
70 using add_volatile_t = typename ::std::add_volatile<T>::type;
71 template <
class T>
using add_const_t = typename ::std::add_const<T>::type;
72 template <
class T>
using add_cv_t = typename ::std::add_cv<T>::type;
75 using add_lvalue_reference_t = typename ::std::add_lvalue_reference<T>::type;
78 using add_rvalue_reference_t = typename ::std::add_rvalue_reference<T>::type;
81 using remove_reference_t = typename ::std::remove_reference<T>::type;
84 using remove_pointer_t = typename ::std::remove_pointer<T>::type;
86 template <
class T>
using add_pointer_t = typename ::std::add_pointer<T>::type;
89 using make_unsigned_t = typename ::std::make_unsigned<T>::type;
90 template <
class T>
using make_signed_t = typename ::std::make_signed<T>::type;
93 using remove_extent_t = typename ::std::remove_extent<T>::type;
96 using remove_all_extents_t = typename ::std::remove_all_extents<T>::type;
98 template < ::std::
size_t Len, ::std::
size_t Align>
99 using aligned_storage_t = typename ::std::aligned_storage<Len, Align>::type;
101 template <
class T>
using decay_t = typename ::std::decay<T>::type;
103 template <
bool B,
class T =
void>
104 using enable_if_t = typename ::std::enable_if<B, T>::type;
106 template <
bool B,
class T,
class F>
107 using conditional_t = typename ::std::conditional<B, T, F>::type;
110 using underlying_type_t = typename ::std::underlying_type<T>::type;
113 template <
class... Args>
using invoke_of_t =
typename invoke_of<Args...>::type;
114 template <
class T>
using class_of_t =
typename class_of<T>::type;
124 template <
class Functor,
class Object,
class... Args>
125 auto invoke_expr (Functor&& fun, Object&& obj, Args&&... args) -> enable_if_t<
126 ::std::is_member_function_pointer<remove_reference_t<Functor>>::value and
128 class_of_t<remove_reference_t<Functor>>,
129 remove_reference_t<Object>
131 decltype((::std::forward<Object>(obj).*fun)(::std::forward<Args>(args)...))
134 template <
class Functor,
class Object,
class... Args>
135 auto invoke_expr (Functor&& fun, Object&& obj, Args&&... args) -> enable_if_t<
136 ::std::is_member_function_pointer<remove_reference_t<Functor>>::value and
137 not ::std::is_base_of<
138 class_of_t<remove_reference_t<Functor>>,
139 remove_reference_t<Object>
142 ((*::std::forward<Object>(obj)).*fun)(::std::forward<Args>(args)...)
146 template <
class Functor,
class Object>
147 auto invoke_expr (Functor&& functor, Object&&
object) -> enable_if_t<
148 ::std::is_member_object_pointer<remove_reference_t<Functor>>::value and
150 class_of_t<remove_reference_t<Functor>>,
151 remove_reference_t<Object>
153 decltype(::std::forward<Object>(
object).*functor)
156 template <
class Functor,
class Object>
157 auto invoke_expr (Functor&& functor, Object&&
object) -> enable_if_t<
158 ::std::is_member_object_pointer<remove_reference_t<Functor>>::value and
159 not ::std::is_base_of<
160 class_of_t<remove_reference_t<Functor>>,
161 remove_reference_t<Object>
163 decltype((*::std::forward<Object>(
object)).*functor)
166 template <
class Functor,
class... Args>
167 auto invoke_expr (Functor&& functor, Args&&... args) -> decltype(
168 ::std::forward<Functor>(functor)(::std::forward<Args>(args)...)
172 template <
class... Args>
174 using type = decltype(invoke_expr(::std::declval<Args>()...));
178 using ::std::declval;
181 template <
class T,
class U>
183 template <
class X,
class Y>
184 static auto check (
int) noexcept -> decltype(
185 swap(declval<X&>(), declval<Y&>()),
188 template <
class X,
class Y>
static void check (...) noexcept(
false);
190 static constexpr
bool value =
191 noexcept(check<T, U>(0)) and noexcept(check<U, T>(0));
194 template <
class T,
class U>
197 is_swappable<T, U>::value and noexcept(swap(declval<T&>(), declval<U&>()))
202 template <
class... Args>
struct invokable : ::std::integral_constant<
205 decltype(impl::invoke_expr(::std::declval<Args>()...)),
214 template <
class F,
class... Args>
221 template <
class T>
struct common_type<T> {
using type = decay_t<T>; };
222 template <
class T,
class U>
224 using type = decay_t<
225 decltype(
true ? ::std::declval<T>() : ::std::declval<U>())
229 template <
class T,
class U,
class... Ts>
237 template <
class... T>
using common_type_t =
typename common_type<T...>::type;
252 template <
class T,
class U=T>
253 using is_swappable = ::std::integral_constant<
259 template <
class T,
class U=T>
264 template <
class T,
class... Args>
265 struct all_traits<T, Args...> : ::std::integral_constant<bool,
266 T::value and all_traits<Args...>::value
272 template <
class T,
class... Args>
273 struct any_traits<T, Args...> : ::std::integral_constant<bool,
274 T::value or any_traits<Args...>::value
279 template <
class... Args>
struct no_traits : ::std::integral_constant<bool,
280 not all_traits<Args...>::value