1#ifndef MSTL_CORE_FUNCTIONAL_BIND_HPP__
2#define MSTL_CORE_FUNCTIONAL_BIND_HPP__
17template <
typename Res,
typename... Args>
18struct unary_or_binary_function {};
20template <
typename Res,
typename T1>
21struct unary_or_binary_function<Res, T1>
24template <
typename Res,
typename T1,
typename T2>
25struct unary_or_binary_function<Res, T1, T2>
33template <
typename Sign>
34struct mem_func_traits;
36template <
typename Res,
typename Class,
typename... Args>
37struct mem_func_traits_base {
38 using result_type = Res;
39 using maybe_type = unary_or_binary_function<Res, Class*, Args...>;
40 using arity = integral_constant<
size_t,
sizeof...(Args)>;
43#define __MSTL_MEMFUNC_TRAITS_BASE(CV, REF) \
44template <typename Res, typename Class, typename... Args> \
45struct mem_func_traits<Res (Class::*)(Args...) CV REF> \
46 : mem_func_traits_base<Res, CV Class, Args...> { \
47 using vararg = false_type; \
49template <typename Res, typename Class, typename... Args> \
50struct mem_func_traits<Res (Class::*)(Args..., ...) CV REF> \
51 : mem_func_traits_base<Res, CV Class, Args...> { \
52 using vararg = true_type; \
55#define MSTL_MEMFUNC_TRAITS(REF, P) \
56__MSTL_MEMFUNC_TRAITS_BASE(, REF) \
57__MSTL_MEMFUNC_TRAITS_BASE(const, REF) \
58__MSTL_MEMFUNC_TRAITS_BASE(volatile, REF) \
59__MSTL_MEMFUNC_TRAITS_BASE(const volatile, REF)
62MSTL_MEMFUNC_TRAITS(&,)
63MSTL_MEMFUNC_TRAITS(&&,)
65#ifdef MSTL_STANDARD_17__
66MSTL_MEMFUNC_TRAITS(
noexcept,)
67MSTL_MEMFUNC_TRAITS(& noexcept,)
68MSTL_MEMFUNC_TRAITS(&& noexcept,)
71#undef MSTL_MEMFUNC_TRAITS_BASE
72#undef MSTL_MEMFUNC_TRAITS
75template <
typename Func,
typename =
void_t<>>
76struct maybe_get_result_type {};
78template <
typename Func>
79struct maybe_get_result_type<Func,
void_t<typename Func::result_type>> {
80 using result_type =
typename Func::result_type;
84template <
typename Func>
85struct __weak_result_type_impl : maybe_get_result_type<Func> {};
87template <
typename Res,
typename... Args>
88struct __weak_result_type_impl<Res(Args...)> {
89 using result_type = Res;
91template <
typename Res,
typename... Args>
92struct __weak_result_type_impl<Res(Args..., ...)> {
93 using result_type = Res;
95template <
typename Res,
typename... Args>
96struct __weak_result_type_impl<Res(*)(Args...)> {
97 using result_type = Res;
99template <
typename Res,
typename... Args>
100struct __weak_result_type_impl<Res(*)(Args..., ...)> {
101 using result_type = Res;
104#ifdef MSTL_STANDARD_17__
105template <
typename Res,
typename... Args>
106struct __weak_result_type_impl<Res(Args...) noexcept> {
107 using result_type = Res;
109template <
typename Res,
typename... Args>
110struct __weak_result_type_impl<Res(Args..., ...) noexcept> {
111 using result_type = Res;
113template <
typename Res,
typename... Args>
114struct __weak_result_type_impl<Res(*)(Args...)
noexcept> {
115 using result_type = Res;
117template <
typename Res,
typename... Args>
118struct __weak_result_type_impl<Res(*)(Args..., ...)
noexcept> {
119 using result_type = Res;
124template <typename Func, bool = is_member_function_pointer<Func>::value>
125struct __weak_result_type_memfun
126 : __weak_result_type_impl<Func> {};
128template <
typename MemFunPtr>
129struct __weak_result_type_memfun<MemFunPtr, true> {
130 using result_type =
typename mem_func_traits<MemFunPtr>::result_type;
133template <
typename Func,
typename Class>
134struct __weak_result_type_memfun<Func Class::*, false> {};
143template <
typename Func>
144struct weak_result_type : __weak_result_type_memfun<remove_cv_t<Func>> {};
153template <
typename MemberPtr,
bool IsMemFunc = is_member_function_po
inter_v<MemberPtr>>
154class mem_func_base :
public _INNER mem_func_traits<MemberPtr>::maybe_type {
155 using Traits =
_INNER mem_func_traits<MemberPtr>;
156 using Arity =
typename Traits::arity;
157 using Varargs =
typename Traits::vararg;
159 template <
typename Func,
typename... BoundArgs>
160 friend struct bind_check_arity;
165 using result_type =
typename Traits::result_type;
171 explicit constexpr mem_func_base(MemberPtr pmf) noexcept : ptr_(pmf) {}
179 template <
typename... Args>
180 MSTL_CONSTEXPR20
auto operator ()(Args&&... args)
const
190template <
typename MemberObjPtr>
191class mem_func_base<MemberObjPtr, false> {
192 using Arity = integral_constant<size_t, 0>;
195 template <
typename Func,
typename... BoundArgs>
196 friend struct bind_check_arity;
205 explicit constexpr mem_func_base(MemberObjPtr pm) noexcept : ptr_(pm) {}
213 template <
typename T>
214 MSTL_CONSTEXPR20
auto operator ()(T&& obj)
const
221template <
typename MemberPo
inter>
224template <
typename Res,
typename Class>
225struct mem_func<Res Class::*> : mem_func_base<Res Class::*> {
226 using mem_func_base<Res Class::*>::mem_func_base;
260template <u
int32_t Num>
267template <u
int32_t Num>
279template <u
int32_t Num>
344template <
typename Arg,
347class bind_arg_mapper;
352 template <
typename CVRef,
typename Tuple>
353 MSTL_CONSTEXPR20 T& operator ()(CVRef& arg, Tuple&)
const volatile {
358template <
typename Arg>
359class bind_arg_mapper<Arg, true, false> {
361 template <
typename CVArg,
typename... Args>
362 MSTL_CONSTEXPR20
auto operator ()(CVArg& arg, tuple<Args...>& tuple_ref)
const volatile
365 return call(arg, tuple_ref, Indexes());
369 template <
typename CVArg,
typename... Args,
size_t... Indexes>
370 MSTL_CONSTEXPR20
auto call(CVArg& arg, tuple<Args...>& tuple_ref,
371 const index_tuple<Indexes...>&)
const volatile
378template <
typename Arg>
379class bind_arg_mapper<Arg, false, true> {
380 template <
size_t I,
typename Tuple>
382 (I < tuple_size_v<Tuple>),
386 template <
typename Tuple>
388 operator ()(
const volatile Arg&, Tuple& tuple_ref)
const volatile {
393template <
typename Arg>
394class bind_arg_mapper<Arg, false, false> {
396 template <
typename CVArg,
typename Tuple>
397 MSTL_CONSTEXPR20 CVArg&& operator ()(CVArg&& arg, Tuple&)
const volatile {
421template <
typename Sign>
432template <
typename Func,
typename... BoundArgs>
433class binder<Func(BoundArgs...)> :
public _INNER weak_result_type<Func> {
438 tuple<BoundArgs...> bound_args_;
447 template <
typename BoundArg,
typename CallArgs>
448 struct arg_mapper_result {
449 using type =
decltype(
_INNER bind_arg_mapper<remove_cv_t<BoundArg>>()(
457 template <
typename BoundArg,
typename CallArgs>
458 using arg_mapper_result_t =
typename arg_mapper_result<BoundArg, CallArgs>::type;
465 template <
typename CallArgs>
468 arg_mapper_result_t<BoundArgs, CallArgs>...
476 template <
typename CallArgs>
479 arg_mapper_result_t<const BoundArgs, CallArgs>...
488 template <
typename BoundArg,
typename CallArgs>
489 using arg_mapper_type =
decltype(
_INNER bind_arg_mapper<remove_cv_t<BoundArg>>()(
497 template <
typename CallArgs>
510 template <
typename Res,
typename... Args,
size_t... Indexes>
526 template <
typename Res,
typename... Args,
_MSTL size_t... Indexes>
540 template <
typename... Args>
541 explicit MSTL_CONSTEXPR20
binder(Func&& func, Args&&... args)
553 template <
typename... Args>
554 MSTL_CONSTEXPR20
auto operator ()(Args&&... args)
555 -> result_type<tuple<Args&&...>> {
556 using Res = result_type<tuple<Args&&...>>;
557 return binder::call<Res>(
568 template <
typename... Args>
569 MSTL_CONSTEXPR20
auto operator ()(Args&&... args)
const
570 -> result_type_const<tuple<Args&&...>> {
571 using Res = result_type_const<tuple<Args&&...>>;
572 return binder::call_const<Res>(
577 template <
typename... Args>
578 void operator ()(Args&&... args)
const volatile =
delete;
590template <
typename Res,
typename Sign>
599template <
typename Res,
typename Func,
typename... BoundArgs>
605 tuple<BoundArgs...> bound_args_;
617 template <
typename Result,
typename... Args,
size_t... Indexes>
632 template <
typename Result,
typename... Args,
_MSTL size_t... Indexes>
647 template <
typename... Args>
648 explicit MSTL_CONSTEXPR20
bindrer(Func&& func, Args&&... args)
660 template <
typename... Args>
662 return bindrer::call<Res>(
673 template <
typename... Args>
675 return bindrer::call<Res>(
680 template <
typename... Args>
681 void operator ()(Args&&... args)
const volatile =
delete;
687template <
typename Sign>
689template <
typename Res,
typename Sign>
692#define __MSTL_EXPAND_BIND_EXP(CV) \
693template <typename Sign> \
694struct is_bind_expression<CV binder<Sign>> : true_type {}; \
695template <typename Res, typename Sign> \
696struct is_bind_expression<CV bindrer<Res, Sign>> : true_type {};
698MSTL_MACRO_RANGES_CV(__MSTL_EXPAND_BIND_EXP)
699#undef __MSTL_EXPAND_BIND_EXP
711template <
typename Func,
typename... BoundArgs>
712struct bind_check_arity {};
714template <
typename Ret,
typename... Args,
typename... BoundArgs>
715struct bind_check_arity<Ret (*)(Args...), BoundArgs...> {
716 static_assert(
sizeof...(BoundArgs) ==
sizeof...(Args),
717 "Wrong number of arguments for function");
720template <
typename Ret,
typename... Args,
typename... BoundArgs>
721struct bind_check_arity<Ret (*)(Args..., ...), BoundArgs...> {
722 static_assert(
sizeof...(BoundArgs) >=
sizeof...(Args),
723 "Wrong number of arguments for function");
726template <
typename T,
typename Class,
typename... BoundArgs>
727struct bind_check_arity<T Class::*, BoundArgs...> {
728 using Arity =
typename mem_func<T Class::*>::Arity;
729 using Varargs =
typename mem_func<T Class::*>::Varargs;
730 static_assert(Varargs::value
731 ?
sizeof...(BoundArgs) >= Arity::value + 1
732 :
sizeof...(BoundArgs) == Arity::value + 1,
733 "Wrong number of arguments for pointer-to-member");
746template <
bool IntLike,
typename Func,
typename... BoundArgs>
748 :
_INNER bind_check_arity<decay_t<Func>, BoundArgs...> {
753template <
typename Func,
typename... BoundArgs>
760template <
bool IntLike,
typename Func,
typename... BoundArgs>
776template <
typename Func,
typename... BoundArgs>
778MSTL_NODISCARD constexpr
bind_helper_t<is_integral_like_v<Func>, Func, BoundArgs...>
779bind(Func&& func, BoundArgs&&... args) {
794template <
typename Res,
typename Func,
typename... BoundArgs>
796 :
_INNER bind_check_arity<decay_t<Func>, BoundArgs...> {
804template <
typename Res,
typename Func,
typename... BoundArgs>
819template <
typename Res,
typename Func,
typename... BoundArgs>
822bind(Func&& func, BoundArgs&&... args) {
838template <
typename Func,
typename... BoundArgs>
841#ifdef MSTL_STANDARD_17__
842 static_assert((is_move_constructible_v<BoundArgs> && ...),
"Args should be move constructible");
849 tuple<BoundArgs...> bound_args_;
862 template <
typename T,
size_t... Indices,
typename... CallArgs>
863 static constexpr decltype(
auto)
879 template <
typename Fn,
typename... Args>
886 static_assert(
sizeof...(Args) ==
sizeof...(BoundArgs),
"Wrong number of arguments");
902 template <
typename... CallArgs>
905 noexcept(is_nothrow_invocable_v<Func&, BoundArgs&..., CallArgs...>) {
915 template <
typename... CallArgs>
916 constexpr invoke_result_t<
const Func&,
const BoundArgs&..., CallArgs...>
918 noexcept(is_nothrow_invocable_v<
const Func&,
const BoundArgs&..., CallArgs...>) {
928 template <
typename... CallArgs>
931 noexcept(is_nothrow_invocable_v<Func, BoundArgs..., CallArgs...>) {
941 template <
typename... CallArgs>
944 noexcept(is_nothrow_invocable_v<
const Func,
const BoundArgs..., CallArgs...>) {
955template <
typename Func,
typename... Args>
968template <
typename Func,
typename... Args>
MSTL_CONSTEXPR20 binder(Func &&func, Args &&... args)
构造函数
binder(const binder &)=default
复制构造函数
binder(binder &&)=default
移动构造函数
bindrer(bindrer &&)=default
移动构造函数
bindrer(const bindrer &)=default
复制构造函数
MSTL_CONSTEXPR20 bindrer(Func &&func, Args &&... args)
构造函数
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
MSTL_ALWAYS_INLINE enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
MSTL_INLINE17 constexpr bool is_placeholder_v
is_placeholder的便捷变量模板
MSTL_INLINE17 constexpr bool is_bind_expression_v
is_bind_expression的便捷变量模板
MSTL_INLINE17 constexpr uint32_t placeholder_v
placeholder值的便捷变量模板
unsigned int uint32_t
32位无符号整数类型
MSTL_DEPRECATE_FOR("use lambda or bind_front instead of bind") MSTL_NODISCARD const expr bind_helper_t< is_integral_like_v< Func >
bind函数
MSTL_NODISCARD constexpr binder_front_type< Func, Args... > bind_front(Func &&func, Args &&... args) noexcept(is_nothrow_constructible< binder_front_type< Func, Args... >, int, Func, Args... >::value)
bind_front函数
typename bindr_helper< Res, Func, BoundArgs... >::type bindr_helper_t
bindr_helper的便捷别名
binder_front< decay_t< Func >, decay_t< Args >... > binder_front_type
binder_front类型的便捷别名
typename bind_helper< IntLike, Func, BoundArgs... >::type bind_helper_t
bind_helper的便捷别名
typename build_index_tuple< Num >::type build_index_tuple_t
build_index_tuple的便捷别名
integer_sequence< size_t, Values... > index_sequence
索引序列
make_index_sequence< sizeof...(Types)> index_sequence_for
根据类型参数包生成索引序列
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命名空间
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
MSTL_NODISCARD constexpr tuple< Types &&... > forward_as_tuple(Types &&... args) noexcept
创建转发引用元组
typename decay< T >::type decay_t
decay的便捷别名
integral_constant< uint32_t, Value > uint32_constant
32位无符号整数常量包装器
bool_constant< true > true_type
表示true的类型
bool_constant< false > false_type
表示false的类型
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL_INLINE17 constexpr placeholder< 19 > p19
占位符19
MSTL_INLINE17 constexpr placeholder< 21 > p21
占位符21
MSTL_INLINE17 constexpr placeholder< 8 > p8
占位符8
MSTL_INLINE17 constexpr placeholder< 24 > p24
占位符24
MSTL_INLINE17 constexpr placeholder< 17 > p17
占位符17
MSTL_INLINE17 constexpr placeholder< 4 > p4
占位符4
MSTL_INLINE17 constexpr placeholder< 12 > p12
占位符12
MSTL_INLINE17 constexpr placeholder< 15 > p15
占位符15
MSTL_INLINE17 constexpr placeholder< 14 > p14
占位符14
MSTL_INLINE17 constexpr placeholder< 22 > p22
占位符22
MSTL_INLINE17 constexpr placeholder< 9 > p9
占位符9
MSTL_INLINE17 constexpr placeholder< 3 > p3
占位符3
MSTL_INLINE17 constexpr placeholder< 20 > p20
占位符20
MSTL_INLINE17 constexpr placeholder< 1 > p1
占位符1
MSTL_INLINE17 constexpr placeholder< 27 > p27
占位符27
MSTL_INLINE17 constexpr placeholder< 25 > p25
占位符25
MSTL_INLINE17 constexpr placeholder< 16 > p16
占位符16
MSTL_INLINE17 constexpr placeholder< 2 > p2
占位符2
MSTL_INLINE17 constexpr placeholder< 13 > p13
占位符13
MSTL_INLINE17 constexpr placeholder< 6 > p6
占位符6
MSTL_INLINE17 constexpr placeholder< 29 > p29
占位符29
MSTL_INLINE17 constexpr placeholder< 26 > p26
占位符26
MSTL_INLINE17 constexpr placeholder< 5 > p5
占位符5
MSTL_INLINE17 constexpr placeholder< 28 > p28
占位符28
MSTL_INLINE17 constexpr placeholder< 11 > p11
占位符11
MSTL_INLINE17 constexpr placeholder< 18 > p18
占位符18
MSTL_INLINE17 constexpr placeholder< 10 > p10
占位符10
MSTL_INLINE17 constexpr placeholder< 7 > p7
占位符7
MSTL_INLINE17 constexpr placeholder< 23 > p23
占位符23
typename tuple_element< Index, Types... >::type tuple_element_t
tuple_element的类型别名
decay_t< Func > func_type
函数类型
binder< func_type(decay_t< BoundArgs >...)> type
推导出的binder类型
binder_front(const binder_front &)=default
复制构造函数
binder_front(binder_front &&)=default
移动构造函数
~binder_front()=default
析构函数
constexpr invoke_result_t< Func &, BoundArgs &..., CallArgs... > operator()(CallArgs &&... call_args) &noexcept(is_nothrow_invocable_v< Func &, BoundArgs &..., CallArgs... >)
左值调用操作符
constexpr binder_front(int p, Fn &&func, Args &&... args) noexcept(conjunction< is_nothrow_constructible< Func, Fn >, is_nothrow_constructible< BoundArgs, Args >... >::value)
构造函数
binder_front & operator=(const binder_front &)=default
复制赋值运算符
static constexpr bool value