22#ifndef LELY_LIBC_TYPE_TRAITS_HPP_
23#define LELY_LIBC_TYPE_TRAITS_HPP_
33#if __cplusplus <= 201703L
37 using type = typename ::std::remove_cv<
38 typename ::std::remove_reference<T>::type>::type;
42using remove_cvref_t =
typename remove_cvref<T>::type;
46#if __cplusplus >= 201703L
48using ::std::bool_constant;
50using ::std::invoke_result;
51using ::std::invoke_result_t;
53using ::std::is_invocable;
54using ::std::is_invocable_r;
58using ::std::conjunction;
59using ::std::disjunction;
65using 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>()...));
91template <
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;
137template <
class F,
class... Args,
class Fd = typename ::std::decay<F>::type>
139invoke(F&& f, Args&&... args)
141 ::std::forward<Args>(args)...)) {
143 ::std::forward<Args>(args)...);
146template <
class,
class,
class...>
149template <
class F,
class... Args>
151 ::std::declval<Args>()...))),
153 using type =
decltype(
invoke(::std::declval<F>(), ::std::declval<Args>()...));
165template <
class F,
class... Args>
168template <
class F,
class... Args>
169using invoke_result_t =
typename invoke_result<F, Args...>::type;
190template <
class,
class,
class =
void>
193template <
class Result,
class R>
195 : bool_constant<::std::is_void<R>::value ||
196 ::std::is_convertible<typename Result::type, R>::value> {};
205template <
class F,
class... Args>
214template <
class R,
class F,
class... Args>
227template <
class B1,
class... Bn>
229 : ::std::conditional<static_cast<bool>(B1::value), conjunction<Bn...>,
242template <
class B1,
class... Bn>
244 : ::std::conditional<static_cast<bool>(B1::value), B1,
245 disjunction<Bn...>>::type {};
249struct negation : bool_constant<!static_cast<bool>(B::value)> {};
This header file is part of the Lely libraries; it contains the compiler feature definitions.
invoke_result_t< F, Args... > invoke(F &&f, Args &&... args)
Invokes f with the arguments args... as if by INVOKE(forward<F>(f), forward<Args>(args)....
typename detail::make_void< T... >::type void_t
Utility metafunction that maps a sequence of any types to the type void.
Forms the logical conjunction of the type traits B..., effectively performing a logical AND on the se...
Forms the logical disjunction of the type traits B..., effectively performing a logical OR on the seq...
Deduces the return type of an INVOKE expression at compile time.
Determines whether F can be invoked with the arguments Args... to yield a result that is convertable ...
Determines whether F can be invoked with the arguments Args....
Forms the logical negation of the type trait B.