22 #ifndef LELY_LIBC_TYPE_TRAITS_HPP_
23 #define LELY_LIBC_TYPE_TRAITS_HPP_
27 #include <type_traits>
33 #if __cplusplus <= 201703L
37 using type = typename ::std::remove_cv<
38 typename ::std::remove_reference<T>::type>::type;
42 using remove_cvref_t =
typename remove_cvref<T>::type;
44 #endif // __cplusplus <= 201703L
46 #if __cplusplus >= 201703L
48 using ::std::bool_constant;
50 using ::std::invoke_result;
51 using ::std::invoke_result_t;
53 using ::std::is_invocable;
54 using ::std::is_invocable_r;
58 using ::std::conjunction;
59 using ::std::disjunction;
60 using ::std::negation;
62 #else // __cplusplus < 201703L
65 using bool_constant = ::std::integral_constant<bool, B>;
77 template <
class F,
class... Args>
79 call(F&& f, Args&&... args)
80 -> decltype(::std::forward<F>(f)(::std::forward<Args>(args)...)) {
81 return ::std::forward<F>(f)(::std::forward<Args>(args)...);
84 template <
class F,
class... Args>
87 return noexcept(::std::declval<F>()(::std::declval<Args>()...));
91 template <
class MT,
class B>
94 class T,
class Td = typename ::std::decay<T>::type,
95 class = typename ::std::enable_if<::std::is_base_of<B, Td>::value>::type>
98 return static_cast<T&&
>(t);
102 class T,
class Td = typename ::std::decay<T>::type,
103 class = typename ::std::enable_if<is_reference_wrapper<Td>::value>::type>
105 get(T&& t) -> decltype(t.get()) {
110 class T,
class Td = typename ::std::decay<T>::type,
111 class = typename ::std::enable_if<!::std::is_base_of<B, Td>::value>::type,
112 class = typename ::std::enable_if<!is_reference_wrapper<Td>::value>::type>
114 get(T&& t) -> decltype(*::std::forward<T>(t)) {
115 return *::std::forward<T>(t);
119 class T,
class... Args,
class MT1,
120 class = typename ::std::enable_if<::std::is_function<MT1>::value>::type>
122 call(MT1 B::*pmf, T&& t, Args&&... args)
123 -> decltype((invoke_impl::get(::std::forward<T>(t)).*
124 pmf)(::std::forward<Args>(args)...)) {
125 return (invoke_impl::get(::std::forward<T>(t)).*
126 pmf)(::std::forward<Args>(args)...);
131 call(MT B::*pmd, T&& t)
132 -> decltype(invoke_impl::get(::std::forward<T>(t)).*pmd) {
133 return invoke_impl::get(::std::forward<T>(t)).*pmd;
137 template <
class F,
class... Args,
class Fd = typename ::std::decay<F>::type>
139 invoke(F&& f, Args&&... args)
141 ::std::forward<Args>(args)...)) {
143 ::std::forward<Args>(args)...);
146 template <
class,
class,
class...>
149 template <
class F,
class... Args>
151 ::std::declval<Args>()...))),
153 using type = decltype(
invoke(::std::declval<F>(), ::std::declval<Args>()...));
165 template <
class F,
class... Args>
168 template <
class F,
class... Args>
169 using invoke_result_t =
typename invoke_result<F, Args...>::type;
185 template <
class... T>
190 template <
class,
class,
class =
void>
193 template <
class Result,
class R>
195 : bool_constant<::std::is_void<R>::value ||
196 ::std::is_convertible<typename Result::type, R>::value> {};
205 template <
class F,
class... Args>
214 template <
class R,
class F,
class... Args>
221 template <
class... B>
227 template <
class B1,
class... Bn>
229 : ::std::conditional<static_cast<bool>(B1::value), conjunction<Bn...>,
236 template <
class... B>
242 template <
class B1,
class... Bn>
244 : ::std::conditional<static_cast<bool>(B1::value), B1,
245 disjunction<Bn...>>::type {};
249 struct negation : bool_constant<!static_cast<bool>(B::value)> {};
251 #endif // __cplusplus < 201703L
256 #endif // !LELY_LIBC_TYPE_TRAITS_HPP_