NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
invoke.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_FUNCTIONAL_INVOKE_HPP__
2#define NEFORCE_CORE_FUNCTIONAL_INVOKE_HPP__
3
10
12NEFORCE_BEGIN_NAMESPACE__
13
15
22struct invoke_memfun_ref_tag {
23 constexpr invoke_memfun_ref_tag() noexcept = default;
24};
25
32struct invoke_memfun_deref_tag {
33 constexpr invoke_memfun_deref_tag() noexcept = default;
34};
35
42struct invoke_memobj_ref_tag {
43 constexpr invoke_memobj_ref_tag() noexcept = default;
44};
45
52struct invoke_memobj_deref_tag {
53 constexpr invoke_memobj_deref_tag() noexcept = default;
54};
55
62struct invoke_other_tag {
63 constexpr invoke_other_tag() noexcept = default;
64};
65
66
75template <typename T, typename Tag>
76struct invoke_result_true {
77 using invoke_type = Tag;
78 using type = T;
79};
80
87struct invoke_result_false {};
88
89
90NEFORCE_BEGIN_INNER__
91
99template <typename MemPtr, typename Arg, typename... Args>
100struct __invoke_result_memfun_ref {
101private:
102 template <typename F, typename T, typename... Args1>
103 static invoke_result_true<decltype((_NEFORCE declval<T>().*_NEFORCE declval<F>())(_NEFORCE declval<Args1>()...)),
104 invoke_memfun_ref_tag>
105 __test(int);
106
107 template <typename...>
108 static invoke_result_false __test(...);
109
110public:
111 using type = decltype(__test<MemPtr, Arg, Args...>(0));
112};
113
121template <typename MemPtr, typename Arg, typename... Args>
122struct __invoke_result_memfun_deref {
123private:
124 template <typename F, typename T, typename... Args1>
125 static invoke_result_true<decltype((*_NEFORCE declval<T>().*_NEFORCE declval<F>())(_NEFORCE declval<Args1>()...)),
126 invoke_memfun_deref_tag>
127 __test(int);
128
129 template <typename...>
130 static invoke_result_false __test(...);
131
132public:
133 using type = decltype(__test<MemPtr, Arg, Args...>(0));
134};
135
142template <typename MemPtr, typename Arg>
143struct __invoke_result_memobj_ref {
144private:
145 template <typename F, typename T>
146 static invoke_result_true<decltype(_NEFORCE declval<T>().*_NEFORCE declval<F>()), invoke_memobj_ref_tag>
147 __test(int);
148
149 template <typename, typename>
150 static invoke_result_false __test(...);
151
152public:
153 using type = decltype(__test<MemPtr, Arg>(0));
154};
155
162template <typename MemPtr, typename Arg>
163struct __invoke_result_memobj_deref {
164private:
165 template <typename F, typename T>
166 static invoke_result_true<decltype(*_NEFORCE declval<T>().*_NEFORCE declval<F>()), invoke_memobj_deref_tag>
167 __test(int);
168
169 template <typename, typename>
170 static invoke_result_false __test(...);
171
172public:
173 using type = decltype(__test<MemPtr, Arg>(0));
174};
175
184template <typename MemPtr, typename Arg>
185struct __invoke_result_memobj;
186
193template <typename Res, typename Class, typename Arg>
194struct __invoke_result_memobj<Res Class::*, Arg> {
195 using Argval = remove_cvref_t<Arg>;
196 using MemPtr = Res Class::*;
197 using type = typename conditional_t<disjunction<is_same<Argval, Class>, is_base_of<Class, Argval>>::value,
198 __invoke_result_memobj_ref<MemPtr, Arg>,
199 __invoke_result_memobj_deref<MemPtr, Arg>>::type;
200};
201
209template <typename MemPtr, typename Arg, typename... Args>
210struct __invoke_result_memfun;
211
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;
225};
226
235template <bool IsMemObj, bool IsMemFun, typename F, typename... Args>
236struct __invoke_result_dispatch {
237 using type = invoke_result_false;
238};
239
241template <typename MemPtr, typename Arg>
242struct __invoke_result_dispatch<true, false, MemPtr, Arg>
243: __invoke_result_memobj<decay_t<MemPtr>, unwrap_reference_t<Arg>> {};
244
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...> {};
249
251template <typename F, typename... Args>
252struct __invoke_result_dispatch<false, false, F, Args...> {
253private:
254 template <typename F1, typename... Args1>
255 static invoke_result_true<decltype(_NEFORCE declval<F1>()(_NEFORCE declval<Args1>()...)), invoke_other_tag>
256 __test(int);
257
258 template <typename...>
259 static invoke_result_false __test(...);
260
261public:
262 using type = decltype(__test<F, Args...>(0));
263};
264
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 {};
275
276NEFORCE_END_INNER__
278
284
293template <typename Sign>
295
301template <typename F, typename... Args>
302struct invoke_result<F(Args...)> : inner::__invoke_result_aux<F, Args...> {};
303
310template <typename F, typename... Args>
311using invoke_result_t = typename inner::__invoke_result_aux<F, Args...>::type;
312
313
315NEFORCE_BEGIN_INNER__
316
325template <typename Result, typename Ret, bool IsVoid = is_void<Ret>::value, typename Dummy = void>
326struct __is_invocable_aux : false_type {};
327
329template <typename Result, typename Ret>
330struct __is_invocable_aux<Result, Ret, true, void_t<typename Result::type>> : true_type {};
331
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)
341#endif
342
344template <typename Result, typename Ret>
345struct __is_invocable_aux<Result, Ret, false, void_t<typename Result::type>> {
346private:
347 using Res_t = typename Result::type;
348
349 template <typename T, bool Nothrow = noexcept(_NEFORCE declvoid<T>(_NEFORCE declval<Res_t>())),
350 typename = decltype(_NEFORCE declvoid<T>(_NEFORCE declval<Res_t>())),
351 bool Dangle =
352#if defined(NEFORCE_COMPILER_GCC) && defined(NEFORCE_PLATFORM_WINDOWS)
353 __reference_converts_from_temporary(T, Res_t)
354#else
355 false
356#endif
357 >
358 static bool_constant<Nothrow && !Dangle> __test(int);
359
360 template <typename T, bool = false>
361 static false_type __test(...);
362
363public:
364 using type = decltype(__test<Ret, true>(1));
365};
366
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)
372# pragma warning(pop)
373#endif
374
375NEFORCE_END_INNER__
377
378
387template <typename F, typename... Args>
388struct is_invocable : inner::__is_invocable_aux<inner::__invoke_result_aux<F, Args...>, void>::type {};
389
390#ifdef NEFORCE_STANDARD_14
395template <typename F, typename... Args>
396NEFORCE_INLINE17 constexpr bool is_invocable_v = is_invocable<F, Args...>::value;
397#endif
398
399
409template <typename Ret, typename F, typename... Args>
410struct is_invocable_r : inner::__is_invocable_aux<inner::__invoke_result_aux<F, Args...>, Ret>::type {};
411
412#ifdef NEFORCE_STANDARD_14
417template <typename Ret, typename F, typename... Args>
418NEFORCE_INLINE17 constexpr bool is_invocable_r_v = is_invocable_r<Ret, F, Args...>::value;
419#endif
420
421
423NEFORCE_BEGIN_INNER__
424
425template <typename F, typename T, typename... Args>
426constexpr bool __invoke_is_nothrow_dispatch(invoke_memfun_ref_tag) {
427 return noexcept((_NEFORCE declval<unwrap_reference_t<T>>().*_NEFORCE declval<F>())(_NEFORCE declval<Args>()...));
428}
429template <typename F, typename T, typename... Args>
430constexpr bool __invoke_is_nothrow_dispatch(invoke_memfun_deref_tag) {
431 return noexcept((*_NEFORCE declval<T>().*_NEFORCE declval<F>())(_NEFORCE declval<Args>()...));
432}
433template <typename F, typename T>
434constexpr bool __invoke_is_nothrow_dispatch(invoke_memobj_ref_tag) {
435 return noexcept(_NEFORCE declval<unwrap_reference_t<T>>().*_NEFORCE declval<F>());
436}
437template <typename F, typename T>
438constexpr bool __invoke_is_nothrow_dispatch(invoke_memobj_deref_tag) {
439 return noexcept(*_NEFORCE declval<T>().*_NEFORCE declval<F>());
440}
441template <typename F, typename... Args>
442constexpr bool __invoke_is_nothrow_dispatch(invoke_other_tag) {
443 return noexcept(_NEFORCE declval<F>()(_NEFORCE declval<Args>()...));
444}
445
453template <typename Result, typename F, typename... Args>
454struct __invoke_is_nothrow : bool_constant<__invoke_is_nothrow_dispatch<F, Args...>(typename Result::invoke_type{})> {};
455
460template <typename F, typename... Args>
461using __bind_invoke_is_nothrow = __invoke_is_nothrow<__invoke_result_aux<F, Args...>, F, Args...>;
462
463NEFORCE_END_INNER__
465
466
475template <typename F, typename... Args>
476struct is_nothrow_invocable : conjunction<is_invocable<F, Args...>, inner::__bind_invoke_is_nothrow<F, Args...>>::type {
477};
478
479#ifdef NEFORCE_STANDARD_14
484template <typename F, typename... Args>
485NEFORCE_INLINE17 constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<F, Args...>::value;
486#endif
487
488
490NEFORCE_BEGIN_INNER__
491
492template <typename T, typename U = unwrap_reference_t<T>>
493constexpr U&& __invoke_forward(remove_reference_t<T>& t) noexcept {
494 return static_cast<U&&>(t);
495}
496
497template <typename Res, typename F, typename... Args>
498NEFORCE_CONSTEXPR14 Res __invoke_dispatch(invoke_other_tag, F&& f, Args&&... args) {
499 return _NEFORCE forward<F>(f)(_NEFORCE forward<Args>(args)...);
500}
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)...);
504}
505template <typename Res, typename MemFun, typename T, typename... Args>
506NEFORCE_CONSTEXPR14 Res __invoke_dispatch(invoke_memfun_deref_tag, MemFun&& f, T&& t, Args&&... args) {
507 return (*_NEFORCE forward<T>(t).*f)(_NEFORCE forward<Args>(args)...);
508}
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;
512}
513template <typename Res, typename MemPtr, typename T>
514NEFORCE_CONSTEXPR14 Res __invoke_dispatch(invoke_memobj_deref_tag, MemPtr&& f, T&& t) {
515 return *_NEFORCE forward<T>(t).*f;
516}
517
518NEFORCE_END_INNER__
520
521
536template <typename Callable, typename... Args>
537NEFORCE_CONSTEXPR14 typename inner::__invoke_result_aux<Callable, Args...>::type
538invoke(Callable&& f, Args&&... args) noexcept(is_nothrow_invocable<Callable, Args...>::value) {
539 using result = inner::__invoke_result_aux<Callable, Args...>;
540 using type = typename result::type;
541 using tag = typename result::invoke_type;
542 return inner::__invoke_dispatch<type>(tag{}, _NEFORCE forward<Callable>(f), _NEFORCE forward<Args>(args)...);
543}
544
545
547NEFORCE_BEGIN_INNER__
548
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) {
552 inner::__invoke_dispatch<T>(Tag{}, _NEFORCE forward<Callable>(f), _NEFORCE forward<Args>(args)...);
553 return;
554}
555
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) {
559 return inner::__invoke_dispatch<T>(Tag{}, _NEFORCE forward<Callable>(f), _NEFORCE forward<Args>(args)...);
560}
561
562NEFORCE_END_INNER__
564
565
577template <typename Res, typename Callable, typename... Args>
578NEFORCE_CONSTEXPR14 enable_if_t<is_invocable_r<Res, Callable, Args...>::value, Res>
579invoke_r(Callable&& f, Args&&... args) noexcept(is_nothrow_invocable<Callable, Args...>::value) {
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),
584 _NEFORCE forward<Args>(args)...);
585}
586 // InvokeFunction
588
589NEFORCE_END_NAMESPACE__
590#endif // NEFORCE_CORE_FUNCTIONAL_INVOKE_HPP__
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
#define NEFORCE_COMPILER_GCC
定义使用GCC编译器编译
add_rvalue_reference_t< T > declval() noexcept
获取类型的右值引用,仅用于非求值上下文
void declvoid(type_identity_t< T >) noexcept
将类型映射为void,仅用于非求值上下文
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的便捷别名
#define NEFORCE_PLATFORM_WINDOWS
定义在Windows平台编译
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的类型
void void_t
将任意类型映射为void
bool_constant< false > false_type
表示false的类型
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
引用包装器
类型集合的逻辑与操作
推导函数调用结果类型的主模板
判断类型是否可调用并返回指定类型
判断类型是否可调用
判断调用是否不会抛出异常