YSTest: functor.hpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

functor.hpp
浏览该文件的文档.
1 /*
2 © 2010-2020 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
30 #ifndef YB_INC_ystdex_functor_hpp_
31 #define YB_INC_ystdex_functor_hpp_ 1
32
33 #include "ref.hpp" // for <functional>, enable_if_t, is_detected,
34 // ystdex::addressof, nor_, not_, is_reference_wrapper, and_;
35 #include "type_traits.hpp" // for ystdex::addrof_t, ystdex::indirect_t,
36 // ystdex::first_t, ystdex::second_t;
37 #include <string> // for std::char_traits;
38
39 namespace ystdex
40 {
41
43
44 namespace details
45 {
46
48 template<class _type, typename = void>
49 using mem_is_transparent_t = typename _type::is_transparent;
50
51 } // namespace details;
52
54
55
60 template<typename _type, typename _tDummy = void>
61 struct has_mem_is_transparent
62 : is_detected<details::mem_is_transparent_t, _type, _tDummy>
63 {};
64
73 template<typename _fComp, typename _tDummy, typename _type = void>
74 using enable_if_transparent_t
75 = enable_if_t<has_mem_is_transparent<_fComp, _tDummy>::value, _type>;
77
78
92 template<typename _type = void>
93 struct id
94 {
95 YB_PURE yconstfn _type
96 operator()(const _type& x) const ynothrow
97 {
98 return x;
99 }
100
102 YB_STATELESS yconstfn
103 operator add_ptr_t<_type(_type)>() const ynothrow
104 {
105 return [](_type x) ynothrow -> _type{
106 return x;
107 };
108 }
109 };
110
111 template<>
112 struct id<void>
113 {
114 template<typename _type>
115 YB_PURE yconstfn _type
116 operator()(_type&& x) const ynothrow
117 {
118 return yforward(x);
119 }
120
122 template<typename _type>
123 YB_STATELESS yconstfn
124 operator add_ptr_t<_type(_type)>() const ynothrow
125 {
126 return [](_type x) ynothrow -> _type{
127 return x;
128 };
129 }
130 };
132
133
139 template<typename _type = void>
140 struct addressof_op
141 {
142 yconstfn _type*
143 operator()(_type& x) const ynothrow
144 {
145 return ystdex::addressof(x);
146 }
147 };
148
149 template<>
150 struct addressof_op<void>
151 {
152 template<typename _type>
153 yconstfn _type*
154 operator()(_type& x) const ynothrow
155 {
156 return ystdex::addressof(x);
157 }
158 };
160
161
167 template<typename _type = void>
168 struct mem_get
169 {
170 auto
171 operator()(const _type& x) const -> decltype(x.get())
172 {
173 return yforward(x.get());
174 }
175 };
176
177 template<>
178 struct mem_get<void>
179 {
180 template<typename _type>
181 auto
182 operator()(_type&& x) const ynoexcept_spec(std::declval<_type>().get())
183 -> decltype(x.get())
184 {
185 return yforward(x.get());
186 }
187 };
189
195 struct is_equal
196 {
198 template<typename _type1, typename _type2>
199 yconstfn yimpl(enable_if_t)<nor_<is_reference_wrapper<_type1>,
200 is_reference_wrapper<_type2>>::value, bool>
201 operator()(const _type1& x, const _type2& y) const ynoexcept_spec(x == y)
202 {
203 return x == y;
204 }
206
207 template<typename _type1, typename _type2>
208 yconstfn yimpl(enable_if_t)<and_<is_reference_wrapper<_type1>,
209 not_<is_reference_wrapper<_type2>>>::value, bool>
210 operator()(const _type1& x, const _type2& y) const ynothrow
211 {
212 return ystdex::addressof(x.get()) == ystdex::addressof(y);
213 }
214 template<typename _type1, typename _type2>
215 yconstfn yimpl(enable_if_t)<and_<not_<is_reference_wrapper<_type1>>,
216 is_reference_wrapper<_type2>>::value, bool>
217 operator()(const _type1& x, const _type2& y) const ynothrow
218 {
219 return ystdex::addressof(x) == ystdex::addressof(y.get());
220 }
221 template<typename _type1, typename _type2>
222 yconstfn yimpl(enable_if_t)<and_<is_reference_wrapper<_type1>,
223 is_reference_wrapper<_type2>>::value, bool>
224 operator()(const _type1& x, const _type2& y) const ynothrow
225 {
226 return ystdex::addressof(x.get()) == ystdex::addressof(y.get());
227 }
229 };
230
232
233 // XXX: See $2019-01 @ %Documentation::Workflow.
234 #if YB_IMPL_GNUCPP >= 60000
235 # define YB_Impl_Functor_pushf YB_Diag_Push \
236 YB_Diag_Ignore(suggest-attribute=const) \
237 YB_Diag_Ignore(suggest-attribute=pure)
238 # define YB_Impl_Functor_popf YB_Diag_Pop
239 #else
240 # define YB_Impl_Functor_pushf
241 # define YB_Impl_Functor_popf
242 #endif
243
244
245 // NOTE: There is no 'constexpr' in WG21 N3936; but it is in ISO/IEC 14882:2014
246 // and drafts later.
247 #define YB_Impl_Functor_Ops_Primary(_q, _n, _tRet, _using_stmt, _expr, ...) \
248 template<typename _type = void> \
249 struct _n \
250 { \
251 using first_argument_type = _type; \
252 _using_stmt \
253 using result_type = _tRet; \
254 \
255 YB_Impl_Functor_pushf \
256 yconstfn _tRet \
257 operator()(__VA_ARGS__) const _q \
258 { \
259 return _expr; \
260 } \
261 YB_Impl_Functor_popf \
262 };
263
264 #define YB_Impl_Functor_Ops_Spec(_q, _n, _tparams, _params, _expr) \
265 template<> \
266 struct _n<void> \
267 { \
268 using is_transparent = yimpl(void); \
269 \
270 YB_Impl_Functor_pushf \
271 template<_tparams> \
272 yconstfn auto \
273 operator()(_params) const _q -> decltype(_expr) \
274 { \
275 return _expr; \
276 } \
277 YB_Impl_Functor_popf \
278 };
279
280 // NOTE: Since ISO C++11, the standard does allow change to a stricter
281 // noexcept-specification, see [res.on.exception.handling]. Also note WG21
282 // P0509R1 accepted by WG21 N4664 to resolve GB 41 changes the order of
283 // paragraphs, but not the relevant rule.
284 #define YB_Impl_Functor_Ops_Spec_Ptr(_n) \
285 template<typename _type> \
286 struct _n<_type*> \
287 { \
288 using first_argument_type = _type*; \
289 using second_argument_type = _type*; \
290 using result_type = bool; \
291 \
292 YB_Impl_Functor_pushf \
293 yconstfn bool \
294 operator()(_type* x, _type* y) const yimpl(ynothrow) \
295 { \
296 return std::_n<_type*>()(x, y); \
297 } \
298 YB_Impl_Functor_popf \
299 };
300
301 #define YB_Impl_Functor_Ops_using(_type2) using second_argument_type = _type2;
302
303 #define YB_Impl_Functor_Ops1(_n, _op, _tRet) \
304 YB_Impl_Functor_Ops_Primary(, _n, _tRet, , _op x, const _type& x) \
305 \
306 YB_Impl_Functor_Ops_Spec(, _n, typename _type, _type&& x, _op yforward(x))
307
308 #define YB_Impl_Functor_Ops2(_n, _op, _tRet) \
309 YB_Impl_Functor_Ops_Primary(, _n, _tRet, YB_Impl_Functor_Ops_using(_type), \
310 x _op y, const _type& x, const _type& y) \
311 \
312 YB_Impl_Functor_Ops_Spec(, _n, typename _type1 YPP_Comma typename \
313 _type2, _type1&& x YPP_Comma _type2&& y, yforward(x) _op yforward(y))
314
315 #define YB_Impl_Functor_Binary(_n, _op) \
316 YB_Impl_Functor_Ops2(_n, _op, _type)
317
318 #define YB_Impl_Functor_Unary(_n, _op) \
319 YB_Impl_Functor_Ops1(_n, _op, _type)
320
322 inline namespace cpp2014
323 {
324
325 #if __cpp_lib_transparent_operators >= 201210L
326 using std::plus;
327 using std::minus;
328 using std::multiplies;
329 using std::divides;
330 using std::modulus;
331 using std::negate;
332
333 using std::equal_to;
334 using std::not_equal_to;
335 using std::greater;
337 using std::less;
338 using std::greater_equal;
339 using std::less_equal;
340
341 using std::logical_and;
342 using std::logical_or;
343 using std::logical_not;
344
345 using std::bit_and;
347 using std::bit_or;
348 using std::bit_xor;
349 using std::bit_not;
350 #else
351
356 YB_Impl_Functor_Binary(plus, +)
358
359 YB_Impl_Functor_Binary(minus, -)
361
362 YB_Impl_Functor_Binary(multiplies, *)
364
365
369 YB_Impl_Functor_Binary(divides, /)
370
372 YB_Impl_Functor_Binary(modulus, %)
373
378 YB_Impl_Functor_Unary(negate, -)
379
380 #define YB_Impl_Functor_bool(_n, _op) \
381 YB_Impl_Functor_Ops2(_n, _op, bool)
382
383 #define YB_Impl_Functor_bool_Ordered(_n, _op) \
384 YB_Impl_Functor_bool(_n, _op) \
385 \
386 YB_Impl_Functor_Ops_Spec_Ptr(_n)
387
389 YB_Impl_Functor_bool(equal_to, ==)
390
391 YB_Impl_Functor_bool(not_equal_to, !=)
393
395 YB_Impl_Functor_bool_Ordered(greater, >)
396
398 YB_Impl_Functor_bool_Ordered(less, <)
399
401 YB_Impl_Functor_bool_Ordered(greater_equal, >=)
402
404 YB_Impl_Functor_bool_Ordered(less_equal, <=)
405
407
408 YB_Impl_Functor_bool(logical_and, &&)
410
412 YB_Impl_Functor_bool(logical_or, ||)
413
415 YB_Impl_Functor_Ops1(logical_not, !, bool)
416
418 YB_Impl_Functor_Binary(bit_and, &)
419
421 YB_Impl_Functor_Binary(bit_or, |)
422
424 YB_Impl_Functor_Binary(bit_xor, ^)
425
427 // NOTE: Available in %std since ISO C++14.
428 YB_Impl_Functor_Unary(bit_not, ~)
430
431 #endif
432
433 } // inline namespace cpp2014;
434
440 YB_Impl_Functor_Ops1(addrof, &, addrof_t<const _type&>)
442
443 YB_Impl_Functor_Ops1(indirect, *, indirect_t<const _type&>)
445
446
448 YB_Impl_Functor_Ops_Primary(ynothrow, ref_eq, bool,
449 YB_Impl_Functor_Ops_using(_type), ystdex::addressof(x)
450 == ystdex::addressof(y), const _type& x, const _type& y)
451
452 YB_Impl_Functor_Ops_Spec(ynothrow, ref_eq,
454 typename _type1 YPP_Comma typename _type2, _type1&& x YPP_Comma _type2&& y,
455 ystdex::addressof(yforward(x)) == ystdex::addressof(yforward(y)))
457
459
460 YB_Impl_Functor_Ops_Primary(ynothrow, first_of, first_t<_type&>, , x.first,
461 _type& x)
462
463 // NOTE: More parentheses are needed to keep the correct value category.
464 YB_Impl_Functor_Ops_Spec(ynothrow, first_of, typename _type, _type&& x,
465 yforward((x.first)))
466
467 YB_Impl_Functor_Ops_Primary(ynothrow, second_of, second_t<_type&>, , x.second,
468 _type& x)
469
470 // NOTE: More parentheses are needed to keep the correct value category.
471 YB_Impl_Functor_Ops_Spec(ynothrow, second_of, typename _type, _type&& x,
472 yforward((x.second)))
474
475
476 #undef YB_Impl_Functor_bool_Ordered
477 #undef YB_Impl_Functor_bool
478 #undef YB_Impl_Functor_Unary
479 #undef YB_Impl_Functor_Binary
480 #undef YB_Impl_Functor_Ops2
481 #undef YB_Impl_Functor_Ops1
482 #undef YB_Impl_Functor_Ops_using
483 #undef YB_Impl_Functor_Ops_Spec
484 #undef YB_Impl_Functor_Ops_Primary
485 #undef YB_Impl_Functor_popf
486 #undef YB_Impl_Functor_pushf
487
488
490
491 template<bool, typename _tScalar>
492 struct xcrease_t
493 {
495 inline _tScalar&
496 operator()(_tScalar& _x) const
497 {
498 return ++_x;
499 }
500 };
501 template<typename _tScalar>
502 struct xcrease_t<false, _tScalar>
503 {
505 inline _tScalar&
506 operator()(_tScalar& _x) const
507 {
508 return --_x;
509 }
510 };
512
518 template<bool, typename _tScalar1, typename _tScalar2>
519 struct delta_assignment
520 {
521 yconstfn _tScalar1&
522 operator()(_tScalar1& x, _tScalar2 y) const
523 {
524 return x += y;
525 }
526 };
527 template<typename _tScalar1, typename _tScalar2>
528 struct delta_assignment<false, _tScalar1, _tScalar2>
529 {
530 yconstfn _tScalar1&
531 operator()(_tScalar1& x, _tScalar2 y) const
532 {
533 return x -= y;
534 }
535 };
537
539 template<bool _bIsPositive, typename _tScalar>
540 yconstfn _tScalar&
541 xcrease(_tScalar& _x)
542 {
543 return xcrease_t<_bIsPositive, _tScalar>()(_x);
544 }
545
550 template<bool _bIsPositive, typename _tScalar1, typename _tScalar2>
551 yconstfn _tScalar1&
552 delta_assign(_tScalar1& _x, _tScalar2& _y)
553 {
554 return delta_assignment<_bIsPositive, _tScalar1, _tScalar2>()(_x, _y);
555 }
557
558 } // namespace ystdex;
559
560 #endif
561
YB_Impl_Functor_bool_Ordered
#define YB_Impl_Functor_bool_Ordered(_n, _op)
Definition: functor.hpp:383
ystdex::is_equal::operator()
enable_if_t< and_< is_reference_wrapper< _type1 >, not_< is_reference_wrapper< _type2 > > >::value, bool > operator()(const _type1 &x, const _type2 &y) const
Definition: functor.hpp:210
x
const EncapsulationBase & x
Definition: NPLA1Forms.cpp:1536
type_traits.hpp
ISO C++ 类型特征扩展。
ystdex::is_equal::operator()
enable_if_t< and_< not_< is_reference_wrapper< _type1 > >, is_reference_wrapper< _type2 > >::value, bool > operator()(const _type1 &x, const _type2 &y) const
Definition: functor.hpp:217
ystdex::xcrease_t< false, _tScalar >::operator()
_tScalar & operator()(_tScalar &_x) const
Definition: functor.hpp:506
YB_PURE
#define YB_PURE
指示函数或函数模板实例为纯函数。
Definition: ydef.h:919
ystdex::addrof_t
decltype(&std::declval< _type >()) addrof_t
Definition: type_traits.hpp:66
YB_Impl_Functor_bool
#define YB_Impl_Functor_bool(_n, _op)
Definition: functor.hpp:380
ystdex::cpp2014::greater_equal
大于等于关系仿函数。
Definition: functor.hpp:401
ref.hpp
引用包装。
ystdex::xcrease_t
选择自增/自减运算仿函数。
Definition: functor.hpp:493
ystdex::cpp2014::logical_not
逻辑非仿函数。
Definition: functor.hpp:415
ystdex::addrof
一元 & 操作。
Definition: functor.hpp:441
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: meta.hpp:199
ystdex::addressof_op::operator()
_type * operator()(_type &x) const
Definition: functor.hpp:143
ystdex::has_mem_is_transparent
判断 _type 是否包含 is_transparent 成员类型。
Definition: functor.hpp:63
ystdex::mem_get
成员 get 操作。
Definition: functor.hpp:169
ystdex::cpp2014::equal_to
等于关系仿函数。
Definition: functor.hpp:389
ystdex::cpp2014::less
小于关系仿函数。
Definition: functor.hpp:398
YB_Impl_Functor_Binary
#define YB_Impl_Functor_Binary(_n, _op)
Definition: functor.hpp:315
ystdex::first_t
decltype(std::declval< _type >().first) first_t
Definition: type_traits.hpp:105
ynoexcept_spec
#define ynoexcept_spec(...)
表达式 noexcept 异常规范。
Definition: ydef.h:1181
ystdex::cpp2014::bit_and
位与仿函数。
Definition: functor.hpp:418
ystdex::indirect
一元 * 操作。
Definition: functor.hpp:444
ystdex::delta_assignment
选择加法/减法复合赋值运算仿函数。
Definition: functor.hpp:520
YPP_Comma
#define YPP_Comma
替换为逗号的预处理记号。
Definition: ydef.h:370
ystdex::is_equal
相等关系仿函数。
Definition: functor.hpp:196
ystdex::mem_get::operator()
auto operator()(const _type &x) const -> decltype(x.get())
Definition: functor.hpp:171
ystdex::cpp2014::not_equal_to
不等于关系仿函数。
Definition: functor.hpp:392
ystdex::indirect_t
decltype(*std::declval< _type >()) indirect_t
Definition: type_traits.hpp:69
ystdex::details::_type2
_type2
Definition: operators.hpp:241
ystdex::xcrease_t::operator()
_tScalar & operator()(_tScalar &_x) const
Definition: functor.hpp:496
YB_Impl_Functor_Unary
#define YB_Impl_Functor_Unary(_n, _op)
Definition: functor.hpp:318
ystdex::mem_get< void >::operator()
auto operator()(_type &&x) const -> decltype(x.get())
Definition: functor.hpp:182
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
ystdex::addressof_op< void >::operator()
_type * operator()(_type &x) const
Definition: functor.hpp:154
YB_STATELESS
#define YB_STATELESS
指示函数或函数模板实例为无状态函数。
Definition: ydef.h:941
ystdex::enable_if_transparent_t
enable_if_t< has_mem_is_transparent< _fComp, _tDummy >::value, _type > enable_if_transparent_t
移除不满足包含 is_transparent 成员类型比较器的重载。
Definition: functor.hpp:75
ystdex::id::operator()
_type operator()(const _type &x) const
Definition: functor.hpp:96
ystdex::delta_assignment< false, _tScalar1, _tScalar2 >::operator()
_tScalar1 & operator()(_tScalar1 &x, _tScalar2 y) const
Definition: functor.hpp:531
ystdex::is_equal::operator()
enable_if_t< and_< is_reference_wrapper< _type1 >, is_reference_wrapper< _type2 > >::value, bool > operator()(const _type1 &x, const _type2 &y) const
Definition: functor.hpp:224
ystdex::id< void >::operator()
_type operator()(_type &&x) const
Definition: functor.hpp:116
ystdex::is_reference_wrapper
判断模板参数指定的类型是否为引用包装的实例。
Definition: ref.hpp:150
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
ystdex::cpp2014::bit_or
位或仿函数。
Definition: functor.hpp:421
ystdex::ref_eq
引用等价关系仿函数。
Definition: functor.hpp:450
YB_Impl_Functor_Ops1
#define YB_Impl_Functor_Ops1(_n, _op, _tRet)
Definition: functor.hpp:303
YB_Impl_Functor_Ops_Spec
#define YB_Impl_Functor_Ops_Spec(_q, _n, _tparams, _params, _expr)
Definition: functor.hpp:264
ystdex::cpp2014::greater
大于关系仿函数。
Definition: functor.hpp:395
ystdex::cpp2014::divides
除法仿函数。
Definition: functor.hpp:369
ystdex::cpp2014::logical_and
逻辑与仿函数。
Definition: functor.hpp:409
ystdex::cpp2014::bit_xor
位异或仿函数。
Definition: functor.hpp:424
ystdex::first_of
Definition: functor.hpp:461
ystdex::delta_assign
_tScalar1 & delta_assign(_tScalar1 &_x, _tScalar2 &_y)
选择加法/减法复合赋值运算。
Definition: functor.hpp:552
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
ystdex::delta_assignment::operator()
_tScalar1 & operator()(_tScalar1 &x, _tScalar2 y) const
Definition: functor.hpp:522
ystdex::id
恒等仿函数。
Definition: functor.hpp:94
YB_Impl_Functor_Ops_Primary
#define YB_Impl_Functor_Ops_Primary(_q, _n, _tRet, _using_stmt, _expr,...)
Definition: functor.hpp:247
ystdex::addressof
enable_if_t< has_no_overloaded_addressof< _type >::value, _type * > addressof(_type &r)
尝试对非重载 operator& 提供 constexpr 的 std::addressof 替代。
Definition: addressof.hpp:131
ystdex::cpp2014::modulus
模运算仿函数。
Definition: functor.hpp:372
ystdex::cpp2014::less_equal
小于等于关系仿函数。
Definition: functor.hpp:404
ystdex::cpp2014::bit_not
位取反仿函数。
Definition: functor.hpp:428
ystdex::cpp2014::logical_or
逻辑或仿函数。
Definition: functor.hpp:412
ystdex::is_detected
typename details::detector< nonesuch, void, _gOp, _tParams... >::value_t is_detected
Definition: meta.hpp:396
ystdex::second_of
Definition: functor.hpp:468
ystdex::details::mem_is_transparent_t
typename _type::is_transparent mem_is_transparent_t
Definition: functor.hpp:49
YB_Impl_Functor_Ops_using
#define YB_Impl_Functor_Ops_using(_type2)
Definition: functor.hpp:301
ystdex::second_t
decltype(std::declval< _type >().second) second_t
Definition: type_traits.hpp:108
ystdex::addressof_op
ystdex::addressof 仿函数。
Definition: functor.hpp:141
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:413
ystdex::add_ptr_t
_type * add_ptr_t
Definition: type_traits.hpp:53
ystdex::not_
逻辑非。
Definition: integral_constant.hpp:193
ystdex::cpp2014::negate
取反仿函数。
Definition: functor.hpp:378
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:1199
NPL::get
PDefH(void, LiftTermRef, TermNode &term, const TermNode &tm) ImplExpr(NPL ref get()
Definition: NPLA.h:1737
ystdex::xcrease
_tScalar & xcrease(_tScalar &_x)
选择自增/自减运算。
Definition: functor.hpp:541
ystdex::is_equal::operator()
enable_if_t< nor_< is_reference_wrapper< _type1 >, is_reference_wrapper< _type2 > >::value, bool > operator()(const _type1 &x, const _type2 &y) const
Definition: functor.hpp:201
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
ystdex::nor_
逻辑或非。
Definition: integral_constant.hpp:207
ystdex::and_
逻辑操作元函数。
Definition: integral_constant.hpp:151