28 #ifndef YB_INC_YSTDEX_OPERATORS_HPP_
29 #define YB_INC_YSTDEX_OPERATORS_HPP_ 1
36 #define YB_OP_FRIEND(_op, _tRet, _expr, ...) \
37 friend yconstfn _tRet operator _op (__VA_ARGS__) {return (_expr);}
38 #define YB_OP_TEMPLATE_HEADER2(_name) \
39 template<class _type, class _type2, class _tBase = empty_base<_type>> \
41 #define YB_OP_TEMPLATE_HEADER1(_name) \
42 template<class _type, class _tBase = empty_base<_type>> \
49 #define YB_OP_COMPARE2(_op, _expr, _param_type, _param_type2) \
50 YB_OP_FRIEND(_op, bool, _expr, const _param_type& x, \
51 const _param_type2& y)
52 #define YB_OP_COMPARE1(_op, _expr, _param_type) \
53 YB_OP_FRIEND(_op, bool, _expr, const _param_type& x, \
116 #undef YB_OP_COMPARE2
117 #undef YB_OP_COMPARE1
120 #define YB_OP_COMMUTATIVE(_name, _op) \
121 YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
123 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type2& y) \
124 YB_OP_FRIEND(_op, _type, y _op##= x, const _type2& y, _type x) \
126 YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
128 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
131 #define YB_OP_NON_COMMUTATIVE(_name, _op) \
132 YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
134 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type2& y) \
136 YB_OP_TEMPLATE_HEADER2(_name##2##_##left) : _tBase \
138 YB_OP_FRIEND(_op, _type, _type(x) _op##= y, const _type2& x, \
141 YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
143 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
155 #undef YB_OP_NON_COMMUTATIVE
156 #undef YB_OP_COMMUTATIVE
159 #define YB_OP_BINARY(_name, _op) \
160 YB_OP_TEMPLATE_HEADER2(_name##2) : _tBase \
162 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type2& y) \
164 YB_OP_TEMPLATE_HEADER1(_name##1) : _tBase \
166 YB_OP_FRIEND(_op, _type, x _op##= y, _type x, const _type& y) \
177 operator++(_type& x,
int)
189 operator--(_type& x,
int)
201 operator->() const -> decltype(&*std::declval<const _type&>())
203 return &*
static_cast<const _type&
>(*this);
210 operator[](_type2 n)
const
211 -> decltype(*(std::declval<const _type&>() + n))
213 return *(
static_cast<const _type&
>(*this) + n);
278 orable2<_type, _type2, _tBase>>
439 # define YB_OP_CHAIN2(_name) \
440 using ystdex::details::_name; \
441 template<class _type, class _type2, class _tBase> \
442 struct is_chained_base<_name<_type, _type2, _tBase>> \
446 # define YB_OP_CHAIN1(_name) \
447 using ystdex::details::_name; \
448 template<class _type, class _tBase> \
449 struct is_chained_base<_name<_type, _tBase>> \
453 #define YB_OP_CHAIN(_name) \
454 using ystdex::details::_name##2; \
455 template<class _type, class _type2 = _type, \
456 class _tBase = empty_base<_type>, \
457 bool _v = is_chained_base<_type2>::value \
460 : _name##2<_type, _type2, _tBase> \
463 using ystdex::details::_name##1; \
464 template<class _type, class _type2, class _tBase> \
465 struct _name<_type, _type2, _tBase, true> \
466 : _name##1<_type, _type2> \
469 template <class _type, class _tBase> \
470 struct _name<_type, _type, _tBase, false> \
471 : _name##1<_type, _tBase> \
474 template<class _type, class _type2, class _tBase, bool _v> \
475 struct is_chained_base<_name<_type, _type2, _tBase, _v>> \
479 YB_OP_CHAIN2(_name##2) \
480 YB_OP_CHAIN1(_name##1)
537 #undef YB_OP_TEMPLATE_HEADER1
538 #undef YB_OP_TEMPLATE_HEADER2