1#ifndef MSTL_CORE_FUNCTIONAL_INVOKE_HPP__
2#define MSTL_CORE_FUNCTIONAL_INVOKE_HPP__
26struct invoke_memfun_ref_tag {
27 constexpr invoke_memfun_ref_tag()
noexcept =
default;
36struct invoke_memfun_deref_tag {
37 constexpr invoke_memfun_deref_tag()
noexcept =
default;
46struct invoke_memobj_ref_tag {
47 constexpr invoke_memobj_ref_tag()
noexcept =
default;
56struct invoke_memobj_deref_tag {
57 constexpr invoke_memobj_deref_tag()
noexcept =
default;
66struct invoke_other_tag {
67 constexpr invoke_other_tag()
noexcept =
default;
86template <
typename Sign>
97template <
typename T,
typename Tag>
122template <
typename MemPtr,
typename Arg,
typename... Args>
123struct __invoke_result_memfun_ref {
125 template <
typename F,
typename T,
typename... Args1>
129 template <
typename...>
133 using type =
decltype(__test<MemPtr, Arg, Args...>(0));
143template <
typename MemPtr,
typename Arg,
typename... Args>
144struct __invoke_result_memfun_deref {
146 template <
typename F,
typename T,
typename... Args1>
148 invoke_memfun_deref_tag> __test(
int);
150 template <
typename...>
151 static invoke_result_false __test(...);
154 using type =
decltype(__test<MemPtr, Arg, Args...>(0));
163template <
typename MemPtr,
typename Arg>
164struct __invoke_result_memobj_ref {
166 template <
typename F,
typename T>
170 template <
typename,
typename>
174 using type =
decltype(__test<MemPtr, Arg>(0));
183template <
typename MemPtr,
typename Arg>
184struct __invoke_result_memobj_deref {
186 template <
typename F,
typename T>
190 template <
typename,
typename>
194 using type =
decltype(__test<MemPtr, Arg>(0));
205template <
typename MemPtr,
typename Arg>
206struct __invoke_result_memobj;
214template <
typename Res,
typename Class,
typename Arg>
215struct __invoke_result_memobj<Res Class::*, Arg> {
217 using MemPtr = Res Class::*;
220 __invoke_result_memobj_ref<MemPtr, Arg>,
221 __invoke_result_memobj_deref<MemPtr, Arg>>::type;
231template <
typename MemPtr,
typename Arg,
typename... Args>
232struct __invoke_result_memfun;
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;
257template <
bool IsMemObj,
bool IsMemFun,
typename F,
typename... Args>
258struct __invoke_result_dispatch {
259 using type = invoke_result_false;
263template <
typename MemPtr,
typename Arg>
264struct __invoke_result_dispatch<true, false, MemPtr, Arg>
265 : __invoke_result_memobj<decay_t<MemPtr>, unwrap_reference_t<Arg>> {};
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...> {};
273template <
typename F,
typename... Args>
274struct __invoke_result_dispatch<false, false, F, Args...> {
276 template <
typename F1,
typename... Args1>
277 static invoke_result_true<
280 template <
typename...>
281 static invoke_result_false __test(...);
284 using type =
decltype(__test<F, Args...>(0));
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 {};
308template <
typename F,
typename... Args>
317template <
typename F,
typename... Args>
339template <typename Result, typename Ret, bool IsVoid = is_void<Ret>::value,
typename Dummy =
void>
343template <
typename Result,
typename Ret>
344struct __is_invocable_aux<Result, Ret, true,
void_t<typename Result::type>> :
true_type {};
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__)
354#pragma warning(disable : 4624)
358template <
typename Result,
typename Ret>
359struct __is_invocable_aux<Result, Ret, false,
void_t<typename Result::type>> {
361 using Res_t =
typename Result::type;
366 __reference_converts_from_temporary(T, Res_t)
373 template <
typename T,
bool = false>
377 using type =
decltype(__test<Ret, true>(1));
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__)
400template <
typename F,
typename... Args>
401struct is_invocable :
_INNER __is_invocable_aux<_INNER __invoke_result_aux<F, Args...>, void>::type {};
403#ifdef MSTL_STANDARD_14__
408template <
typename F,
typename... Args>
409MSTL_INLINE17
constexpr bool is_invocable_v =
is_invocable<F, Args...>::value;
422template <
typename Ret,
typename F,
typename... Args>
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;
438template <
typename F,
typename T,
typename... Args>
442template <
typename F,
typename T,
typename... Args>
446template <
typename F,
typename T>
450template <
typename F,
typename T>
454template <
typename F,
typename... Args>
466template <
typename Result,
typename F,
typename... Args>
468 __invoke_is_nothrow_dispatch<F, Args...> (typename Result::invoke_type{})> {};
474template <
typename F,
typename... Args>
475using __bind_invoke_is_nothrow = __invoke_is_nothrow<__invoke_result_aux<F, Args...>, F, Args...>;
489template <
typename F,
typename... Args>
491 is_invocable<F, Args...>, _INNER __bind_invoke_is_nothrow<F, Args...>>::type {};
493#ifdef MSTL_STANDARD_14__
498template <
typename F,
typename... Args>
513template <
typename T,
typename U = unwrap_reference_t<T>>
515 return static_cast<U&&
>(t);
518template <
typename Res,
typename F,
typename... Args>
519MSTL_CONSTEXPR14 Res __invoke_dispatch(
invoke_other_tag, F&& f, Args&&... args) {
522template <
typename Res,
typename MemFun,
typename T,
typename... Args>
526template <
typename Res,
typename MemFun,
typename T,
typename... Args>
530template <
typename Res,
typename MemPtr,
typename T>
532 return _INNER __invoke_forward<T>(t).*f;
534template <
typename Res,
typename MemPtr,
typename T>
557template <
typename Callable,
typename... Args>
558MSTL_CONSTEXPR14
typename _INNER __invoke_result_aux<Callable, Args...>::type
561 using result =
_INNER __invoke_result_aux<Callable, Args...>;
562 using type =
typename result::type;
563 using tag =
typename result::invoke_type;
571template <
typename T,
typename Tag,
typename Res,
typename Callable,
typename... Args>
573__invoke_r_dispatch(Callable&& f, Args&&... args)
579template <
typename T,
typename Tag,
typename Res,
typename Callable,
typename... Args>
581__invoke_r_dispatch(Callable&& f, Args&&... args)
601template <
typename Res,
typename Callable,
typename... Args>
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...>(
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
#define MSTL_COMPILER_GCC__
定义使用GCC编译器编译
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命名空间
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的便捷别名