YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
operators.hpp
浏览该文件的文档.
1 /*
2  © 2011-2014 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_operators_hpp_
31 #define YB_INC_ystdex_operators_hpp_ 1
32 
33 #include "../ydef.h"
34 
35 namespace ystdex
36 {
37 
38 #define YB_OP_FRIEND(_op, _tRet, _expr, ...) \
39  friend yconstfn _tRet \
40  operator _op (__VA_ARGS__) {return (_expr);}
41 #define YB_OP_TEMPLATE_HEADER2(_name) \
42  template<class _type, class _type2, class _tBase = empty_base<_type>> \
43  struct _name
44 #define YB_OP_TEMPLATE_HEADER1(_name) \
45  template<class _type, class _tBase = empty_base<_type>> \
46  struct _name
47 
48 
49 namespace details
50 {
51 
52 #define YB_OP_COMPARE2(_op, _expr, _param_type, _param_type2) \
53  YB_OP_FRIEND(_op, bool, _expr, const _param_type& x, \
54  const _param_type2& y)
55 #define YB_OP_COMPARE1(_op, _expr, _param_type) \
56  YB_OP_FRIEND(_op, bool, _expr, const _param_type& x, \
57  const _param_type& y)
58 
59 
61 {
62  YB_OP_COMPARE2(<=, !bool(x > y), _type, _type2)
63  YB_OP_COMPARE2(>=, !bool(x < y), _type, _type2)
64  YB_OP_COMPARE2(>, y < x, _type2, _type)
65  YB_OP_COMPARE2(<, y > x, _type2, _type)
66  YB_OP_COMPARE2(<=, !bool(y < x), _type2, _type)
67  YB_OP_COMPARE2(>=, !bool(y > x), _type2, _type)
68 };
69 
71 {
72  YB_OP_COMPARE1(>, y < x, _type)
73  YB_OP_COMPARE1(<=, !bool(y < x), _type)
74  YB_OP_COMPARE1(>=, !bool(x < y), _type)
75 };
76 
77 
79 {
80  YB_OP_COMPARE2(==, x == y, _type2, _type)
81  YB_OP_COMPARE2(!=, !bool(x == y), _type2, _type)
82  YB_OP_COMPARE2(!=, !bool(y == x), _type, _type2)
83 };
84 
86 {
87  YB_OP_COMPARE1(!=, !bool(x == y), _type)
88 };
89 
90 
92 {
93  YB_OP_COMPARE2(!=, !bool(x < y) && !bool(x > y), _type, _type2)
94 };
95 
97 {
98  YB_OP_COMPARE1(!=, !bool(x < y) && !bool(y < x), _type)
99 };
100 
101 
103 {
104  YB_OP_COMPARE2(<=, bool(x < y) || bool(x == y), _type, _type2)
105  YB_OP_COMPARE2(>=, bool(x > y) || bool(x == y), _type, _type2)
106  YB_OP_COMPARE2(>, y < x, _type2, _type)
107  YB_OP_COMPARE2(<, y > x, _type2, _type)
108  YB_OP_COMPARE2(<=, bool(y > x) || bool(y == x), _type2, _type)
109  YB_OP_COMPARE2(>=, bool(y < x) || bool(y == x), _type2, _type)
110 };
111 
113 {
114  YB_OP_COMPARE1(>, y < x, _type)
115  YB_OP_COMPARE1(<=, bool(x < y) || bool(x == y), _type)
116  YB_OP_COMPARE1(>=, bool(y < x) || bool(x == y), _type)
117 };
118 
119 #undef YB_OP_COMPARE2
120 #undef YB_OP_COMPARE1
121 
122 
123 #define YB_OP_COMMUTATIVE(_name, _op) \
124  YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
125  { \
126  YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type2& y) \
127  YB_OP_FRIEND(_op, _type, y _op##= x, const _type2& x, _type y) \
128  }; \
129  YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
130  { \
131  YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
132  };
133 
134 #define YB_OP_NON_COMMUTATIVE(_name, _op) \
135  YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
136  { \
137  YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type2& y) \
138  }; \
139  YB_OP_TEMPLATE_HEADER2(_name##2##_##left) : _tBase \
140  { \
141  YB_OP_FRIEND(_op, _type, _type(x) _op##= y, const _type2& x, \
142  const _type& y) \
143  }; \
144  YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
145  { \
146  YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
147  };
148 
157 
158 #undef YB_OP_NON_COMMUTATIVE
159 #undef YB_OP_COMMUTATIVE
160 
161 
162 #define YB_OP_BINARY(_name, _op) \
163  YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
164  { \
165  YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type2& y) \
166  }; \
167  YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
168  { \
169  YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
170  };
171 
174 
175 #undef YB_OP_BINARY
176 
178 {
179  friend _type
180  operator++(_type& x, int)
181  {
182  _type t(x);
183 
184  ++x;
185  return t;
186  }
187 };
188 
190 {
191  friend _type
192  operator--(_type& x, int)
193  {
194  _type t(x);
195 
196  ++x;
197  return t;
198  }
199 };
200 
202 {
203  auto
204  operator->() const -> decltype(&*std::declval<const _type&>())
205  {
206  return &*static_cast<const _type&>(*this);
207  }
208 };
209 
211 {
212  auto
213  operator[](_type2 n) const
214  -> decltype(*(std::declval<const _type&>() + n))
215  {
216  return *(static_cast<const _type&>(*this) + n);
217  }
218 };
219 
220 
222  equality_comparable2<_type, _type2, _tBase>>
223 {};
224 
226  : less_than_comparable1<_type, equality_comparable1<_type, _tBase>>
227 {};
228 
229 
231  : addable2<_type, _type2, subtractable2<_type, _type2, _tBase>>
232 {};
233 
235  : addable1<_type, subtractable1<_type, _tBase>>
236 {};
237 
238 
240  : multipliable2<_type, _type2, dividable2<_type, _type2, _tBase>>
241 {};
242 
244  : multipliable1<_type, dividable1<_type, _tBase>>
245 {};
246 
247 
249  : multiplicative2<_type, _type2, modable2<_type, _type2, _tBase>>
250 {};
251 
253  : multiplicative1<_type, modable1<_type, _tBase>>
254 {};
255 
256 
258  : additive2<_type, _type2, multiplicative2<_type, _type2, _tBase>>
259 {};
260 
262  : additive1<_type, multiplicative1<_type, _tBase>>
263 {};
264 
265 
267  integer_multiplicative2<_type, _type2, _tBase>>
268 {};
269 
271  : additive1<_type, integer_multiplicative1<_type, _tBase>>
272 {};
273 
274 
276  andable2<_type, _type2, orable2<_type, _type2, _tBase>>>
277 {};
278 
280  : xorable1<_type, andable1<_type, orable1<_type, _tBase>>>
281 {};
282 
283 
285  : incrementable<_type, decrementable<_type, _tBase>>
286 {};
287 
288 
290  right_shiftable2<_type, _type2, _tBase>>
291 {};
292 
294  : left_shiftable1<_type, right_shiftable1<_type, _tBase>>
295 {};
296 
297 
299  subtractable2_left<_type, _type2, multipliable2<_type, _type2, _tBase>>>
300 {};
301 
303  : additive1<_type, multipliable1<_type, _tBase>>
304 {};
305 
306 
308  totally_ordered2<_type, _type2, _tBase>>
309 {};
310 
312  : ring_operators1<_type, totally_ordered1<_type, _tBase>>
313 {};
314 
315 
317  dividable2<_type, _type2, dividable2_left<_type, _type2, _tBase>>>
318 {};
319 
321  : ring_operators1<_type, dividable1<_type, _tBase>>
322 {};
323 
324 
326  _type2, totally_ordered2<_type, _type2, _tBase>>
327 {};
328 
330  : field_operators1<_type, totally_ordered1<_type, _tBase>>
331 {};
332 
333 
335  _type2, dividable2<_type, _type2, dividable2_left<_type, _type2,
336  modable2<_type, _type2, modable2_left<_type, _type2, _tBase>>>>>
337 {};
338 
340  : ring_operators1<_type, dividable1<_type, modable1<_type, _tBase>>>
341 {};
342 
343 
345  _type, _type2, euclidean_ring_operators2<_type, _type2, _tBase>>
346 {};
347 
349  : totally_ordered1<_type, euclidean_ring_operators1<_type, _tBase>>
350 {};
351 
352 
354  incrementable<_type, dereferenceable<_type, _tBase>>>
355 {};
356 
357 
359 {};
360 
361 
363 {};
364 
365 
367  : forward_iteratable<_type, decrementable<_type, _tBase>>
368 {};
369 
370 
373  additive2<_type, _type2, indexable<_type, _type2, _tBase>>>>
374 {};
375 
376 } // namespace details;
377 
378 
379 template<class>
380 struct is_chained_base : false_type
381 {};
382 
383 
384 # define YB_OP_CHAIN2(_name) \
385  using ystdex::details::_name; \
386  template<class _type, class _type2, class _tBase> \
387  struct is_chained_base<_name<_type, _type2, _tBase>> : true_type \
388  {};
389 
390 # define YB_OP_CHAIN1(_name) \
391  using ystdex::details::_name; \
392  template<class _type, class _tBase> \
393  struct is_chained_base<_name<_type, _tBase>> : true_type \
394  {};
395 
396 #define YB_OP_CHAIN(_name) \
397  using ystdex::details::_name##2; \
398  template<class _type, class _type2 = _type, class \
399  _tBase = empty_base<_type>, bool _b = is_chained_base<_type2>::value> \
400  struct _name : _name##2<_type, _type2, _tBase> \
401  {}; \
402  \
403  using ystdex::details::_name##1; \
404  template<class _type, class _type2, class _tBase> \
405  struct _name<_type, _type2, _tBase, true> : _name##1<_type, _type2> \
406  {}; \
407  \
408  template<class _type, class _tBase> \
409  struct _name<_type, _type, _tBase, false> : _name##1<_type, _tBase> \
410  {}; \
411  \
412  template<class _type, class _type2, class _tBase, bool _b> \
413  struct is_chained_base<_name<_type, _type2, _tBase, _b>> \
414  : true_type \
415  {}; \
416  \
417  YB_OP_CHAIN2(_name##2) \
418  YB_OP_CHAIN1(_name##1)
419 
420 
424 YB_OP_CHAIN(addable)
425 YB_OP_CHAIN(subtractable)
426 YB_OP_CHAIN2(subtractable2_left)
427 YB_OP_CHAIN(dividable)
428 YB_OP_CHAIN2(dividable2_left)
429 YB_OP_CHAIN(modable)
430 YB_OP_CHAIN2(modable2_left)
431 YB_OP_CHAIN(xorable)
432 YB_OP_CHAIN(andable)
433 YB_OP_CHAIN(orable)
434 
435 YB_OP_CHAIN1(incrementable)
436 YB_OP_CHAIN1(decrementable)
437 
438 YB_OP_CHAIN1(dereferenceable)
439 YB_OP_CHAIN2(indexable)
440 
442 YB_OP_CHAIN(right_shiftable)
445 
453 YB_OP_CHAIN1(unit_steppable)
461 YB_OP_CHAIN1(input_iteratable)
462 YB_OP_CHAIN1(output_iteratable)
463 YB_OP_CHAIN1(forward_iteratable)
464 YB_OP_CHAIN1(bidirectional_iteratable)
465 YB_OP_CHAIN2(random_access_iteratable)
466 
467 #undef YB_OP_CHAIN2
468 #undef YB_OP_CHAIN1
469 #undef YB_OP_CHAIN
470 
472 
473 template<class _type, class _type2>
474 struct operators2 : public totally_ordered2<_type, _type2,
475  integer_arithmetic2<_type, _type2, bitwise2<_type, _type2>>>
476 {};
477 
478 
479 template<class _type, class _type2 = _type>
480 struct operators : public operators2<_type, _type2>
481 {};
482 
483 template<class _type>
484 struct operators<_type, _type> : totally_ordered<_type,
485  integer_arithmetic<_type, bitwise<_type, unit_steppable<_type>>>>
486 {};
488 
489 #undef YB_OP_TEMPLATE_HEADER1
490 #undef YB_OP_TEMPLATE_HEADER2
491 #undef YB_OP_FRIEND
492 
493 } // namespace ystdex;
494 
495 #endif
496 
friend _type operator--(_type &x, int)
Definition: operators.hpp:192
friend _type operator++(_type &x, int)
Definition: operators.hpp:180
#define YB_OP_BINARY(_name, _op)
Definition: operators.hpp:162
#define YB_OP_COMPARE1(_op, _expr, _param_type)
Definition: operators.hpp:55
#define YB_OP_CHAIN2(_name)
Definition: operators.hpp:384
#define YB_OP_COMPARE2(_op, _expr, _param_type, _param_type2)
Definition: operators.hpp:52
#define YB_OP_CHAIN1(_name)
Definition: operators.hpp:390
#define YB_OP_CHAIN(_name)
Definition: operators.hpp:396
#define YB_OP_TEMPLATE_HEADER2(_name)
Definition: operators.hpp:41
#define YB_OP_COMMUTATIVE(_name, _op)
Definition: operators.hpp:123
auto operator->() const -> decltype(&*std::declval< const _type & >())
Definition: operators.hpp:204
#define YB_OP_NON_COMMUTATIVE(_name, _op)
Definition: operators.hpp:134
#define YB_OP_TEMPLATE_HEADER1(_name)
Definition: operators.hpp:44
auto operator[](_type2 n) const -> decltype(*(std::declval< const _type & >()+n))
Definition: operators.hpp:213