MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
invoke.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_FUNCTIONAL_INVOKE_HPP__
2#define MSTL_CORE_FUNCTIONAL_INVOKE_HPP__
3
10
13
19
26struct invoke_memfun_ref_tag {
27 constexpr invoke_memfun_ref_tag() noexcept = default;
28};
29
36struct invoke_memfun_deref_tag {
37 constexpr invoke_memfun_deref_tag() noexcept = default;
38};
39
46struct invoke_memobj_ref_tag {
47 constexpr invoke_memobj_ref_tag() noexcept = default;
48};
49
56struct invoke_memobj_deref_tag {
57 constexpr invoke_memobj_deref_tag() noexcept = default;
58};
59
66struct invoke_other_tag {
67 constexpr invoke_other_tag() noexcept = default;
68};
69 // InvokeTags
71
77
86template <typename Sign>
88
97template <typename T, typename Tag>
99 using invoke_type = Tag;
100 using type = T;
101};
102
110
111
114
122template <typename MemPtr, typename Arg, typename... Args>
123struct __invoke_result_memfun_ref {
124private:
125 template <typename F, typename T, typename... Args1>
127 invoke_memfun_ref_tag> __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
143template <typename MemPtr, typename Arg, typename... Args>
144struct __invoke_result_memfun_deref {
145private:
146 template <typename F, typename T, typename... Args1>
147 static invoke_result_true<decltype((*_MSTL declval<T>().*_MSTL declval<F>())(_MSTL declval<Args1>()...)),
148 invoke_memfun_deref_tag> __test(int);
149
150 template <typename...>
151 static invoke_result_false __test(...);
152
153public:
154 using type = decltype(__test<MemPtr, Arg, Args...>(0));
155};
156
163template <typename MemPtr, typename Arg>
164struct __invoke_result_memobj_ref {
165private:
166 template <typename F, typename T>
168 invoke_memobj_ref_tag> __test(int);
169
170 template <typename, typename>
171 static invoke_result_false __test(...);
172
173public:
174 using type = decltype(__test<MemPtr, Arg>(0));
175};
176
183template <typename MemPtr, typename Arg>
184struct __invoke_result_memobj_deref {
185private:
186 template <typename F, typename T>
188 invoke_memobj_deref_tag> __test(int);
189
190 template <typename, typename>
191 static invoke_result_false __test(...);
192
193public:
194 using type = decltype(__test<MemPtr, Arg>(0));
195};
196
205template <typename MemPtr, typename Arg>
206struct __invoke_result_memobj;
207
214template <typename Res, typename Class, typename Arg>
215struct __invoke_result_memobj<Res Class::*, Arg> {
216 using Argval = remove_cvref_t<Arg>;
217 using MemPtr = Res Class::*;
218 using type = typename conditional_t<disjunction<
220 __invoke_result_memobj_ref<MemPtr, Arg>,
221 __invoke_result_memobj_deref<MemPtr, Arg>>::type;
222};
223
231template <typename MemPtr, typename Arg, typename... Args>
232struct __invoke_result_memfun;
233
241template <typename Res, typename Class, typename Arg, typename... Args>
242struct __invoke_result_memfun<Res Class::*, Arg, Args...> {
243 using MemPtr = Res Class::*;
245 __invoke_result_memfun_ref<MemPtr, Arg, Args...>,
246 __invoke_result_memfun_deref<MemPtr, Arg, Args...>>::type;
247};
248
257template <bool IsMemObj, bool IsMemFun, typename F, typename... Args>
258struct __invoke_result_dispatch {
259 using type = invoke_result_false;
260};
261
263template <typename MemPtr, typename Arg>
264struct __invoke_result_dispatch<true, false, MemPtr, Arg>
265 : __invoke_result_memobj<decay_t<MemPtr>, unwrap_reference_t<Arg>> {};
266
268template <typename MemPtr, typename Arg, typename... Args>
269struct __invoke_result_dispatch<false, true, MemPtr, Arg, Args...>
270 : __invoke_result_memfun<decay_t<MemPtr>, unwrap_reference_t<Arg>, Args...> {};
271
273template <typename F, typename... Args>
274struct __invoke_result_dispatch<false, false, F, Args...> {
275private:
276 template <typename F1, typename... Args1>
277 static invoke_result_true<
278 decltype(_MSTL declval<F1>()(_MSTL declval<Args1>()...)), invoke_other_tag> __test(int);
279
280 template <typename...>
281 static invoke_result_false __test(...);
282
283public:
284 using type = decltype(__test<F, Args...>(0));
285};
286
293template <typename F, typename... Args>
294struct __invoke_result_aux : __invoke_result_dispatch<
295 is_member_object_pointer<remove_reference_t<F>>::value,
296 is_member_function_pointer<remove_reference_t<F>>::value,
297 F, Args...>::type {};
298
301
302
308template <typename F, typename... Args>
309struct invoke_result<F(Args...)> : _INNER __invoke_result_aux<F, Args...> {};
310
317template <typename F, typename... Args>
318using invoke_result_t = typename _INNER __invoke_result_aux<F, Args...>::type;
319 // InvokeResult
321
327
330
339template <typename Result, typename Ret, bool IsVoid = is_void<Ret>::value, typename Dummy = void>
340struct __is_invocable_aux : false_type {};
341
343template <typename Result, typename Ret>
344struct __is_invocable_aux<Result, Ret, true, void_t<typename Result::type>> : true_type {};
345
346#ifdef MSTL_COMPILER_GCC__
347#pragma GCC diagnostic push
348#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
349#elif defined(MSTL_COMPILER_CLANG__)
350#pragma clang diagnostic push
351#pragma clang diagnostic ignored "-Wctor-dtor-privacy"
352#elif defined(MSTL_COMPILER_MSVC__)
353#pragma warning(push)
354#pragma warning(disable : 4624)
355#endif
356
358template <typename Result, typename Ret>
359struct __is_invocable_aux<Result, Ret, false, void_t<typename Result::type>> {
360private:
361 using Res_t = typename Result::type;
362
363 template <typename T, bool Nothrow = noexcept(_MSTL declvoid<T>(_MSTL declval<Res_t>())),
364 typename = decltype(_MSTL declvoid<T>(_MSTL declval<Res_t>())), bool Dangle =
365#if defined(MSTL_COMPILER_GCC__) && defined(MSTL_PLATFORM_WINDOWS__)
366 __reference_converts_from_temporary(T, Res_t)
367#else
368 false
369#endif
370 >
371 static bool_constant<Nothrow && !Dangle> __test(int);
372
373 template <typename T, bool = false>
374 static false_type __test(...);
375
376public:
377 using type = decltype(__test<Ret, true>(1));
378};
379
380#ifdef MSTL_COMPILER_CLANG__
381#pragma clang diagnostic pop
382#elif defined(MSTL_COMPILER_GCC__)
383#pragma GCC diagnostic pop
384#elif defined(MSTL_COMPILER_MSVC__)
385#pragma warning(pop)
386#endif
387
390
391
400template <typename F, typename... Args>
401struct is_invocable : _INNER __is_invocable_aux<_INNER __invoke_result_aux<F, Args...>, void>::type {};
402
403#ifdef MSTL_STANDARD_14__
408template <typename F, typename... Args>
409MSTL_INLINE17 constexpr bool is_invocable_v = is_invocable<F, Args...>::value;
410#endif
411
412
422template <typename Ret, typename F, typename... Args>
423struct is_invocable_r : _INNER __is_invocable_aux<_INNER __invoke_result_aux<F, Args...>, Ret>::type {};
424
425#ifdef MSTL_STANDARD_14__
430template <typename Ret, typename F, typename... Args>
431MSTL_INLINE17 constexpr bool is_invocable_r_v = is_invocable_r<Ret, F, Args...>::value;
432#endif
433
434
437
438template <typename F, typename T, typename... Args>
439constexpr bool __invoke_is_nothrow_dispatch(invoke_memfun_ref_tag) {
441}
442template <typename F, typename T, typename... Args>
443constexpr bool __invoke_is_nothrow_dispatch(invoke_memfun_deref_tag) {
444 return noexcept((*_MSTL declval<T>().*_MSTL declval<F>())(_MSTL declval<Args>()...));
445}
446template <typename F, typename T>
447constexpr bool __invoke_is_nothrow_dispatch(invoke_memobj_ref_tag) {
449}
450template <typename F, typename T>
451constexpr bool __invoke_is_nothrow_dispatch(invoke_memobj_deref_tag) {
452 return noexcept(*_MSTL declval<T>().*_MSTL declval<F>());
453}
454template <typename F, typename... Args>
455constexpr bool __invoke_is_nothrow_dispatch(invoke_other_tag) {
456 return noexcept(_MSTL declval<F>()(_MSTL declval<Args>()...));
457}
458
466template <typename Result, typename F, typename... Args>
467struct __invoke_is_nothrow : bool_constant<
468 __invoke_is_nothrow_dispatch<F, Args...> (typename Result::invoke_type{})> {};
469
474template <typename F, typename... Args>
475using __bind_invoke_is_nothrow = __invoke_is_nothrow<__invoke_result_aux<F, Args...>, F, Args...>;
476
479
480
489template <typename F, typename... Args>
491 is_invocable<F, Args...>, _INNER __bind_invoke_is_nothrow<F, Args...>>::type {};
492
493#ifdef MSTL_STANDARD_14__
498template <typename F, typename... Args>
499MSTL_INLINE17 constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<F, Args...>::value;
500#endif
501 // InvocableChecks
503
509
512
513template <typename T, typename U = unwrap_reference_t<T>>
514constexpr U&& __invoke_forward(remove_reference_t<T>& t) noexcept {
515 return static_cast<U&&>(t);
516}
517
518template <typename Res, typename F, typename... Args>
519MSTL_CONSTEXPR14 Res __invoke_dispatch(invoke_other_tag, F&& f, Args&&... args) {
520 return _MSTL forward<F>(f)(_MSTL forward<Args>(args)...);
521}
522template <typename Res, typename MemFun, typename T, typename... Args>
523MSTL_CONSTEXPR14 Res __invoke_dispatch(invoke_memfun_ref_tag, MemFun&& f, T&& t, Args&&... args) {
524 return (_INNER __invoke_forward<T>(t).*f)(_MSTL forward<Args>(args)...);
525}
526template <typename Res, typename MemFun, typename T, typename... Args>
527MSTL_CONSTEXPR14 Res __invoke_dispatch(invoke_memfun_deref_tag, MemFun&& f, T&& t, Args&&... args){
528 return (*_MSTL forward<T>(t).*f)(_MSTL forward<Args>(args)...);
529}
530template <typename Res, typename MemPtr, typename T>
531MSTL_CONSTEXPR14 Res __invoke_dispatch(invoke_memobj_ref_tag, MemPtr&& f, T&& t) {
532 return _INNER __invoke_forward<T>(t).*f;
533}
534template <typename Res, typename MemPtr, typename T>
535MSTL_CONSTEXPR14 Res __invoke_dispatch(invoke_memobj_deref_tag, MemPtr&& f, T&& t) {
536 return *_MSTL forward<T>(t).*f;
537}
538
541
542
557template <typename Callable, typename... Args>
558MSTL_CONSTEXPR14 typename _INNER __invoke_result_aux<Callable, Args...>::type
559invoke(Callable&& f, Args&&... args)
560noexcept(is_nothrow_invocable<Callable, Args...>::value) {
561 using result = _INNER __invoke_result_aux<Callable, Args...>;
562 using type = typename result::type;
563 using tag = typename result::invoke_type;
564 return _INNER __invoke_dispatch<type>(tag{}, _MSTL forward<Callable>(f), _MSTL forward<Args>(args)...);
565}
566
567
570
571template <typename T, typename Tag, typename Res, typename Callable, typename... Args>
572MSTL_CONSTEXPR14 enable_if_t<is_invocable_r<Res, Callable, Args...>::value && is_void<Res>::value, Res>
573__invoke_r_dispatch(Callable&& f, Args&&... args)
574noexcept(is_nothrow_invocable<Callable, Args...>::value) {
575 __invoke_dispatch<T>(Tag{}, _MSTL forward<Callable>(f), _MSTL forward<Args>(args)...);
576 return;
577}
578
579template <typename T, typename Tag, typename Res, typename Callable, typename... Args>
580MSTL_CONSTEXPR14 enable_if_t<is_invocable_r<Res, Callable, Args...>::value && !is_void<Res>::value, Res>
581__invoke_r_dispatch(Callable&& f, Args&&... args)
582noexcept(is_nothrow_invocable<Callable, Args...>::value) {
583 return __invoke_dispatch<T>(Tag{}, _MSTL forward<Callable>(f), _MSTL forward<Args>(args)...);
584}
585
588
589
601template <typename Res, typename Callable, typename... Args>
602MSTL_CONSTEXPR14 enable_if_t<is_invocable_r<Res, Callable, Args...>::value, Res>
603invoke_r(Callable&& f, Args&&... args)
604noexcept(is_nothrow_invocable<Callable, Args...>::value) {
605 using result = _INNER __invoke_result_aux<Callable, Args...>;
606 using type = typename result::type;
607 using tag = typename result::invoke_type;
608 return _INNER __invoke_r_dispatch<type, tag, Res, Callable, Args...>(
610 );
611}
612 // InvokeFunction
614
616#endif // MSTL_CORE_FUNCTIONAL_INVOKE_HPP__
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
#define MSTL_COMPILER_GCC__
定义使用GCC编译器编译
add_rvalue_reference_t< T > declval() noexcept
获取类型的右值引用,仅用于非求值上下文
void declvoid(type_identity_t< T >) noexcept
将类型映射为void,仅用于非求值上下文
MSTL_CONSTEXPR14 _INNER __invoke_result_aux< Callable, Args... >::type invoke(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
统一调用接口
MSTL_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)
带返回类型检查的统一调用接口
typename _INNER __invoke_result_aux< F, Args... >::type invoke_result_t
invoke_result的便捷别名
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
#define MSTL_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的便捷别名
MSTL引用包装器
类型集合的逻辑与操作
类型集合的逻辑或操作
成员函数解引用调用标签
成员函数引用调用标签
成员对象解引用调用标签
成员对象引用调用标签
其他类型调用标签
推导失败的空结构
成功推导到调用结果类型的包装器
T type
调用结果类型
Tag invoke_type
调用类型标签
推导函数调用结果类型的主模板
判断Base是否是Derived的基类
判断类型是否可调用并返回指定类型
判断类型是否可调用
判断调用是否不会抛出异常
判断两个类型是否相同
判断类型是否为void