1#ifndef NEFORCE_CORE_FUNCTIONAL_INVOKE_HPP__
2#define NEFORCE_CORE_FUNCTIONAL_INVOKE_HPP__
12NEFORCE_BEGIN_NAMESPACE__
22struct invoke_memfun_ref_tag {
23 constexpr invoke_memfun_ref_tag() noexcept = default;
32struct invoke_memfun_deref_tag {
33 constexpr invoke_memfun_deref_tag() noexcept = default;
42struct invoke_memobj_ref_tag {
43 constexpr invoke_memobj_ref_tag() noexcept = default;
52struct invoke_memobj_deref_tag {
53 constexpr invoke_memobj_deref_tag() noexcept = default;
62struct invoke_other_tag {
63 constexpr invoke_other_tag() noexcept = default;
75template <typename T, typename Tag>
76struct invoke_result_true {
77 using invoke_type = Tag;
87struct invoke_result_false {};
99template <
typename MemPtr,
typename Arg,
typename... Args>
100struct __invoke_result_memfun_ref {
102 template <
typename F,
typename T,
typename... Args1>
104 invoke_memfun_ref_tag>
107 template <
typename...>
108 static invoke_result_false __test(...);
111 using type =
decltype(__test<MemPtr, Arg, Args...>(0));
121template <
typename MemPtr,
typename Arg,
typename... Args>
122struct __invoke_result_memfun_deref {
124 template <
typename F,
typename T,
typename... Args1>
126 invoke_memfun_deref_tag>
129 template <
typename...>
130 static invoke_result_false __test(...);
133 using type =
decltype(__test<MemPtr, Arg, Args...>(0));
142template <
typename MemPtr,
typename Arg>
143struct __invoke_result_memobj_ref {
145 template <
typename F,
typename T>
146 static invoke_result_true<decltype(_NEFORCE declval<T>().*_NEFORCE
declval<F>()), invoke_memobj_ref_tag>
149 template <
typename,
typename>
150 static invoke_result_false __test(...);
153 using type =
decltype(__test<MemPtr, Arg>(0));
162template <
typename MemPtr,
typename Arg>
163struct __invoke_result_memobj_deref {
165 template <
typename F,
typename T>
166 static invoke_result_true<decltype(*_NEFORCE declval<T>().*_NEFORCE
declval<F>()), invoke_memobj_deref_tag>
169 template <
typename,
typename>
170 static invoke_result_false __test(...);
173 using type =
decltype(__test<MemPtr, Arg>(0));
184template <
typename MemPtr,
typename Arg>
185struct __invoke_result_memobj;
193template <
typename Res,
typename Class,
typename Arg>
194struct __invoke_result_memobj<Res Class::*, Arg> {
196 using MemPtr = Res Class::*;
198 __invoke_result_memobj_ref<MemPtr, Arg>,
199 __invoke_result_memobj_deref<MemPtr, Arg>>::type;
209template <
typename MemPtr,
typename Arg,
typename... Args>
210struct __invoke_result_memfun;
219template <
typename Res,
typename Class,
typename Arg,
typename... Args>
220struct __invoke_result_memfun<Res Class::*, Arg, Args...> {
221 using MemPtr = Res Class::*;
223 __invoke_result_memfun_ref<MemPtr, Arg, Args...>,
224 __invoke_result_memfun_deref<MemPtr, Arg, Args...>>::type;
235template <
bool IsMemObj,
bool IsMemFun,
typename F,
typename... Args>
236struct __invoke_result_dispatch {
237 using type = invoke_result_false;
241template <
typename MemPtr,
typename Arg>
242struct __invoke_result_dispatch<true, false, MemPtr, Arg>
243: __invoke_result_memobj<decay_t<MemPtr>, unwrap_reference_t<Arg>> {};
246template <
typename MemPtr,
typename Arg,
typename... Args>
247struct __invoke_result_dispatch<false, true, MemPtr, Arg, Args...>
248: __invoke_result_memfun<decay_t<MemPtr>, unwrap_reference_t<Arg>, Args...> {};
251template <
typename F,
typename... Args>
252struct __invoke_result_dispatch<false, false, F, Args...> {
254 template <
typename F1,
typename... Args1>
255 static invoke_result_true<decltype(_NEFORCE declval<F1>()(_NEFORCE
declval<Args1>()...)), invoke_other_tag>
258 template <
typename...>
259 static invoke_result_false __test(...);
262 using type =
decltype(__test<F, Args...>(0));
271template <
typename F,
typename... Args>
272struct __invoke_result_aux
273: __invoke_result_dispatch<is_member_object_pointer<remove_reference_t<F>>::value,
274 is_member_function_pointer<remove_reference_t<F>>::value, F, Args...>::type {};
293template <
typename Sign>
301template <
typename F,
typename... Args>
302struct invoke_result<F(Args...)> : inner::__invoke_result_aux<F, Args...> {};
310template <
typename F,
typename... Args>
325template <typename Result, typename Ret, bool IsVoid = is_void<Ret>::value,
typename Dummy =
void>
329template <
typename Result,
typename Ret>
330struct __is_invocable_aux<Result, Ret, true,
void_t<typename Result::type>> :
true_type {};
332#ifdef NEFORCE_COMPILER_GCC
333# pragma GCC diagnostic push
334# pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
335#elif defined(NEFORCE_COMPILER_CLANG)
336# pragma clang diagnostic push
337# pragma clang diagnostic ignored "-Wctor-dtor-privacy"
338#elif defined(NEFORCE_COMPILER_MSVC)
339# pragma warning(push)
340# pragma warning(disable : 4624)
344template <
typename Result,
typename Ret>
345struct __is_invocable_aux<Result, Ret, false,
void_t<typename Result::type>> {
347 using Res_t =
typename Result::type;
349 template <typename T, bool Nothrow = noexcept(_NEFORCE declvoid<T>(_NEFORCE
declval<Res_t>())),
353 __reference_converts_from_temporary(T, Res_t)
360 template <
typename T,
bool = false>
364 using type =
decltype(__test<Ret, true>(1));
367#ifdef NEFORCE_COMPILER_CLANG
368# pragma clang diagnostic pop
369#elif defined(NEFORCE_COMPILER_GCC)
370# pragma GCC diagnostic pop
371#elif defined(NEFORCE_COMPILER_MSVC)
387template <
typename F,
typename... Args>
388struct is_invocable : inner::__is_invocable_aux<inner::__invoke_result_aux<F, Args...>, void>::type {};
390#ifdef NEFORCE_STANDARD_14
395template <
typename F,
typename... Args>
409template <
typename Ret,
typename F,
typename... Args>
410struct is_invocable_r : inner::__is_invocable_aux<inner::__invoke_result_aux<F, Args...>, Ret>::type {};
412#ifdef NEFORCE_STANDARD_14
417template <
typename Ret,
typename F,
typename... Args>
425template <
typename F,
typename T,
typename... Args>
426constexpr bool __invoke_is_nothrow_dispatch(invoke_memfun_ref_tag) {
429template <
typename F,
typename T,
typename... Args>
430constexpr bool __invoke_is_nothrow_dispatch(invoke_memfun_deref_tag) {
433template <
typename F,
typename T>
434constexpr bool __invoke_is_nothrow_dispatch(invoke_memobj_ref_tag) {
437template <
typename F,
typename T>
438constexpr bool __invoke_is_nothrow_dispatch(invoke_memobj_deref_tag) {
441template <
typename F,
typename... Args>
442constexpr bool __invoke_is_nothrow_dispatch(invoke_other_tag) {
453template <
typename Result,
typename F,
typename... Args>
454struct __invoke_is_nothrow :
bool_constant<__invoke_is_nothrow_dispatch<F, Args...>(typename Result::invoke_type{})> {};
460template <
typename F,
typename... Args>
461using __bind_invoke_is_nothrow = __invoke_is_nothrow<__invoke_result_aux<F, Args...>, F, Args...>;
475template <
typename F,
typename... Args>
479#ifdef NEFORCE_STANDARD_14
484template <
typename F,
typename... Args>
492template <
typename T,
typename U = unwrap_reference_t<T>>
494 return static_cast<U&&
>(t);
497template <
typename Res,
typename F,
typename... Args>
498NEFORCE_CONSTEXPR14 Res __invoke_dispatch(invoke_other_tag, F&& f, Args&&... args) {
501template <
typename Res,
typename MemFun,
typename T,
typename... Args>
502NEFORCE_CONSTEXPR14 Res __invoke_dispatch(invoke_memfun_ref_tag, MemFun&& f, T&& t, Args&&... args) {
503 return (inner::__invoke_forward<T>(t).*f)(_NEFORCE
forward<Args>(args)...);
505template <
typename Res,
typename MemFun,
typename T,
typename... Args>
506NEFORCE_CONSTEXPR14 Res __invoke_dispatch(invoke_memfun_deref_tag, MemFun&& f, T&& t, Args&&... args) {
509template <
typename Res,
typename MemPtr,
typename T>
510NEFORCE_CONSTEXPR14 Res __invoke_dispatch(invoke_memobj_ref_tag, MemPtr&& f, T&& t) {
511 return inner::__invoke_forward<T>(t).*f;
513template <
typename Res,
typename MemPtr,
typename T>
514NEFORCE_CONSTEXPR14 Res __invoke_dispatch(invoke_memobj_deref_tag, MemPtr&& f, T&& t) {
536template <
typename Callable,
typename... Args>
537NEFORCE_CONSTEXPR14
typename inner::__invoke_result_aux<Callable, Args...>::type
539 using result = inner::__invoke_result_aux<Callable, Args...>;
540 using type =
typename result::type;
541 using tag =
typename result::invoke_type;
549template <
typename T,
typename Tag,
typename Res,
typename Callable,
typename... Args>
550NEFORCE_CONSTEXPR14
enable_if_t<is_invocable_r<Res, Callable, Args...>::value && is_void<Res>::value, Res>
551__invoke_r_dispatch(Callable&& f, Args&&... args)
noexcept(is_nothrow_invocable<Callable, Args...>::value) {
556template <
typename T,
typename Tag,
typename Res,
typename Callable,
typename... Args>
557NEFORCE_CONSTEXPR14
enable_if_t<is_invocable_r<Res, Callable, Args...>::value && !is_void<Res>::value, Res>
558__invoke_r_dispatch(Callable&& f, Args&&... args)
noexcept(is_nothrow_invocable<Callable, Args...>::value) {
577template <
typename Res,
typename Callable,
typename... Args>
578NEFORCE_CONSTEXPR14
enable_if_t<is_invocable_r<Res, Callable, Args...>::value, Res>
580 using result = inner::__invoke_result_aux<Callable, Args...>;
581 using type =
typename result::type;
582 using tag =
typename result::invoke_type;
583 return inner::__invoke_r_dispatch<type, tag, Res, Callable, Args...>(_NEFORCE
forward<Callable>(f),
589NEFORCE_END_NAMESPACE__
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
#define NEFORCE_COMPILER_GCC
定义使用GCC编译器编译
NEFORCE_INLINE17 constexpr bool is_nothrow_invocable_v
is_nothrow_invocable的便捷变量模板
NEFORCE_CONSTEXPR14 enable_if_t< is_invocable_r< Res, Callable, Args... >::value, Res > invoke_r(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
带返回类型检查的统一调用接口
NEFORCE_CONSTEXPR14 inner::__invoke_result_aux< Callable, Args... >::type invoke(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
统一调用接口
NEFORCE_INLINE17 constexpr bool is_invocable_v
is_invocable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_invocable_r_v
is_invocable_r的便捷变量模板
typename inner::__invoke_result_aux< F, Args... >::type invoke_result_t
invoke_result的便捷别名
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
typename remove_reference< T >::type remove_reference_t
remove_reference的便捷别名
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
bool_constant< true > true_type
表示true的类型
bool_constant< false > false_type
表示false的类型
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名