30 #ifndef YB_INC_ystdex_operators_hpp_
31 #define YB_INC_ystdex_operators_hpp_ 1
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>> \
44 #define YB_OP_TEMPLATE_HEADER1(_name) \
45 template<class _type, class _tBase = empty_base<_type>> \
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, \
119 #undef YB_OP_COMPARE2
120 #undef YB_OP_COMPARE1
123 #define YB_OP_COMMUTATIVE(_name, _op) \
124 YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
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) \
129 YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
131 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
134 #define YB_OP_NON_COMMUTATIVE(_name, _op) \
135 YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
137 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type2& y) \
139 YB_OP_TEMPLATE_HEADER2(_name##2##_##left) : _tBase \
141 YB_OP_FRIEND(_op, _type, _type(x) _op##= y, const _type2& x, \
144 YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
146 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
158 #undef YB_OP_NON_COMMUTATIVE
159 #undef YB_OP_COMMUTATIVE
162 #define YB_OP_BINARY(_name, _op) \
163 YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
165 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type2& y) \
167 YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
169 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
204 operator->() const -> decltype(&*std::declval<const _type&>())
206 return &*
static_cast<const _type&
>(*this);
214 -> decltype(*(std::declval<const _type&>() + n))
216 return *(
static_cast<const _type&
>(*this) + n);
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 \
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 \
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> \
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> \
408 template<class _type, class _tBase> \
409 struct _name<_type, _type, _tBase, false> : _name##1<_type, _tBase> \
412 template<class _type, class _type2, class _tBase, bool _b> \
413 struct is_chained_base<_name<_type, _type2, _tBase, _b>> \
417 YB_OP_CHAIN2(_name##2) \
418 YB_OP_CHAIN1(_name##1)
473 template<
class _type,
class _type2>
475 integer_arithmetic2<_type, _type2, bitwise2<_type, _type2>>>
479 template<
class _type,
class _type2 = _type>
483 template<
class _type>
485 integer_arithmetic<_type, bitwise<_type, unit_steppable<_type>>>>
489 #undef YB_OP_TEMPLATE_HEADER1
490 #undef YB_OP_TEMPLATE_HEADER2
friend _type operator--(_type &x, int)
friend _type operator++(_type &x, int)
#define YB_OP_BINARY(_name, _op)
#define YB_OP_COMPARE1(_op, _expr, _param_type)
#define YB_OP_CHAIN2(_name)
#define YB_OP_COMPARE2(_op, _expr, _param_type, _param_type2)
#define YB_OP_CHAIN1(_name)
#define YB_OP_CHAIN(_name)
#define YB_OP_TEMPLATE_HEADER2(_name)
#define YB_OP_COMMUTATIVE(_name, _op)
auto operator->() const -> decltype(&*std::declval< const _type & >())
#define YB_OP_NON_COMMUTATIVE(_name, _op)
#define YB_OP_TEMPLATE_HEADER1(_name)
auto operator[](_type2 n) const -> decltype(*(std::declval< const _type & >()+n))