YSTest: apply.hpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

apply.hpp
浏览该文件的文档.
1 /*
2 © 2013-2016, 2018 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YB_INC_ystdex_apply_hpp_
29 #define YB_INC_ystdex_apply_hpp_ 1
30
31 #include "invoke.hpp" // for "invoke.hpp", index_sequence, ystdex::invoke,
32 // make_index_sequence, decay_t;
33 #include "integer_sequence.hpp" // for index_sequence;
34 #include <tuple> // for <tuple>, std::tuple, std::get, std::forward_as_tuple,
35 // std::tuple_size, std::make_from_tuple;
36
44 #ifndef __cpp_lib_apply
45 # if YB_IMPL_MSCPP >= 1910 || __cplusplus >= 201603L
46 # define __cpp_lib_apply 201603L
47 # endif
48 #endif
49 #ifndef __cpp_lib_tuple_element_t
50 # if YB_IMPL_MSCPP >= 1900 || __cplusplus >= 201402L
51 # define __cpp_lib_tuple_element_t 201402L
52 # endif
53 #endif
54 #ifndef __cpp_lib_make_from_tuple
55 # if YB_IMPL_MSCPP >= 1910 || __cplusplus >= 201606L
56 # define __cpp_lib_make_from_tuple 201606L
57 # endif
58 #endif
59
60
61 namespace ystdex
62 {
63
69 template<class, class>
70 struct call_projection;
71
72 template<typename _tRet, typename... _tParams, size_t... _vSeq>
73 struct call_projection<_tRet(_tParams...), index_sequence<_vSeq...>>
74 {
76
77 template<typename _func>
78 static yconstfn auto
79 apply_call(_func&& f, std::tuple<_tParams...>&& args, yimpl(decay_t<
80 decltype(yforward(f)(std::get<_vSeq>(yforward(args))...))>* = {}))
81 -> yimpl(decltype(yforward(f)(std::get<_vSeq>(yforward(args))...)))
82 {
83 return yforward(f)(std::get<_vSeq>(yforward(args))...);
84 }
85
86 template<typename _fCallable>
87 static yconstfn auto
88 apply_invoke(_fCallable&& f, std::tuple<_tParams...>&& args,
89 yimpl(decay_t<decltype(ystdex::invoke(yforward(f),
90 std::get<_vSeq>(yforward(args))...))>* = {})) -> yimpl(decltype(
91 ystdex::invoke(yforward(f), std::get<_vSeq>(yforward(args))...)))
92 {
93 return ystdex::invoke(yforward(f), std::get<_vSeq>(yforward(args))...);
94 }
96
97 template<typename _func>
98 static yconstfn auto
99 call(_func&& f, _tParams&&... args) -> yimpl(decltype(
100 apply_call(yforward(f), std::forward_as_tuple(yforward(args)...))))
101 {
102 return
103 apply_call(yforward(f), std::forward_as_tuple(yforward(args)...));
104 }
105
107 template<typename _fCallable>
108 static yconstfn auto
109 invoke(_fCallable&& f, _tParams&&... args) -> yimpl(decltype(
110 apply_invoke(yforward(f), std::forward_as_tuple(yforward(args)...))))
111 {
112 return
113 apply_invoke(yforward(f), std::forward_as_tuple(yforward(args)...));
114 }
115 };
116
121 template<typename... _tParams, size_t... _vSeq>
122 struct call_projection<std::tuple<_tParams...>, index_sequence<_vSeq...>>
123 {
125 template<typename _func>
126 static yconstfn auto
127 apply_call(_func&& f, std::tuple<_tParams...>&& args)
128 -> yimpl(decltype(yforward(f)(std::get<_vSeq>(yforward(args))...)))
129 {
130 return yforward(f)(std::get<_vSeq>(yforward(args))...);
131 }
132
134 template<typename _fCallable>
135 static yconstfn auto
136 apply_invoke(_fCallable&& f, std::tuple<_tParams...>&& args)
137 -> yimpl(decltype(ystdex::invoke(yforward(f),
138 std::get<_vSeq>(yforward(args))...)))
139 {
140 return ystdex::invoke(yforward(f), std::get<_vSeq>(yforward(args))...);
141 }
142
144 template<typename _func>
145 static yconstfn auto
146 call(_func&& f, _tParams&&... args) -> decltype(
147 apply_call(yforward(f), std::forward_as_tuple(yforward(args)...)))
148 {
149 return
150 apply_call(yforward(f), std::forward_as_tuple(yforward(args)...));
151 }
152
154 template<typename _fCallable>
155 static yconstfn auto
156 invoke(_fCallable&& f, _tParams&&... args) -> yimpl(decltype(
157 apply_invoke(yforward(f), std::forward_as_tuple(yforward(args)...))))
158 {
159 return apply_invoke(yforward(f),
160 std::forward_as_tuple(yforward(args)...));
161 }
162 };
164
165 #if !(__cpp_lib_make_from_tuple >= 201606L)
166 namespace details
168 {
169
170 template<typename _type, typename _tTuple, size_t... _vSeq>
171 yconstfn _type
172 make_from_tuple_impl(_tTuple&& t, index_sequence<_vSeq...>)
173 {
174 return _type(std::get<_vSeq>(yforward(t))...);
175 }
176
177 } // namespace details;
178 #endif
179
180 inline namespace cpp2017
181 {
182
188 #if __cpp_lib_apply >= 201603L
189 using std::apply;
190 #else
191
197 template<typename _func, class _tTuple>
198 yconstfn auto
199 apply(_func&& f, _tTuple&& t)
200 -> yimpl(decltype(call_projection<_tTuple, make_index_sequence<
201 std::tuple_size<decay_t<_tTuple>>::value>>::apply_invoke(yforward(f),
202 yforward(t))))
203 {
204 return call_projection<_tTuple, make_index_sequence<std::tuple_size<
205 decay_t<_tTuple>>::value>>::apply_invoke(yforward(f), yforward(t));
206 }
207 #endif
208
209 #if __cpp_lib_make_from_tuple >= 201606L
210 using std::make_from_tuple;
211 #else
212
219 template<typename _type, class _tTuple>
220 yconstfn _type
221 make_from_tuple(_tTuple&& t)
222 {
223 return details::make_from_tuple_impl<_type>(yforward(t),
224 make_index_sequence<std::tuple_size<decay_t<_tTuple>>::value>());
225 }
226 #endif
227
228
229 } // inline namespace cpp2017;
230
231 } // namespace ystdex;
232
233 #endif
234
invoke.hpp
可调用对象和调用包装接口。
ystdex::call_projection
调用投影：向原调用传递序列指定的位置的参数。
Definition: apply.hpp:70
ystdex::cpp2017::apply
auto apply(_func &&f, _tTuple &&t) -> decltype(call_projection< _tTuple, make_index_sequence< std::tuple_size< decay_t< _tTuple >>::value >>::apply_invoke(std::forward< decltype(f)>(f), std::forward< decltype(t)>(t)))
应用函数对象和参数元组。
Definition: apply.hpp:199
ystdex::invoke
invoke_result_t< _fCallable, _tParams... > invoke(_fCallable &&f, _tParams &&... args)
调用可调用对象。
Definition: invoke.hpp:538
ystdex::call_projection< std::tuple< _tParams... >, index_sequence< _vSeq... > >::invoke
static auto invoke(_fCallable &&f, _tParams &&... args) -> decltype(apply_invoke(std::forward< decltype(f)>(f), std::forward_as_tuple(std::forward< decltype(args)>(args)...)))
Definition: apply.hpp:156
ystdex::call_projection< std::tuple< _tParams... >, index_sequence< _vSeq... > >::apply_invoke
static auto apply_invoke(_fCallable &&f, std::tuple< _tParams... > &&args) -> decltype(ystdex::invoke(std::forward< decltype(f)>(f), std::get< _vSeq >(std::forward< decltype(args)>(args))...))
Definition: apply.hpp:136
CHRLib::f
f(d, s)
ystdex::call_projection< _tRet(_tParams...), index_sequence< _vSeq... > >::invoke
static auto invoke(_fCallable &&f, _tParams &&... args) -> decltype(apply_invoke(std::forward< decltype(f)>(f), std::forward_as_tuple(std::forward< decltype(args)>(args)...)))
Definition: apply.hpp:109
ystdex::cpp2017::make_from_tuple
_type make_from_tuple(_tTuple &&t)
从元组构造指定类型的值。
Definition: apply.hpp:221
CHRLib::args
YB_ATTR_nodiscard _tParams && args
Definition: CharacterProcessing.h:649
ystdex::cpp2014::decay_t
typename decay< _type >::type decay_t
Definition: meta.hpp:196
ystdex::call_projection< _tRet(_tParams...), index_sequence< _vSeq... > >::apply_call
static auto apply_call(_func &&f, std::tuple< _tParams... > &&args, decay_t< decltype(std::forward< decltype(f)>(f)(std::get< _vSeq >(std::forward< decltype(args)>(args))...))> *={}) -> decltype(std::forward< decltype(f)>(f)(std::get< _vSeq >(std::forward< decltype(args)>(args))...))
Definition: apply.hpp:79
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
ystdex::details::make_from_tuple_impl
_type make_from_tuple_impl(_tTuple &&t, index_sequence< _vSeq... >)
Definition: apply.hpp:172
std
Definition: optional.h:982
ystdex::call_projection< std::tuple< _tParams... >, index_sequence< _vSeq... > >::apply_call
static auto apply_call(_func &&f, std::tuple< _tParams... > &&args) -> decltype(std::forward< decltype(f)>(f)(std::get< _vSeq >(std::forward< decltype(args)>(args))...))
Definition: apply.hpp:127
integer_sequence.hpp
整数序列元编程接口。
ystdex::call_projection< _tRet(_tParams...), index_sequence< _vSeq... > >::apply_invoke
static auto apply_invoke(_fCallable &&f, std::tuple< _tParams... > &&args, decay_t< decltype(ystdex::invoke(std::forward< decltype(f)>(f), std::get< _vSeq >(std::forward< decltype(args)>(args))...))> *={}) -> decltype(ystdex::invoke(std::forward< decltype(f)>(f), std::get< _vSeq >(std::forward< decltype(args)>(args))...))
Definition: apply.hpp:88
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
YSLib::_tParams
YB_ATTR_nodiscard YB_PURE typename _tParams
Definition: ValueNode.h:1294
ystdex::call_projection< _tRet(_tParams...), index_sequence< _vSeq... > >::call
static auto call(_func &&f, _tParams &&... args) -> decltype(apply_call(std::forward< decltype(f)>(f), std::forward_as_tuple(std::forward< decltype(args)>(args)...)))
Definition: apply.hpp:99
ystdex::cpp2014::make_index_sequence
make_integer_sequence< size_t, _vN > make_index_sequence
Definition: integer_sequence.hpp:304
ystdex::cpp2014::integer_sequence
Definition: integer_sequence.hpp:53
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:413
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
ystdex::call_projection< std::tuple< _tParams... >, index_sequence< _vSeq... > >::call
static auto call(_func &&f, _tParams &&... args) -> decltype(apply_call(std::forward< decltype(f)>(f), std::forward_as_tuple(std::forward< decltype(args)>(args)...)))
Definition: apply.hpp:146