10 #if !defined(CNL_IMPL_OPERATORS_OVERLOADS_H)
11 #define CNL_IMPL_OPERATORS_OVERLOADS_H
13 #include "../../arithmetic.h"
14 #include "definition.h"
25 template<
typename LhsOperand,
typename RhsOperand>
26 inline constexpr
auto wants_generic_ops_binary =
27 _impl::wants_generic_ops<LhsOperand> || _impl::wants_generic_ops<RhsOperand>;
35 #define CNL_DEFINE_UNARY_OPERATOR(OP, NAME) \
36 template<class Operand> \
37 requires _impl::wants_generic_ops<Operand> \
38 [[nodiscard]] constexpr auto operator OP(Operand const& rhs) \
40 return cnl::custom_operator<NAME, cnl::op_value<Operand>>()(rhs); \
43 CNL_DEFINE_UNARY_OPERATOR(+, plus_op)
45 CNL_DEFINE_UNARY_OPERATOR(-, minus_op)
47 CNL_DEFINE_UNARY_OPERATOR(~, bitwise_not_op)
52 #define CNL_DEFINE_BINARY_OPERATOR(OP, NAME) \
53 template<cnl::arithmetic LhsOperand, cnl::arithmetic RhsOperand> \
54 requires wants_generic_ops_binary<LhsOperand, RhsOperand> \
55 [[nodiscard]] constexpr auto \
56 operator OP(LhsOperand const& lhs, RhsOperand const& rhs) \
58 return cnl::custom_operator<NAME, cnl::op_value<LhsOperand>, cnl::op_value<RhsOperand>>{}( \
62 CNL_DEFINE_BINARY_OPERATOR(+, add_op)
64 CNL_DEFINE_BINARY_OPERATOR(-, subtract_op)
66 CNL_DEFINE_BINARY_OPERATOR(*, multiply_op)
68 CNL_DEFINE_BINARY_OPERATOR(/, divide_op)
70 CNL_DEFINE_BINARY_OPERATOR(%, modulo_op)
72 CNL_DEFINE_BINARY_OPERATOR(|, bitwise_or_op)
74 CNL_DEFINE_BINARY_OPERATOR(&, bitwise_and_op)
76 CNL_DEFINE_BINARY_OPERATOR(^, bitwise_xor_op)
81 #define CNL_DEFINE_SHIFT_OPERATOR(OP, NAME) \
82 template<cnl::arithmetic LhsOperand, cnl::arithmetic RhsOperand> \
83 requires wants_generic_ops_binary<LhsOperand, RhsOperand> \
84 [[nodiscard]] constexpr auto \
85 operator OP(LhsOperand const& lhs, RhsOperand const& rhs) \
87 return cnl::custom_operator<NAME, op_value<LhsOperand>, op_value<RhsOperand>>()(lhs, rhs); \
90 CNL_DEFINE_SHIFT_OPERATOR(<<, shift_left_op)
92 CNL_DEFINE_SHIFT_OPERATOR(>>, shift_right_op)
97 #define CNL_DEFINE_COMPARISON_OPERATOR(OP, NAME) \
98 template<cnl::arithmetic LhsOperand, cnl::arithmetic RhsOperand> \
99 requires wants_generic_ops_binary<LhsOperand, RhsOperand> \
100 [[nodiscard]] constexpr auto \
101 operator OP(LhsOperand const& lhs, RhsOperand const& rhs) \
103 return cnl::custom_operator<NAME, op_value<LhsOperand>, op_value<RhsOperand>>()(lhs, rhs); \
106 CNL_DEFINE_COMPARISON_OPERATOR(==, equal_op)
108 CNL_DEFINE_COMPARISON_OPERATOR(!=, not_equal_op)
110 CNL_DEFINE_COMPARISON_OPERATOR(<, less_than_op)
112 CNL_DEFINE_COMPARISON_OPERATOR(>, greater_than_op)
114 CNL_DEFINE_COMPARISON_OPERATOR(<=, less_than_or_equal_op)
116 CNL_DEFINE_COMPARISON_OPERATOR(>=, greater_than_or_equal_op)
121 #define CNL_DEFINE_PRE_OPERATOR(OP, NAME) \
122 template<cnl::arithmetic RhsOperand> \
123 constexpr decltype(auto) operator OP(RhsOperand& rhs) \
125 return cnl::custom_operator<NAME, cnl::op_value<RhsOperand>>()(rhs); \
128 CNL_DEFINE_PRE_OPERATOR(++, pre_increment_op)
130 CNL_DEFINE_PRE_OPERATOR(--, pre_decrement_op)
135 #define CNL_DEFINE_POST_OPERATOR(OP, NAME) \
136 template<cnl::arithmetic LhsOperand> \
137 constexpr auto operator OP(LhsOperand& lhs, int) \
138 ->decltype(cnl::custom_operator<NAME, cnl::op_value<LhsOperand>>()(lhs)) \
140 return cnl::custom_operator<NAME, cnl::op_value<LhsOperand>>()(lhs); \
143 CNL_DEFINE_POST_OPERATOR(++, post_increment_op)
145 CNL_DEFINE_POST_OPERATOR(--, post_decrement_op)
150 #define CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(OP, NAME) \
151 template<cnl::arithmetic LhsOperand, cnl::arithmetic RhsOperand> \
152 requires _impl::wants_generic_ops_binary<LhsOperand, RhsOperand> \
153 constexpr auto operator OP(LhsOperand& lhs, RhsOperand const& rhs) \
155 return cnl::custom_operator< \
156 NAME, op_value<LhsOperand>, op_value<RhsOperand>>()(lhs, rhs); \
159 CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(+=, assign_add_op)
161 CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(-=, assign_subtract_op)
163 CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(*=, assign_multiply_op)
165 CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(/=, assign_divide_op)
167 CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(%=, assign_modulo_op)
169 CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(|=, assign_bitwise_or_op)
171 CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(&=, assign_bitwise_and_op)
173 CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(^=, assign_bitwise_xor_op)
178 #define CNL_DEFINE_COMPOUND_ASSIGNMENT_SHIFT_OPERATOR(OP, NAME) \
179 template<cnl::arithmetic LhsOperand, cnl::arithmetic RhsOperand> \
180 requires _impl::wants_generic_ops_binary<LhsOperand, RhsOperand> \
181 constexpr auto operator OP(LhsOperand& lhs, RhsOperand const& rhs) \
183 return cnl::custom_operator< \
184 NAME, op_value<LhsOperand>, op_value<RhsOperand>>()(lhs, rhs); \
187 CNL_DEFINE_COMPOUND_ASSIGNMENT_SHIFT_OPERATOR(<<=, assign_shift_left_op)
189 CNL_DEFINE_COMPOUND_ASSIGNMENT_SHIFT_OPERATOR(>>=, assign_shift_right_op)
193 #endif // CNL_IMPL_OPERATORS_OVERLOADS_H