YSTest: functor.hpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

functor.hpp
浏览该文件的文档.
1 /*
2 © 2010-2017 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 enable_if_t, is_detected, ystdex::constfn_addressof,
34 // not_, or_, is_reference_wrapper, and_, std::greater, std::less,
35 // std::greater_equal, std::less_equal, addrof_t, indirect_t;
36 #include <string> // for std::char_traits;
37 #include <algorithm> // for std::lexicographical_compare;
38
39 #if YB_IMPL_MSCPP >= 1900
40
45 # ifndef __cpp_lib_robust_nonmodifying_seq_ops
46 # define __cpp_lib_robust_nonmodifying_seq_ops 201304
47 # endif
48 #endif
49
50 namespace ystdex
51 {
52
54
55 namespace details
56 {
57
59 template<class _type, typename = void>
60 using mem_is_transparent_t = typename _type::is_transparent;
61
62 } // namespace details;
63
65
66
71 template<typename _type, typename _tDummy = void>
72 struct has_mem_is_transparent
73 : is_detected<details::mem_is_transparent_t, _type, _tDummy>
74 {};
75
84 template<typename _fComp, typename _tDummy, typename _type = void>
85 using enable_if_transparent_t
86 = enable_if_t<has_mem_is_transparent<_fComp, _tDummy>::value, _type>;
88
89
101 template<typename _type = void>
102 struct id
103 {
104 yconstfn _type
105 operator()(const _type& x) const ynothrow
106 {
107 return x;
108 }
109
111 yconstfn
112 operator add_ptr_t<_type(_type)>() const ynothrow
113 {
114 return [](_type x) ynothrow -> _type{
115 return x;
116 };
117 }
118 };
119
120 template<>
121 struct id<void>
122 {
123 template<typename _type>
124 yconstfn _type
125 operator()(_type&& x) const ynothrow
126 {
127 return yforward(x);
128 }
129
131 template<typename _type>
132 yconstfn
133 operator add_ptr_t<_type(_type)>() const ynothrow
134 {
135 return [](_type x) ynothrow -> _type{
136 return x;
137 };
138 }
139 };
141
142
148 template<typename _type = void>
149 struct addressof_op
150 {
151 yconstfn _type*
152 operator()(_type& x) const ynothrow
153 {
154 return ystdex::constfn_addressof(x);
155 }
156 };
157
158 template<>
159 struct addressof_op<void>
160 {
161 template<typename _type>
162 yconstfn _type*
163 operator()(_type& x) const ynothrow
164 {
165 return ystdex::constfn_addressof(x);
166 }
167 };
169
170
176 template<typename _type = void>
177 struct mem_get
178 {
179 auto
180 operator()(const _type& x) const -> decltype(x.get())
181 {
182 return yforward(x.get());
183 }
184 };
185
186 template<>
187 struct mem_get<void>
188 {
189 template<typename _type>
190 auto
191 operator()(_type&& x) const ynoexcept_spec(std::declval<_type&&>().get())
192 -> decltype(x.get())
193 {
194 return yforward(x.get());
195 }
196 };
198
204 struct is_equal
205 {
207 template<typename _type1, typename _type2>
208 yconstfn yimpl(enable_if_t)<not_<or_<is_reference_wrapper<_type1>,
209 is_reference_wrapper<_type2>>>::value, bool>
210 operator()(const _type1& x, const _type2& y) const ynoexcept_spec(x == y)
211 {
212 return x == y;
213 }
215
216 template<typename _type1, typename _type2>
217 yconstfn yimpl(enable_if_t)<and_<is_reference_wrapper<_type1>,
218 not_<is_reference_wrapper<_type2>>>::value, bool>
219 operator()(const _type1& x, const _type2& y) const ynothrow
220 {
221 return std::addressof(x.get()) == std::addressof(y);
222 }
223 template<typename _type1, typename _type2>
224 yconstfn yimpl(enable_if_t)<and_<not_<is_reference_wrapper<_type1>>,
225 is_reference_wrapper<_type2>>::value, bool>
226 operator()(const _type1& x, const _type2& y) const ynothrow
227 {
228 return std::addressof(x) == std::addressof(y.get());
229 }
230 template<typename _type1, typename _type2>
231 yconstfn yimpl(enable_if_t)<and_<is_reference_wrapper<_type1>,
232 is_reference_wrapper<_type2>>::value, bool>
233 operator()(const _type1& x, const _type2& y) const ynothrow
234 {
235 return std::addressof(x.get()) == std::addressof(y.get());
236 }
238 };
239
241 template<typename _type>
242 struct ref_eq
243 {
244 yconstfn bool
245 operator()(const _type& _x, const _type& _y) const
246 {
247 return &_x == &_y;
248 }
249 };
250
251 // NOTE: There is 'constexpr' in WG21 N3936; but it is in ISO/IEC 14882:2014.
252 #define YB_Impl_Functor_Ops_Primary(_n, _tRet, _using_stmt, _expr, ...) \
253 template<typename _type = void> \
254 struct _n \
255 { \
256 using first_argument_type = _type; \
257 _using_stmt \
258 using result_type = _tRet; \
259 \
260 yconstfn _tRet \
261 operator()(__VA_ARGS__) const \
262 { \
263 return _expr; \
264 } \
265 };
266
267 #define YB_Impl_Functor_Ops_Spec(_n, _tparams, _params, _expr) \
268 template<> \
269 struct _n<void> \
270 { \
271 using is_transparent = yimpl(void); \
272 \
273 template<_tparams> \
274 yconstfn auto \
275 operator()(_params) const -> decltype(_expr) \
276 { \
277 return _expr; \
278 } \
279 };
280
281 #define YB_Impl_Functor_Ops_Spec_Ptr(_n) \
282 template<typename _type> \
283 struct _n<_type*> \
284 { \
285 using first_argument_type = _type*; \
286 using second_argument_type = _type*; \
287 using result_type = bool; \
288 \
289 yconstfn bool \
290 operator()(_type* x, _type* y) const \
291 { \
292 return std::_n<_type*>()(x, y); \
293 } \
294 };
295
296 #define YB_Impl_Functor_Ops_using(_tRet) using second_argument_type = _tRet;
297
298 #define YB_Impl_Functor_Ops1(_n, _op, _tRet) \
299 YB_Impl_Functor_Ops_Primary(_n, _tRet, , _op x, const _type& x) \
300 \
301 YB_Impl_Functor_Ops_Spec(_n, typename _type, _type&& x, _op yforward(x))
302
303 #define YB_Impl_Functor_Ops2(_n, _op, _tRet) \
304 YB_Impl_Functor_Ops_Primary(_n, _tRet, \
305 YB_Impl_Functor_Ops_using(_tRet), x _op y, const _type& x, \
306 const _type& y) \
307 \
308 YB_Impl_Functor_Ops_Spec(_n, typename _type1 YPP_Comma typename \
309 _type2, _type1&& x YPP_Comma _type2&& y, yforward(x) _op yforward(y))
310
311 #define YB_Impl_Functor_Binary(_n, _op) \
312 YB_Impl_Functor_Ops2(_n, _op, _type)
313
314 #define YB_Impl_Functor_Unary(_n, _op) \
315 YB_Impl_Functor_Ops1(_n, _op, _type)
316
318 inline namespace cpp2014
319 {
320
321 #if __cpp_lib_transparent_operators >= 201210 || __cplusplus >= 201402L
322 using std::plus;
323 using std::minus;
324 using std::multiplies;
325 using std::divides;
326 using std::modulus;
327 using std::negate;
328
329 using std::equal_to;
330 using std::not_equal_to;
331 using std::greater;
333 using std::less;
334 using std::greater_equal;
335 using std::less_equal;
336
337 using std::logical_and;
338 using std::logical_or;
339 using std::logical_not;
340
341 using std::bit_and;
343 using std::bit_or;
344 using std::bit_xor;
345 using std::bit_not;
346 #else
347
352 YB_Impl_Functor_Binary(plus, +)
354
355 YB_Impl_Functor_Binary(minus, -)
357
358 YB_Impl_Functor_Binary(multiplies, *)
360
361
365 YB_Impl_Functor_Binary(divides, /)
366
368 YB_Impl_Functor_Binary(modulus, %)
369
374 YB_Impl_Functor_Unary(negate, -)
375
376 #define YB_Impl_Functor_bool(_n, _op) \
377 YB_Impl_Functor_Ops2(_n, _op, bool)
378
379 #define YB_Impl_Functor_bool_Ordered(_n, _op) \
380 YB_Impl_Functor_bool(_n, _op) \
381 \
382 YB_Impl_Functor_Ops_Spec_Ptr(_n)
383
385 YB_Impl_Functor_bool(equal_to, ==)
386
387 YB_Impl_Functor_bool(not_equal_to, !=)
389
391 YB_Impl_Functor_bool_Ordered(greater, >)
392
394 YB_Impl_Functor_bool_Ordered(less, <)
395
397 YB_Impl_Functor_bool_Ordered(greater_equal, >=)
398
400 YB_Impl_Functor_bool_Ordered(less_equal, <=)
401
403
404 YB_Impl_Functor_bool(logical_and, &&)
406
408 YB_Impl_Functor_bool(logical_or, ||)
409
411 YB_Impl_Functor_Ops1(logical_not, !, bool)
412
414 YB_Impl_Functor_Binary(bit_and, &)
415
417 YB_Impl_Functor_Binary(bit_or, |)
418
420 YB_Impl_Functor_Binary(bit_xor, ^)
421
423 // NOTE: Available in %std since ISO C++14.
424 YB_Impl_Functor_Unary(bit_not, ~)
426
427 #endif
428
429 } // inline namespace cpp2014;
430
436 YB_Impl_Functor_Ops1(addrof, &, addrof_t<const _type&>)
438
439 YB_Impl_Functor_Ops1(indirect, *, indirect_t<const _type&>)
442
443 #undef YB_Impl_Functor_bool_Ordered
444 #undef YB_Impl_Functor_bool
445 #undef YB_Impl_Functor_Unary
446 #undef YB_Impl_Functor_Binary
447 #undef YB_Impl_Functor_Ops2
448 #undef YB_Impl_Functor_Ops1
449 #undef YB_Impl_Functor_Ops_using
450 #undef YB_Impl_Functor_Ops_Spec
451 #undef YB_Impl_Functor_Ops_Primary
452
453
455
456 template<bool, typename _tScalar>
457 struct xcrease_t
458 {
460 inline _tScalar&
461 operator()(_tScalar& _x) const
462 {
463 return ++_x;
464 }
465 };
466 template<typename _tScalar>
467 struct xcrease_t<false, _tScalar>
468 {
470 inline _tScalar&
471 operator()(_tScalar& _x) const
472 {
473 return --_x;
474 }
475 };
477
483 template<bool, typename _tScalar1, typename _tScalar2>
484 struct delta_assignment
485 {
486 yconstfn _tScalar1&
487 operator()(_tScalar1& x, _tScalar2 y) const
488 {
489 return x += y;
490 }
491 };
492 template<typename _tScalar1, typename _tScalar2>
493 struct delta_assignment<false, _tScalar1, _tScalar2>
494 {
495 yconstfn _tScalar1&
496 operator()(_tScalar1& x, _tScalar2 y) const
497 {
498 return x -= y;
499 }
500 };
502
504 template<bool _bIsPositive, typename _tScalar>
505 yconstfn _tScalar&
506 xcrease(_tScalar& _x)
507 {
508 return xcrease_t<_bIsPositive, _tScalar>()(_x);
509 }
510
515 template<bool _bIsPositive, typename _tScalar1, typename _tScalar2>
516 yconstfn _tScalar1&
517 delta_assign(_tScalar1& _x, _tScalar2& _y)
518 {
519 return delta_assignment<_bIsPositive, _tScalar1, _tScalar2>()(_x, _y);
520 }
522
523 } // namespace ystdex;
524
525 #endif
526
YB_Impl_Functor_bool
#define YB_Impl_Functor_bool(_n, _op)
Definition: functor.hpp:376
ystdex::cpp2014::bit_not
位取反仿函数。
Definition: functor.hpp:424
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:680
ystdex::constfn_addressof
enable_if_t<!has_overloaded_addressof< _type >::value, _type * > constfn_addressof(_type &r)
尝试对非重载 operator& 提供 constexpr 的 std::addressof 替代。
Definition: addressof.hpp:78
ystdex::cpp2014::bit_and
位与仿函数。
Definition: functor.hpp:414
ystdex::details::mem_is_transparent_t
typename _type::is_transparent mem_is_transparent_t
Definition: functor.hpp:60
YB_Impl_Functor_Ops1
#define YB_Impl_Functor_Ops1(_n, _op, _tRet)
Definition: functor.hpp:298
ystdex::addrof_t
decltype(&std::declval< _type >()) addrof_t
Definition: type_traits.hpp:1034
ystdex::delta_assign
_tScalar1 & delta_assign(_tScalar1 &_x, _tScalar2 &_y)
选择加法/减法复合赋值运算。
Definition: functor.hpp:517
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
NPL::x
const TermNode &term ynothrow const TermNode &term ynothrow const TermNode &term ynothrow TermNode &term const TermNode &term ValueNode &node const ValueNode &node const _type & x
Definition: SContext.h:94
ystdex::indirect_t
decltype(*std::declval< _type >()) indirect_t
Definition: type_traits.hpp:1037
ystdex::not_
Definition: type_traits.hpp:456
ystdex::delta_assignment
选择加法/减法复合赋值运算仿函数。
Definition: functor.hpp:484
ynoexcept_spec
#define ynoexcept_spec(...)
表达式 noexcept 异常规范。
Definition: ydef.h:794
ystdex::add_ptr_t
_type * add_ptr_t
Definition: type_traits.hpp:1021
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:262
ystdex::indirect
一元 * 操作。
Definition: functor.hpp:440
ystdex::addressof_op< void >::operator()
_type * operator()(_type &x) const
Definition: functor.hpp:163
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: type_traits.hpp:343
ystdex::delta_assignment< false, _tScalar1, _tScalar2 >::operator()
_tScalar1 & operator()(_tScalar1 &x, _tScalar2 y) const
Definition: functor.hpp:496
YB_Impl_Functor_Binary
#define YB_Impl_Functor_Binary(_n, _op)
Definition: functor.hpp:311
ystdex::addressof_op::operator()
_type * operator()(_type &x) const
Definition: functor.hpp:152
ystdex::is_reference_wrapper
判断模板参数指定的类型是否。
Definition: ref.hpp:161
ystdex::ref_eq::operator()
bool operator()(const _type &_x, const _type &_y) const
Definition: functor.hpp:245
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:219
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:233
YB_Impl_Functor_bool_Ordered
#define YB_Impl_Functor_bool_Ordered(_n, _op)
Definition: functor.hpp:379
ystdex::xcrease_t
选择自增/自减运算仿函数。
Definition: functor.hpp:457
ystdex::id::operator()
_type operator()(const _type &x) const
Definition: functor.hpp:105
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:766
ystdex::xcrease
_tScalar & xcrease(_tScalar &_x)
选择自增/自减运算。
Definition: functor.hpp:506
ystdex
特性测试宏。
Definition: ydef.h:822
ystdex::mem_get< void >::operator()
auto operator()(_type &&x) const -> decltype(x.get())
Definition: functor.hpp:191
ystdex::cpp2014::greater
大于关系仿函数。
Definition: functor.hpp:391
ystdex::has_mem_is_transparent
判断 _type 是否包含 is_transparent 成员类型。
Definition: functor.hpp:72
ystdex::id
恒等仿函数。
Definition: functor.hpp:102
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:86
ref.hpp
引用包装。
ystdex::cpp2014::not_equal_to
不等于关系仿函数。
Definition: functor.hpp:388
ystdex::cpp2014::negate
取反仿函数。
Definition: functor.hpp:374
ystdex::mem_get::operator()
auto operator()(const _type &x) const -> decltype(x.get())
Definition: functor.hpp:180
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:226
ystdex::cpp2014::bit_or
位或仿函数。
Definition: functor.hpp:417
ystdex::is_equal::operator()
enable_if_t< not_< or_< is_reference_wrapper< _type1 >, is_reference_wrapper< _type2 > > >::value, bool > operator()(const _type1 &x, const _type2 &y) const
Definition: functor.hpp:210
std
Definition: memory.hpp:1183
ystdex::ref_eq
引用相等关系仿函数。
Definition: functor.hpp:242
ystdex::is_equal
相等关系仿函数。
Definition: functor.hpp:204
ystdex::id< void >::operator()
_type operator()(_type &&x) const
Definition: functor.hpp:125
ystdex::cpp2014::logical_or
逻辑或仿函数。
Definition: functor.hpp:408
ystdex::cpp2014::modulus
模运算仿函数。
Definition: functor.hpp:368
ystdex::xcrease_t< false, _tScalar >::operator()
_tScalar & operator()(_tScalar &_x) const
Definition: functor.hpp:471
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:995
ystdex::addrof
一元 & 操作。
Definition: functor.hpp:437
ystdex::cpp2014::logical_not
逻辑非仿函数。
Definition: functor.hpp:411
ystdex::cpp2014::less
小于关系仿函数。
Definition: functor.hpp:394
ystdex::is_detected
typename details::detector< nonesuch, void, _gOp, _tParams... >::value_t is_detected
Definition: type_traits.hpp:708
ystdex::cpp2014::less_equal
小于等于关系仿函数。
Definition: functor.hpp:400
YB_Impl_Functor_Unary
#define YB_Impl_Functor_Unary(_n, _op)
Definition: functor.hpp:314
ystdex::addressof_op
std::addressof 仿函数。
Definition: functor.hpp:149
ystdex::and_
逻辑操作元函数。
Definition: type_traits.hpp:420
ystdex::xcrease_t::operator()
_tScalar & operator()(_tScalar &_x) const
Definition: functor.hpp:461
ystdex::cpp2014::logical_and
逻辑与仿函数。
Definition: functor.hpp:405
ystdex::mem_get
成员 get 操作。
Definition: functor.hpp:177
ystdex::delta_assignment::operator()
_tScalar1 & operator()(_tScalar1 &x, _tScalar2 y) const
Definition: functor.hpp:487
ystdex::cpp2014::bit_xor
位异或仿函数。
Definition: functor.hpp:420
ystdex::cpp2014::equal_to
等于关系仿函数。
Definition: functor.hpp:385
ystdex::cpp2014::divides
除法仿函数。
Definition: functor.hpp:365
ystdex::cpp2014::greater_equal
大于等于关系仿函数。
Definition: functor.hpp:397
ystdex::details::get
get())
Definition: cast.hpp:102