feat update invoke_result
Some checks failed
linux-x64-gcc / linux-gcc (Release) (push) Failing after 3m3s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Failing after 3m22s
linux-arm-gcc / linux-gcc-armhf (push) Failing after 4m11s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Failing after 4m51s
linux-x64-gcc / linux-gcc (Debug) (push) Failing after 5m36s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Failing after 5m44s
Some checks failed
linux-x64-gcc / linux-gcc (Release) (push) Failing after 3m3s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Failing after 3m22s
linux-arm-gcc / linux-gcc-armhf (push) Failing after 4m11s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Failing after 4m51s
linux-x64-gcc / linux-gcc (Debug) (push) Failing after 5m36s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Failing after 5m44s
This commit is contained in:
parent
778d24b8de
commit
5f299117fe
@ -18,162 +18,172 @@ namespace detail {
|
|||||||
#define EGGS_FWD(...) static_cast<decltype(__VA_ARGS__) &&>(__VA_ARGS__)
|
#define EGGS_FWD(...) static_cast<decltype(__VA_ARGS__) &&>(__VA_ARGS__)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
template<typename C, typename T, bool Ref, bool RefWrapper, bool IsFunction = std::is_function<T>::value>
|
template <typename C, typename T, bool Ref, bool RefWrapper,
|
||||||
|
bool IsFunction = std::is_function<T>::value>
|
||||||
struct invoke_mem_ptr;
|
struct invoke_mem_ptr;
|
||||||
|
|
||||||
// when `pm` is a pointer to member of a class `C` and
|
// when `pm` is a pointer to member of a class `C` and
|
||||||
// `is_base_of_v<C, remove_reference_t<T>>` is `true`;
|
// `is_base_of_v<C, remove_reference_t<T>>` is `true`;
|
||||||
template<typename C, typename T>
|
template <typename C, typename T>
|
||||||
struct invoke_mem_ptr<C, T, /*Ref=*/true, /*RefWrapper=*/false, /*IsFunction=*/false> {
|
struct invoke_mem_ptr<C, T, /*Ref=*/true, /*RefWrapper=*/false,
|
||||||
T C::*pm;
|
/*IsFunction=*/false> {
|
||||||
|
T C::*pm;
|
||||||
|
|
||||||
#if !__cpp_aggregate_paren_init
|
#if !__cpp_aggregate_paren_init
|
||||||
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T1>
|
template <typename T1>
|
||||||
constexpr auto operator()(T1 &&t1) const noexcept(noexcept(EGGS_FWD(t1).*pm)) -> decltype(EGGS_FWD(t1).*pm)
|
constexpr auto operator()(T1 &&t1) const
|
||||||
{
|
noexcept(noexcept(EGGS_FWD(t1).*pm)) -> decltype(EGGS_FWD(t1).*pm) {
|
||||||
return EGGS_FWD(t1).*pm;
|
return EGGS_FWD(t1).*pm;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename C, typename T>
|
template <typename C, typename T>
|
||||||
struct invoke_mem_ptr<C, T, /*Ref=*/true, /*RefWrapper=*/false, /*IsFunction=*/true> {
|
struct invoke_mem_ptr<C, T, /*Ref=*/true, /*RefWrapper=*/false,
|
||||||
T C::*pm;
|
/*IsFunction=*/true> {
|
||||||
|
T C::*pm;
|
||||||
|
|
||||||
#if !__cpp_aggregate_paren_init
|
#if !__cpp_aggregate_paren_init
|
||||||
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T1, typename... Tn>
|
template <typename T1, typename... Tn>
|
||||||
constexpr auto operator()(T1 &&t1, Tn &&...tn) const noexcept(noexcept((EGGS_FWD(t1).*pm)(EGGS_FWD(tn)...)))
|
constexpr auto operator()(T1 &&t1, Tn &&...tn) const
|
||||||
-> decltype((EGGS_FWD(t1).*pm)(EGGS_FWD(tn)...))
|
noexcept(noexcept((EGGS_FWD(t1).*pm)(EGGS_FWD(tn)...)))
|
||||||
{
|
-> decltype((EGGS_FWD(t1).*pm)(EGGS_FWD(tn)...)) {
|
||||||
return (EGGS_FWD(t1).*pm)(EGGS_FWD(tn)...);
|
return (EGGS_FWD(t1).*pm)(EGGS_FWD(tn)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// when `pm` is a pointer to member of a class `C` and
|
// when `pm` is a pointer to member of a class `C` and
|
||||||
// `remove_cvref_t<T>` is a specialization of `reference_wrapper`;
|
// `remove_cvref_t<T>` is a specialization of `reference_wrapper`;
|
||||||
template<typename C, typename T>
|
template <typename C, typename T>
|
||||||
struct invoke_mem_ptr<C, T, /*Ref=*/false, /*RefWrapper=*/true, /*IsFunction=*/false> {
|
struct invoke_mem_ptr<C, T, /*Ref=*/false, /*RefWrapper=*/true,
|
||||||
T C::*pm;
|
/*IsFunction=*/false> {
|
||||||
|
T C::*pm;
|
||||||
|
|
||||||
#if !__cpp_aggregate_paren_init
|
#if !__cpp_aggregate_paren_init
|
||||||
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T1>
|
template <typename T1>
|
||||||
constexpr auto operator()(T1 &&t1) const noexcept(noexcept(t1.get().*pm)) -> decltype(t1.get().*pm)
|
constexpr auto operator()(T1 &&t1) const
|
||||||
{
|
noexcept(noexcept(t1.get().*pm)) -> decltype(t1.get().*pm) {
|
||||||
return t1.get().*pm;
|
return t1.get().*pm;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename C, typename T>
|
template <typename C, typename T>
|
||||||
struct invoke_mem_ptr<C, T, /*Ref=*/false, /*RefWrapper=*/true, /*IsFunction=*/true> {
|
struct invoke_mem_ptr<C, T, /*Ref=*/false, /*RefWrapper=*/true,
|
||||||
T C::*pm;
|
/*IsFunction=*/true> {
|
||||||
|
T C::*pm;
|
||||||
|
|
||||||
#if !__cpp_aggregate_paren_init
|
#if !__cpp_aggregate_paren_init
|
||||||
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T1, typename... Tn>
|
template <typename T1, typename... Tn>
|
||||||
constexpr auto operator()(T1 &&t1, Tn &&...tn) const noexcept(noexcept((t1.get().*pm)(EGGS_FWD(tn)...)))
|
constexpr auto operator()(T1 &&t1, Tn &&...tn) const
|
||||||
-> decltype((t1.get().*pm)(EGGS_FWD(tn)...))
|
noexcept(noexcept((t1.get().*pm)(EGGS_FWD(tn)...)))
|
||||||
{
|
-> decltype((t1.get().*pm)(EGGS_FWD(tn)...)) {
|
||||||
return (t1.get().*pm)(EGGS_FWD(tn)...);
|
return (t1.get().*pm)(EGGS_FWD(tn)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// when `pm` is a pointer to member of a class `C` and `T` does not
|
// when `pm` is a pointer to member of a class `C` and `T` does not
|
||||||
// satisfy the previous two items;
|
// satisfy the previous two items;
|
||||||
template<typename C, typename T>
|
template <typename C, typename T>
|
||||||
struct invoke_mem_ptr<C, T, /*Ref=*/false, /*RefWrapper=*/false, /*IsFunction=*/false> {
|
struct invoke_mem_ptr<C, T, /*Ref=*/false, /*RefWrapper=*/false,
|
||||||
T C::*pm;
|
/*IsFunction=*/false> {
|
||||||
|
T C::*pm;
|
||||||
|
|
||||||
#if !__cpp_aggregate_paren_init
|
#if !__cpp_aggregate_paren_init
|
||||||
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T1>
|
template <typename T1>
|
||||||
constexpr auto operator()(T1 &&t1) const noexcept(noexcept((*EGGS_FWD(t1)).*pm)) -> decltype((*EGGS_FWD(t1)).*pm)
|
constexpr auto operator()(T1 &&t1) const
|
||||||
{
|
noexcept(noexcept((*EGGS_FWD(t1)).*pm)) -> decltype((*EGGS_FWD(t1)).*pm) {
|
||||||
return (*EGGS_FWD(t1)).*pm;
|
return (*EGGS_FWD(t1)).*pm;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename C, typename T>
|
template <typename C, typename T>
|
||||||
struct invoke_mem_ptr<C, T, /*Ref=*/false, /*RefWrapper=*/false, /*IsFunction=*/true> {
|
struct invoke_mem_ptr<C, T, /*Ref=*/false, /*RefWrapper=*/false,
|
||||||
T C::*pm;
|
/*IsFunction=*/true> {
|
||||||
|
T C::*pm;
|
||||||
|
|
||||||
#if !__cpp_aggregate_paren_init
|
#if !__cpp_aggregate_paren_init
|
||||||
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
constexpr invoke_mem_ptr(T C::*pm) noexcept : pm(pm) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T1, typename... Tn>
|
template <typename T1, typename... Tn>
|
||||||
constexpr auto operator()(T1 &&t1, Tn &&...tn) const noexcept(noexcept(((*EGGS_FWD(t1)).*pm)(EGGS_FWD(tn)...)))
|
constexpr auto operator()(T1 &&t1, Tn &&...tn) const
|
||||||
-> decltype(((*EGGS_FWD(t1)).*pm)(EGGS_FWD(tn)...))
|
noexcept(noexcept(((*EGGS_FWD(t1)).*pm)(EGGS_FWD(tn)...)))
|
||||||
{
|
-> decltype(((*EGGS_FWD(t1)).*pm)(EGGS_FWD(tn)...)) {
|
||||||
return ((*EGGS_FWD(t1)).*pm)(EGGS_FWD(tn)...);
|
return ((*EGGS_FWD(t1)).*pm)(EGGS_FWD(tn)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
template<typename F>
|
template <typename F> auto invoke(F &&, ...) -> F &&;
|
||||||
auto invoke(F &&, ...) -> F &&;
|
|
||||||
|
|
||||||
template<typename T, typename C, typename T1>
|
template <typename T, typename C, typename T1>
|
||||||
auto invoke(T C::*, T1 const &, ...) -> invoke_mem_ptr<C,
|
auto invoke(T C::*, T1 const &,
|
||||||
T,
|
...) -> invoke_mem_ptr<C, T,
|
||||||
/*Ref=*/std::is_base_of<C, T1>::value,
|
/*Ref=*/std::is_base_of<C, T1>::value,
|
||||||
/*RefWrapper=*/false>;
|
/*RefWrapper=*/false>;
|
||||||
|
|
||||||
template<typename T, typename C, typename X>
|
template <typename T, typename C, typename X>
|
||||||
auto invoke(T C::*, std::reference_wrapper<X>, ...) -> invoke_mem_ptr<C,
|
auto invoke(T C::*, std::reference_wrapper<X>,
|
||||||
T,
|
...) -> invoke_mem_ptr<C, T,
|
||||||
/*Ref=*/false,
|
/*Ref=*/false,
|
||||||
/*RefWrapper=*/true>;
|
/*RefWrapper=*/true>;
|
||||||
|
|
||||||
//! EGGS_INVOKE(F, ...)
|
//! EGGS_INVOKE(F, ...)
|
||||||
//!
|
//!
|
||||||
//! - _Returns_: `INVOKE(F __VA_OPT__(,) __VA_ARGS__)`.
|
//! - _Returns_: `INVOKE(F __VA_OPT__(,) __VA_ARGS__)`.
|
||||||
#if __cplusplus > 201703L// C++20: P0306
|
#if __cplusplus > 201703L // C++20: P0306
|
||||||
#define EGGS_INVOKE(F, ...) \
|
#define EGGS_INVOKE(F, ...) \
|
||||||
(static_cast<decltype(::eggs::detail::invoke(F __VA_OPT__(, ) __VA_ARGS__))>(F)(__VA_ARGS__))
|
(static_cast<decltype(::eggs::detail::invoke( \
|
||||||
|
F __VA_OPT__(, ) __VA_ARGS__))>(F)(__VA_ARGS__))
|
||||||
#elif _MSVC_TRADITIONAL
|
#elif _MSVC_TRADITIONAL
|
||||||
#define EGGS_INVOKE(F, ...) (static_cast<decltype(::eggs::detail::invoke(F, __VA_ARGS__))>(F)(__VA_ARGS__))
|
#define EGGS_INVOKE(F, ...) \
|
||||||
|
(static_cast<decltype(::eggs::detail::invoke(F, __VA_ARGS__))>(F)( \
|
||||||
|
__VA_ARGS__))
|
||||||
#else
|
#else
|
||||||
#define EGGS_INVOKE(F, ...) (static_cast<decltype(::eggs::detail::invoke(F, ##__VA_ARGS__))>(F)(__VA_ARGS__))
|
#define EGGS_INVOKE(F, ...) \
|
||||||
|
(static_cast<decltype(::eggs::detail::invoke(F, ##__VA_ARGS__))>(F)( \
|
||||||
|
__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// `INVOKE(f, t1, t2, ..., tN)` implicitly converted to `R`.
|
// `INVOKE(f, t1, t2, ..., tN)` implicitly converted to `R`.
|
||||||
template<typename R, typename RD = typename std::remove_cv<R>::type>
|
template <typename R, typename RD = typename std::remove_cv<R>::type>
|
||||||
struct invoke_r {
|
struct invoke_r {
|
||||||
private:
|
private:
|
||||||
static R conversion(R) noexcept;
|
static R conversion(R) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename F, typename... Args>
|
template <typename F, typename... Args>
|
||||||
static constexpr auto
|
static constexpr auto call(F &&f, Args &&...args) noexcept(
|
||||||
call(F &&f, Args &&...args) noexcept(noexcept(conversion(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...))))
|
noexcept(conversion(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...))))
|
||||||
-> decltype(conversion(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...)))
|
-> decltype(conversion(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...))) {
|
||||||
{
|
return EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...);
|
||||||
return EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...);
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// `static_cast<void>(INVOKE(f, t1, t2, ..., tN))` if `R` is _cv_ `void`.
|
// `static_cast<void>(INVOKE(f, t1, t2, ..., tN))` if `R` is _cv_ `void`.
|
||||||
template<typename R>
|
template <typename R> struct invoke_r<R, void> {
|
||||||
struct invoke_r<R, void> {
|
template <typename F, typename... Args>
|
||||||
template<typename F, typename... Args>
|
static constexpr auto call(F &&f, Args &&...args) noexcept(
|
||||||
static constexpr auto call(F &&f, Args &&...args) noexcept(noexcept(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...)))
|
noexcept(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...)))
|
||||||
-> decltype(static_cast<void>(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...)))
|
-> decltype(static_cast<void>(EGGS_INVOKE(EGGS_FWD(f),
|
||||||
{
|
EGGS_FWD(args)...))) {
|
||||||
return static_cast<void>(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...));
|
return static_cast<void>(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//! EGGS_INVOKE(R, F, ...)
|
//! EGGS_INVOKE(R, F, ...)
|
||||||
@ -181,20 +191,21 @@ struct invoke_r<R, void> {
|
|||||||
//! - _Returns_: `INVOKE<R>(F __VA_OPT__(,) __VA_ARGS__)`.
|
//! - _Returns_: `INVOKE<R>(F __VA_OPT__(,) __VA_ARGS__)`.
|
||||||
#define EGGS_INVOKE_R(R, ...) (::eggs::detail::invoke_r<R>::call(__VA_ARGS__))
|
#define EGGS_INVOKE_R(R, ...) (::eggs::detail::invoke_r<R>::call(__VA_ARGS__))
|
||||||
|
|
||||||
}// namespace detail
|
} // namespace detail
|
||||||
}// namespace eggs
|
} // namespace eggs
|
||||||
|
|
||||||
namespace eggs {
|
namespace eggs {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, typename Enable = void>
|
template <typename T, typename Enable = void> struct invoke_result_impl {};
|
||||||
struct invoke_result_impl {};
|
|
||||||
|
|
||||||
template<typename F, typename... Ts>
|
template <typename F, typename... Ts>
|
||||||
struct invoke_result_impl<F(Ts...), decltype((void) EGGS_INVOKE(std::declval<F>(), std::declval<Ts>()...))> {
|
struct invoke_result_impl<F(Ts...),
|
||||||
using type = decltype(EGGS_INVOKE(std::declval<F>(), std::declval<Ts>()...));
|
decltype((void)EGGS_INVOKE(std::declval<F>(),
|
||||||
|
std::declval<Ts>()...))> {
|
||||||
|
using type = decltype(EGGS_INVOKE(std::declval<F>(), std::declval<Ts>()...));
|
||||||
};
|
};
|
||||||
}// namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
//! template <class Fn, class... ArgTypes> struct invoke_result;
|
//! template <class Fn, class... ArgTypes> struct invoke_result;
|
||||||
//!
|
//!
|
||||||
@ -209,23 +220,25 @@ struct invoke_result_impl<F(Ts...), decltype((void) EGGS_INVOKE(std::declval<F>(
|
|||||||
//! - _Preconditions_: `Fn` and all types in the template parameter pack
|
//! - _Preconditions_: `Fn` and all types in the template parameter pack
|
||||||
//! `ArgTypes` are complete types, _cv_ `void`, or arrays of unknown
|
//! `ArgTypes` are complete types, _cv_ `void`, or arrays of unknown
|
||||||
//! bound.
|
//! bound.
|
||||||
template<typename Fn, typename... ArgTypes>
|
template <typename Fn, typename... ArgTypes>
|
||||||
struct invoke_result : detail::invoke_result_impl<Fn && (ArgTypes && ...)> {};
|
struct invoke_result : detail::invoke_result_impl<Fn && (ArgTypes && ...)> {};
|
||||||
|
|
||||||
//! template <class Fn, class... ArgTypes>
|
//! template <class Fn, class... ArgTypes>
|
||||||
//! using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
|
//! using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
|
||||||
template<typename Fn, typename... ArgTypes>
|
template <typename Fn, typename... ArgTypes>
|
||||||
using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
|
using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, typename Enable = void>
|
template <typename T, typename Enable = void>
|
||||||
struct is_invocable_impl : std::false_type {};
|
struct is_invocable_impl : std::false_type {};
|
||||||
|
|
||||||
template<typename F, typename... Ts>
|
template <typename F, typename... Ts>
|
||||||
struct is_invocable_impl<F(Ts...), decltype((void) EGGS_INVOKE(std::declval<F>(), std::declval<Ts>()...))>
|
struct is_invocable_impl<F(Ts...),
|
||||||
|
decltype((void)EGGS_INVOKE(std::declval<F>(),
|
||||||
|
std::declval<Ts>()...))>
|
||||||
: std::true_type {};
|
: std::true_type {};
|
||||||
}// namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
//! template <class Fn, class... ArgTypes> struct is_invocable;
|
//! template <class Fn, class... ArgTypes> struct is_invocable;
|
||||||
//!
|
//!
|
||||||
@ -236,14 +249,15 @@ struct is_invocable_impl<F(Ts...), decltype((void) EGGS_INVOKE(std::declval<F>()
|
|||||||
//! - _Comments_: `Fn` and all types in the template parameter pack
|
//! - _Comments_: `Fn` and all types in the template parameter pack
|
||||||
//! `ArgTypes` shall be complete types, _cv_ `void`, or arrays of
|
//! `ArgTypes` shall be complete types, _cv_ `void`, or arrays of
|
||||||
//! unknown bound.
|
//! unknown bound.
|
||||||
template<typename Fn, typename... ArgTypes>
|
template <typename Fn, typename... ArgTypes>
|
||||||
struct is_invocable : detail::is_invocable_impl<Fn && (ArgTypes && ...)>::type {};
|
struct is_invocable : detail::is_invocable_impl<Fn && (ArgTypes && ...)>::type {
|
||||||
|
};
|
||||||
|
|
||||||
#if __cpp_variable_templates
|
#if __cpp_variable_templates
|
||||||
//! template <class Fn, class... ArgTypes> // (C++14)
|
//! template <class Fn, class... ArgTypes> // (C++14)
|
||||||
//! inline constexpr bool is_invocable_v =
|
//! inline constexpr bool is_invocable_v =
|
||||||
//! eggs::is_invocable<Fn, ArgTypes...>::value;
|
//! eggs::is_invocable<Fn, ArgTypes...>::value;
|
||||||
template<typename Fn, typename... ArgTypes>
|
template <typename Fn, typename... ArgTypes>
|
||||||
#if __cpp_inline_variables
|
#if __cpp_inline_variables
|
||||||
inline
|
inline
|
||||||
#endif
|
#endif
|
||||||
@ -252,13 +266,15 @@ inline
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, typename R, typename Enable = void>
|
template <typename T, typename R, typename Enable = void>
|
||||||
struct is_invocable_r_impl : std::false_type {};
|
struct is_invocable_r_impl : std::false_type {};
|
||||||
|
|
||||||
template<typename F, typename... Ts, typename R>
|
template <typename F, typename... Ts, typename R>
|
||||||
struct is_invocable_r_impl<F(Ts...), R, decltype((void) EGGS_INVOKE_R(R, std::declval<F>(), std::declval<Ts>()...))>
|
struct is_invocable_r_impl<F(Ts...), R,
|
||||||
|
decltype((void)EGGS_INVOKE_R(R, std::declval<F>(),
|
||||||
|
std::declval<Ts>()...))>
|
||||||
: std::true_type {};
|
: std::true_type {};
|
||||||
}// namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
//! template <class R, class Fn, class... ArgTypes> struct is_invocable_r;
|
//! template <class R, class Fn, class... ArgTypes> struct is_invocable_r;
|
||||||
//!
|
//!
|
||||||
@ -269,14 +285,15 @@ struct is_invocable_r_impl<F(Ts...), R, decltype((void) EGGS_INVOKE_R(R, std::de
|
|||||||
//! - _Comments_: `Fn`, `R`, and all types in the template parameter pack
|
//! - _Comments_: `Fn`, `R`, and all types in the template parameter pack
|
||||||
//! `ArgTypes` shall be complete types, _cv_ `void`, or arrays of
|
//! `ArgTypes` shall be complete types, _cv_ `void`, or arrays of
|
||||||
//! unknown bound.
|
//! unknown bound.
|
||||||
template<typename R, typename Fn, typename... ArgTypes>
|
template <typename R, typename Fn, typename... ArgTypes>
|
||||||
struct is_invocable_r : detail::is_invocable_r_impl<Fn && (ArgTypes && ...), R>::type {};
|
struct is_invocable_r
|
||||||
|
: detail::is_invocable_r_impl<Fn && (ArgTypes && ...), R>::type {};
|
||||||
|
|
||||||
#if __cpp_variable_templates
|
#if __cpp_variable_templates
|
||||||
//! template <class R, class Fn, class... ArgTypes> // (C++14)
|
//! template <class R, class Fn, class... ArgTypes> // (C++14)
|
||||||
//! inline constexpr bool is_invocable_r_v =
|
//! inline constexpr bool is_invocable_r_v =
|
||||||
//! eggs::is_invocable_r<R, Fn, ArgTypes...>::value;
|
//! eggs::is_invocable_r<R, Fn, ArgTypes...>::value;
|
||||||
template<typename R, typename Fn, typename... ArgTypes>
|
template <typename R, typename Fn, typename... ArgTypes>
|
||||||
#if __cpp_inline_variables
|
#if __cpp_inline_variables
|
||||||
inline
|
inline
|
||||||
#endif
|
#endif
|
||||||
@ -285,13 +302,17 @@ inline
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, typename Enable = void>
|
template <typename T, typename Enable = void>
|
||||||
struct is_nothrow_invocable_impl : std::false_type {};
|
struct is_nothrow_invocable_impl : std::false_type {};
|
||||||
|
|
||||||
template<typename F, typename... Ts>
|
template <typename F, typename... Ts>
|
||||||
struct is_nothrow_invocable_impl<F(Ts...), decltype((void) EGGS_INVOKE(std::declval<F>(), std::declval<Ts>()...))>
|
struct is_nothrow_invocable_impl<F(Ts...),
|
||||||
: std::integral_constant<bool, noexcept(EGGS_INVOKE(std::declval<F>(), std::declval<Ts>()...))> {};
|
decltype((void)EGGS_INVOKE(
|
||||||
}// namespace detail
|
std::declval<F>(), std::declval<Ts>()...))>
|
||||||
|
: std::integral_constant<bool,
|
||||||
|
noexcept(EGGS_INVOKE(std::declval<F>(),
|
||||||
|
std::declval<Ts>()...))> {};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
//! template <class Fn, class... ArgTypes> struct is_nothrow_invocable;
|
//! template <class Fn, class... ArgTypes> struct is_nothrow_invocable;
|
||||||
//!
|
//!
|
||||||
@ -302,53 +323,60 @@ struct is_nothrow_invocable_impl<F(Ts...), decltype((void) EGGS_INVOKE(std::decl
|
|||||||
//! - _Comments_: `Fn` and all types in the template parameter pack
|
//! - _Comments_: `Fn` and all types in the template parameter pack
|
||||||
//! `ArgTypes` shall be complete types, _cv_ `void`, or arrays of
|
//! `ArgTypes` shall be complete types, _cv_ `void`, or arrays of
|
||||||
//! unknown bound.
|
//! unknown bound.
|
||||||
template<typename Fn, typename... ArgTypes>
|
template <typename Fn, typename... ArgTypes>
|
||||||
struct is_nothrow_invocable : detail::is_nothrow_invocable_impl<Fn && (ArgTypes && ...)>::type {};
|
struct is_nothrow_invocable
|
||||||
|
: detail::is_nothrow_invocable_impl<Fn && (ArgTypes && ...)>::type {};
|
||||||
|
|
||||||
#if __cpp_variable_templates
|
#if __cpp_variable_templates
|
||||||
//! template <class Fn, class... ArgTypes> // (C++14)
|
//! template <class Fn, class... ArgTypes> // (C++14)
|
||||||
//! inline constexpr bool is_nothrow_invocable_v =
|
//! inline constexpr bool is_nothrow_invocable_v =
|
||||||
//! eggs::is_nothrow_invocable<Fn, ArgTypes...>::value;
|
//! eggs::is_nothrow_invocable<Fn, ArgTypes...>::value;
|
||||||
template<typename Fn, typename... ArgTypes>
|
template <typename Fn, typename... ArgTypes>
|
||||||
#if __cpp_inline_variables
|
#if __cpp_inline_variables
|
||||||
inline
|
inline
|
||||||
#endif
|
#endif
|
||||||
constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<Fn, ArgTypes...>::value;
|
constexpr bool is_nothrow_invocable_v =
|
||||||
|
is_nothrow_invocable<Fn, ArgTypes...>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, typename R, typename Enable = void>
|
template <typename T, typename R, typename Enable = void>
|
||||||
struct is_nothrow_invocable_r_impl : std::false_type {};
|
struct is_nothrow_invocable_r_impl : std::false_type {};
|
||||||
|
|
||||||
template<typename F, typename... Ts, typename R>
|
template <typename F, typename... Ts, typename R>
|
||||||
struct is_nothrow_invocable_r_impl<F(Ts...),
|
struct is_nothrow_invocable_r_impl<
|
||||||
R,
|
F(Ts...), R,
|
||||||
decltype((void) EGGS_INVOKE_R(R, std::declval<F>(), std::declval<Ts>()...))>
|
decltype((void)EGGS_INVOKE_R(R, std::declval<F>(), std::declval<Ts>()...))>
|
||||||
: std::integral_constant<bool, noexcept(EGGS_INVOKE_R(R, std::declval<F>(), std::declval<Ts>()...))> {};
|
: std::integral_constant<bool,
|
||||||
}// namespace detail
|
noexcept(EGGS_INVOKE_R(R, std::declval<F>(),
|
||||||
|
std::declval<Ts>()...))> {};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
//! template <class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
|
//! template <class R, class Fn, class... ArgTypes> struct
|
||||||
|
//! is_nothrow_invocable_r;
|
||||||
//!
|
//!
|
||||||
//! - _Condition_: `eggs::is_invocable_r_v<R, Fn, ArgTypes...>` is `true`
|
//! - _Condition_: `eggs::is_invocable_r_v<R, Fn, ArgTypes...>` is `true`
|
||||||
//! and the expression `INVOKE(std::declval<Fn>(), std::declval<ArgTypes>()...)`
|
//! and the expression `INVOKE(std::declval<Fn>(),
|
||||||
//! is known not to throw any exceptions.
|
//! std::declval<ArgTypes>()...)` is known not to throw any exceptions.
|
||||||
//!
|
//!
|
||||||
//! - _Comments_: `Fn`, `R`, and all types in the template parameter pack
|
//! - _Comments_: `Fn`, `R`, and all types in the template parameter pack
|
||||||
//! `ArgTypes` shall be complete types, _cv_ `void`, or arrays of
|
//! `ArgTypes` shall be complete types, _cv_ `void`, or arrays of
|
||||||
//! unknown bound.
|
//! unknown bound.
|
||||||
template<typename R, typename Fn, typename... ArgTypes>
|
template <typename R, typename Fn, typename... ArgTypes>
|
||||||
struct is_nothrow_invocable_r : detail::is_nothrow_invocable_r_impl<Fn && (ArgTypes && ...), R>::type {};
|
struct is_nothrow_invocable_r
|
||||||
|
: detail::is_nothrow_invocable_r_impl<Fn && (ArgTypes && ...), R>::type {};
|
||||||
|
|
||||||
#if __cpp_variable_templates
|
#if __cpp_variable_templates
|
||||||
//! template <class R, class Fn, class... ArgTypes> // (C++14)
|
//! template <class R, class Fn, class... ArgTypes> // (C++14)
|
||||||
//! inline constexpr bool is_nothrow_invocable_r_v =
|
//! inline constexpr bool is_nothrow_invocable_r_v =
|
||||||
//! eggs::is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
|
//! eggs::is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
|
||||||
template<typename R, typename Fn, typename... ArgTypes>
|
template <typename R, typename Fn, typename... ArgTypes>
|
||||||
#if __cpp_inline_variables
|
#if __cpp_inline_variables
|
||||||
inline
|
inline
|
||||||
#endif
|
#endif
|
||||||
constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
|
constexpr bool is_nothrow_invocable_r_v =
|
||||||
|
is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -360,12 +388,11 @@ inline
|
|||||||
//!
|
//!
|
||||||
//! - _Remarks_: This function shall not participate in overload resolution
|
//! - _Remarks_: This function shall not participate in overload resolution
|
||||||
//! unless `eggs::is_invocable_v<F, Args...>` is `true`.
|
//! unless `eggs::is_invocable_v<F, Args...>` is `true`.
|
||||||
template<typename Fn, typename... ArgTypes>
|
template <typename Fn, typename... ArgTypes>
|
||||||
constexpr auto
|
constexpr auto invoke(Fn &&f, ArgTypes &&...args) noexcept(
|
||||||
invoke(Fn &&f, ArgTypes &&...args) noexcept(noexcept(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...)))
|
noexcept(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...)))
|
||||||
-> decltype(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...))
|
-> decltype(EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...)) {
|
||||||
{
|
return EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...);
|
||||||
return EGGS_INVOKE(EGGS_FWD(f), EGGS_FWD(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -377,15 +404,17 @@ invoke(Fn &&f, ArgTypes &&...args) noexcept(noexcept(EGGS_INVOKE(EGGS_FWD(f), EG
|
|||||||
//!
|
//!
|
||||||
//! - _Remarks_: This function shall not participate in overload resolution
|
//! - _Remarks_: This function shall not participate in overload resolution
|
||||||
//! unless `eggs::is_invocable_r_v<R, F, Args...>` is `true`.
|
//! unless `eggs::is_invocable_r_v<R, F, Args...>` is `true`.
|
||||||
template<typename R, typename Fn, typename... ArgTypes>
|
template <typename R, typename Fn, typename... ArgTypes>
|
||||||
constexpr auto
|
constexpr auto invoke_r(Fn &&f, ArgTypes &&...args) noexcept(
|
||||||
invoke_r(Fn &&f, ArgTypes &&...args) noexcept(noexcept(EGGS_INVOKE_R(R, EGGS_FWD(f), EGGS_FWD(args)...)))
|
noexcept(EGGS_INVOKE_R(R, EGGS_FWD(f), EGGS_FWD(args)...)))
|
||||||
-> decltype(EGGS_INVOKE_R(R, EGGS_FWD(f), EGGS_FWD(args)...))
|
-> decltype(EGGS_INVOKE_R(R, EGGS_FWD(f), EGGS_FWD(args)...)) {
|
||||||
{
|
return EGGS_INVOKE_R(R, EGGS_FWD(f), EGGS_FWD(args)...);
|
||||||
return EGGS_INVOKE_R(R, EGGS_FWD(f), EGGS_FWD(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef EGGS_FWD
|
#undef EGGS_FWD
|
||||||
}// namespace eggs
|
} // namespace eggs
|
||||||
|
|
||||||
|
namespace tile {
|
||||||
|
using namespace eggs;
|
||||||
|
}
|
||||||
#endif /*EGGS_INVOKE_HPP*/
|
#endif /*EGGS_INVOKE_HPP*/
|
||||||
|
Loading…
Reference in New Issue
Block a user