CNL  2.0.2 (development)
Compositional Numeric Library
overloads.h
Go to the documentation of this file.
1 
2 // Copyright John McFarlane 2019.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file ../LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
9 
10 #if !defined(CNL_IMPL_OPERATORS_OVERLOADS_H)
11 #define CNL_IMPL_OPERATORS_OVERLOADS_H
12 
13 #include "../../arithmetic.h"
14 #include "definition.h"
15 #include "op.h"
16 
18 namespace cnl {
19  namespace _impl {
20  struct native_tag;
21 
23  // cnl::_impl::wants_generic_ops_binary
24 
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>;
28 
30  // operator overloads
31 
32  // unary operators
33 
34 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
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) \
39  { \
40  return cnl::custom_operator<NAME, cnl::op_value<Operand>>()(rhs); \
41  }
42 
43  CNL_DEFINE_UNARY_OPERATOR(+, plus_op)
44 
45  CNL_DEFINE_UNARY_OPERATOR(-, minus_op)
46 
47  CNL_DEFINE_UNARY_OPERATOR(~, bitwise_not_op)
48 
49  // binary operators
50 
51 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
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) \
57  { \
58  return cnl::custom_operator<NAME, cnl::op_value<LhsOperand>, cnl::op_value<RhsOperand>>{}( \
59  lhs, rhs); \
60  }
61 
62  CNL_DEFINE_BINARY_OPERATOR(+, add_op)
63 
64  CNL_DEFINE_BINARY_OPERATOR(-, subtract_op)
65 
66  CNL_DEFINE_BINARY_OPERATOR(*, multiply_op)
67 
68  CNL_DEFINE_BINARY_OPERATOR(/, divide_op)
69 
70  CNL_DEFINE_BINARY_OPERATOR(%, modulo_op)
71 
72  CNL_DEFINE_BINARY_OPERATOR(|, bitwise_or_op)
73 
74  CNL_DEFINE_BINARY_OPERATOR(&, bitwise_and_op)
75 
76  CNL_DEFINE_BINARY_OPERATOR(^, bitwise_xor_op)
77 
78  // binary operators
79 
80 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
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) \
86  { \
87  return cnl::custom_operator<NAME, op_value<LhsOperand>, op_value<RhsOperand>>()(lhs, rhs); \
88  }
89 
90  CNL_DEFINE_SHIFT_OPERATOR(<<, shift_left_op)
91 
92  CNL_DEFINE_SHIFT_OPERATOR(>>, shift_right_op)
93 
94  // comparison operators
95 
96 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
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) \
102  { \
103  return cnl::custom_operator<NAME, op_value<LhsOperand>, op_value<RhsOperand>>()(lhs, rhs); \
104  }
105 
106  CNL_DEFINE_COMPARISON_OPERATOR(==, equal_op)
107 
108  CNL_DEFINE_COMPARISON_OPERATOR(!=, not_equal_op)
109 
110  CNL_DEFINE_COMPARISON_OPERATOR(<, less_than_op)
111 
112  CNL_DEFINE_COMPARISON_OPERATOR(>, greater_than_op)
113 
114  CNL_DEFINE_COMPARISON_OPERATOR(<=, less_than_or_equal_op)
115 
116  CNL_DEFINE_COMPARISON_OPERATOR(>=, greater_than_or_equal_op)
117 
118  // pre increment/decrement
119 
120 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
121 #define CNL_DEFINE_PRE_OPERATOR(OP, NAME) \
122  template<cnl::arithmetic RhsOperand> \
123  constexpr decltype(auto) operator OP(RhsOperand& rhs) \
124  { \
125  return cnl::custom_operator<NAME, cnl::op_value<RhsOperand>>()(rhs); \
126  }
127 
128  CNL_DEFINE_PRE_OPERATOR(++, pre_increment_op)
129 
130  CNL_DEFINE_PRE_OPERATOR(--, pre_decrement_op)
131 
132  // post increment/decrement
133 
134 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
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)) \
139  { \
140  return cnl::custom_operator<NAME, cnl::op_value<LhsOperand>>()(lhs); \
141  }
142 
143  CNL_DEFINE_POST_OPERATOR(++, post_increment_op)
144 
145  CNL_DEFINE_POST_OPERATOR(--, post_decrement_op)
146 
147  // compound assignment operators
148 
149 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
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) \
154  { \
155  return cnl::custom_operator< \
156  NAME, op_value<LhsOperand>, op_value<RhsOperand>>()(lhs, rhs); \
157  }
158 
159  CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(+=, assign_add_op)
160 
161  CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(-=, assign_subtract_op)
162 
163  CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(*=, assign_multiply_op)
164 
165  CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(/=, assign_divide_op)
166 
167  CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(%=, assign_modulo_op)
168 
169  CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(|=, assign_bitwise_or_op)
170 
171  CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(&=, assign_bitwise_and_op)
172 
173  CNL_DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(^=, assign_bitwise_xor_op)
174 
175  // compound assignment shift operators
176 
177 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
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) \
182  { \
183  return cnl::custom_operator< \
184  NAME, op_value<LhsOperand>, op_value<RhsOperand>>()(lhs, rhs); \
185  }
186 
187  CNL_DEFINE_COMPOUND_ASSIGNMENT_SHIFT_OPERATOR(<<=, assign_shift_left_op)
188 
189  CNL_DEFINE_COMPOUND_ASSIGNMENT_SHIFT_OPERATOR(>>=, assign_shift_right_op)
190  }
191 }
192 
193 #endif // CNL_IMPL_OPERATORS_OVERLOADS_H
op.h
operators represented as types
cnl
compositional numeric library
Definition: abort.h:15