Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/multiprecision/detail/et_ops.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /////////////////////////////////////////////////////////////////////////////// | |
2 // Copyright 2011 John Maddock. Distributed under the Boost | |
3 // Software License, Version 1.0. (See accompanying file | |
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | |
6 #ifndef BOOST_MP_ET_OPS_HPP | |
7 #define BOOST_MP_ET_OPS_HPP | |
8 | |
9 namespace boost{ namespace multiprecision{ | |
10 | |
11 // | |
12 // Non-member operators for number: | |
13 // | |
14 // Unary operators first. | |
15 // Note that these *must* return by value, even though that's somewhat against | |
16 // existing practice. The issue is that in C++11 land one could easily and legitimately | |
17 // write: | |
18 // auto x = +1234_my_user_defined_suffix; | |
19 // which would result in a dangling-reference-to-temporary if unary + returned a reference | |
20 // to it's argument. While return-by-value is obviously inefficient in other situations | |
21 // the reality is that no one ever uses unary operator+ anyway...! | |
22 // | |
23 template <class B, expression_template_option ExpressionTemplates> | |
24 inline BOOST_CONSTEXPR const number<B, ExpressionTemplates> operator + (const number<B, ExpressionTemplates>& v) { return v; } | |
25 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
26 inline BOOST_CONSTEXPR const detail::expression<tag, Arg1, Arg2, Arg3, Arg4> operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return v; } | |
27 template <class B> | |
28 inline detail::expression<detail::negate, number<B, et_on> > operator - (const number<B, et_on>& v) | |
29 { | |
30 BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior."); | |
31 return detail::expression<detail::negate, number<B, et_on> >(v); | |
32 } | |
33 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
34 inline detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) | |
35 { | |
36 BOOST_STATIC_ASSERT_MSG((is_signed_number<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value), "Negating an unsigned type results in ill-defined behavior."); | |
37 return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v); | |
38 } | |
39 template <class B> | |
40 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
41 detail::expression<detail::complement_immediates, number<B, et_on> > >::type | |
42 operator ~ (const number<B, et_on>& v) { return detail::expression<detail::complement_immediates, number<B, et_on> >(v); } | |
43 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
44 inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, | |
45 detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
46 operator ~ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v); } | |
47 // | |
48 // Then addition: | |
49 // | |
50 template <class B> | |
51 inline detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > | |
52 operator + (const number<B, et_on>& a, const number<B, et_on>& b) | |
53 { | |
54 return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b); | |
55 } | |
56 template <class B, class V> | |
57 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::add_immediates, number<B, et_on>, V > >::type | |
58 operator + (const number<B, et_on>& a, const V& b) | |
59 { | |
60 return detail::expression<detail::add_immediates, number<B, et_on>, V >(a, b); | |
61 } | |
62 template <class V, class B> | |
63 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::add_immediates, V, number<B, et_on> > >::type | |
64 operator + (const V& a, const number<B, et_on>& b) | |
65 { | |
66 return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b); | |
67 } | |
68 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
69 inline detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > | |
70 operator + (const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
71 { | |
72 return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
73 } | |
74 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
75 inline detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > | |
76 operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
77 { | |
78 return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); | |
79 } | |
80 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> | |
81 inline detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > | |
82 operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) | |
83 { | |
84 return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); | |
85 } | |
86 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
87 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type | |
88 operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
89 { | |
90 return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b); | |
91 } | |
92 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
93 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
94 operator + (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
95 { | |
96 return detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
97 } | |
98 // | |
99 // Fused multiply add: | |
100 // | |
101 template <class V, class Arg1, class Arg2, class Arg3, class Arg4> | |
102 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>, | |
103 detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type | |
104 operator + (const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) | |
105 { | |
106 return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(b.left(), b.right(), a); | |
107 } | |
108 template <class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
109 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>, | |
110 detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type | |
111 operator + (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
112 { | |
113 return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(a.left(), a.right(), b); | |
114 } | |
115 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> | |
116 inline detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > | |
117 operator + (const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) | |
118 { | |
119 return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(b.left(), b.right(), a); | |
120 } | |
121 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
122 inline detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > | |
123 operator + (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
124 { | |
125 return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(a.left(), a.right(), b); | |
126 } | |
127 // | |
128 // Fused multiply subtract: | |
129 // | |
130 template <class V, class Arg1, class Arg2, class Arg3, class Arg4> | |
131 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>, | |
132 detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> > >::type | |
133 operator - (const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) | |
134 { | |
135 return detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> > | |
136 (detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(b.left(), b.right(), a)); | |
137 } | |
138 template <class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
139 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>, | |
140 detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type | |
141 operator - (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
142 { | |
143 return detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(a.left(), a.right(), b); | |
144 } | |
145 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> | |
146 inline detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > > | |
147 operator - (const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) | |
148 { | |
149 return detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > > | |
150 (detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(b.left(), b.right(), a)); | |
151 } | |
152 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
153 inline detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > | |
154 operator - (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
155 { | |
156 return detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(a.left(), a.right(), b); | |
157 } | |
158 // | |
159 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: | |
160 // | |
161 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> | |
162 inline detail::expression<detail::minus, number<B, ET>, Arg1> | |
163 operator + (const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) | |
164 { | |
165 return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref()); | |
166 } | |
167 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
168 inline detail::expression<detail::minus, number<B, ET>, Arg1> | |
169 operator + (const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
170 { | |
171 return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref()); | |
172 } | |
173 template <class B> | |
174 inline detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> > | |
175 operator + (const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
176 { | |
177 return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()); | |
178 } | |
179 template <class B> | |
180 inline detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> > | |
181 operator + (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b) | |
182 { | |
183 return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()); | |
184 } | |
185 template <class B, class V> | |
186 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::subtract_immediates, V, number<B, et_on> > >::type | |
187 operator + (const detail::expression<detail::negate, number<B, et_on> >& a, const V& b) | |
188 { | |
189 return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(b, a.left_ref()); | |
190 } | |
191 template <class B, class B2, expression_template_option ET> | |
192 inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> > >::type | |
193 operator + (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b) | |
194 { | |
195 return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref()); | |
196 } | |
197 template <class B2, expression_template_option ET, class B> | |
198 inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> > >::type | |
199 operator + (const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
200 { | |
201 return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()); | |
202 } | |
203 template <class B> | |
204 inline detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > > | |
205 operator + (const detail::expression<detail::negate, number<B, et_on> >& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
206 { | |
207 return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >(detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b.left_ref())); | |
208 } | |
209 // | |
210 // Subtraction: | |
211 // | |
212 template <class B> | |
213 inline detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> > | |
214 operator - (const number<B, et_on>& a, const number<B, et_on>& b) | |
215 { | |
216 return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b); | |
217 } | |
218 template <class B, class V> | |
219 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::subtract_immediates, number<B, et_on>, V > >::type | |
220 operator - (const number<B, et_on>& a, const V& b) | |
221 { | |
222 return detail::expression<detail::subtract_immediates, number<B, et_on>, V >(a, b); | |
223 } | |
224 template <class V, class B> | |
225 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::subtract_immediates, V, number<B, et_on> > >::type | |
226 operator - (const V& a, const number<B, et_on>& b) | |
227 { | |
228 return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(a, b); | |
229 } | |
230 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
231 inline detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > | |
232 operator - (const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
233 { | |
234 return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
235 } | |
236 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
237 inline detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > | |
238 operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
239 { | |
240 return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); | |
241 } | |
242 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> | |
243 inline detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > | |
244 operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) | |
245 { | |
246 return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); | |
247 } | |
248 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
249 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type | |
250 operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
251 { | |
252 return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b); | |
253 } | |
254 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
255 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
256 operator - (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
257 { | |
258 return detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
259 } | |
260 // | |
261 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: | |
262 // | |
263 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> | |
264 inline detail::expression<detail::plus, number<B, ET>, Arg1> | |
265 operator - (const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) | |
266 { | |
267 return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref()); | |
268 } | |
269 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
270 inline detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> > | |
271 operator - (const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
272 { | |
273 return detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >( | |
274 detail::expression<detail::plus, number<B, ET>, Arg1>(b, a.left_ref())); | |
275 } | |
276 template <class B> | |
277 inline detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > | |
278 operator - (const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
279 { | |
280 return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()); | |
281 } | |
282 template <class B> | |
283 inline detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > > | |
284 operator - (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b) | |
285 { | |
286 return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >( | |
287 detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref())); | |
288 } | |
289 template <class B, class V> | |
290 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, V > > >::type | |
291 operator - (const detail::expression<detail::negate, number<B, et_on> >& a, const V& b) | |
292 { | |
293 return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, V > >(detail::expression<detail::add_immediates, number<B, et_on>, V >(a.left_ref(), b)); | |
294 } | |
295 template <class B, class B2, expression_template_option ET> | |
296 inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > > >::type | |
297 operator - (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b) | |
298 { | |
299 return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > >(detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); | |
300 } | |
301 template <class V, class B> | |
302 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::add_immediates, V, number<B, et_on> > >::type | |
303 operator - (const V& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
304 { | |
305 return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b.left_ref()); | |
306 } | |
307 template <class B2, expression_template_option ET, class B> | |
308 inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> > >::type | |
309 operator - (const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
310 { | |
311 return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()); | |
312 } | |
313 // | |
314 // Multiplication: | |
315 // | |
316 template <class B> | |
317 inline detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > | |
318 operator * (const number<B, et_on>& a, const number<B, et_on>& b) | |
319 { | |
320 return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b); | |
321 } | |
322 template <class B, class V> | |
323 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::multiply_immediates, number<B, et_on>, V > >::type | |
324 operator * (const number<B, et_on>& a, const V& b) | |
325 { | |
326 return detail::expression<detail::multiply_immediates, number<B, et_on>, V >(a, b); | |
327 } | |
328 template <class V, class B> | |
329 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::multiply_immediates, V, number<B, et_on> > >::type | |
330 operator * (const V& a, const number<B, et_on>& b) | |
331 { | |
332 return detail::expression<detail::multiply_immediates, V, number<B, et_on> >(a, b); | |
333 } | |
334 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
335 inline detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > | |
336 operator * (const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
337 { | |
338 return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
339 } | |
340 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
341 inline detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > | |
342 operator * (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
343 { | |
344 return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); | |
345 } | |
346 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> | |
347 inline detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > | |
348 operator * (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) | |
349 { | |
350 return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); | |
351 } | |
352 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
353 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type | |
354 operator * (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
355 { | |
356 return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b); | |
357 } | |
358 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
359 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
360 operator * (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
361 { | |
362 return detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
363 } | |
364 // | |
365 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: | |
366 // | |
367 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> | |
368 inline detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> > | |
369 operator * (const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) | |
370 { | |
371 return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >( | |
372 detail::expression<detail::multiplies, number<B, ET>, Arg1> (a, b.left_ref())); | |
373 } | |
374 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
375 inline detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> > | |
376 operator * (const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
377 { | |
378 return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >( | |
379 detail::expression<detail::multiplies, number<B, ET>, Arg1>(b, a.left_ref())); | |
380 } | |
381 template <class B> | |
382 inline detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > > | |
383 operator * (const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
384 { | |
385 return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >( | |
386 detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref())); | |
387 } | |
388 template <class B> | |
389 inline detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > > | |
390 operator * (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b) | |
391 { | |
392 return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >( | |
393 detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref())); | |
394 } | |
395 template <class B, class V> | |
396 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V > > >::type | |
397 operator * (const detail::expression<detail::negate, number<B, et_on> >& a, const V& b) | |
398 { | |
399 return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V > > ( | |
400 detail::expression<detail::multiply_immediates, number<B, et_on>, V >(a.left_ref(), b)); | |
401 } | |
402 template <class B, class B2, expression_template_option ET> | |
403 inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > >::type | |
404 operator * (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b) | |
405 { | |
406 return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > ( | |
407 detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); | |
408 } | |
409 template <class V, class B> | |
410 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V > > >::type | |
411 operator * (const V& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
412 { | |
413 return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V > >( | |
414 detail::expression<detail::multiply_immediates, number<B, et_on>, V >(b.left_ref(), a)); | |
415 } | |
416 template <class B2, expression_template_option ET, class B> | |
417 inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > >::type | |
418 operator * (const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
419 { | |
420 return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >( | |
421 detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(b.left_ref(), a)); | |
422 } | |
423 // | |
424 // Division: | |
425 // | |
426 template <class B> | |
427 inline detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > | |
428 operator / (const number<B, et_on>& a, const number<B, et_on>& b) | |
429 { | |
430 return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b); | |
431 } | |
432 template <class B, class V> | |
433 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::divide_immediates, number<B, et_on>, V > >::type | |
434 operator / (const number<B, et_on>& a, const V& b) | |
435 { | |
436 return detail::expression<detail::divide_immediates, number<B, et_on>, V >(a, b); | |
437 } | |
438 template <class V, class B> | |
439 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::divide_immediates, V, number<B, et_on> > >::type | |
440 operator / (const V& a, const number<B, et_on>& b) | |
441 { | |
442 return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b); | |
443 } | |
444 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
445 inline detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > | |
446 operator / (const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
447 { | |
448 return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
449 } | |
450 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
451 inline detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > | |
452 operator / (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
453 { | |
454 return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); | |
455 } | |
456 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> | |
457 inline detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > | |
458 operator / (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) | |
459 { | |
460 return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); | |
461 } | |
462 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
463 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type | |
464 operator / (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
465 { | |
466 return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b); | |
467 } | |
468 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
469 inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
470 operator / (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
471 { | |
472 return detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
473 } | |
474 // | |
475 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: | |
476 // | |
477 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> | |
478 inline detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> > | |
479 operator / (const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) | |
480 { | |
481 return detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >( | |
482 detail::expression<detail::divides, number<B, ET>, Arg1>(a, b.left_ref())); | |
483 } | |
484 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> | |
485 inline detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > > | |
486 operator / (const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) | |
487 { | |
488 return detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >( | |
489 detail::expression<detail::divides, Arg1, number<B, ET> >(a.left_ref(), b)); | |
490 } | |
491 template <class B> | |
492 inline detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > > | |
493 operator / (const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
494 { | |
495 return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >( | |
496 detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref())); | |
497 } | |
498 template <class B> | |
499 inline detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > > | |
500 operator / (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b) | |
501 { | |
502 return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >( | |
503 detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b)); | |
504 } | |
505 template <class B, class V> | |
506 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V > > >::type | |
507 operator / (const detail::expression<detail::negate, number<B, et_on> >& a, const V& b) | |
508 { | |
509 return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V > >( | |
510 detail::expression<detail::divide_immediates, number<B, et_on>, V>(a.left_ref(), b)); | |
511 } | |
512 template <class B, class B2, expression_template_option ET> | |
513 inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > > >::type | |
514 operator / (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b) | |
515 { | |
516 return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >( | |
517 detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); | |
518 } | |
519 template <class V, class B> | |
520 inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > > >::type | |
521 operator / (const V& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
522 { | |
523 return detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > >( | |
524 detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b.left_ref())); | |
525 } | |
526 template <class B2, expression_template_option ET, class B> | |
527 inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > > >::type | |
528 operator / (const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b) | |
529 { | |
530 return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >( | |
531 detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref())); | |
532 } | |
533 // | |
534 // Modulus: | |
535 // | |
536 template <class B> | |
537 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
538 detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> > >::type | |
539 operator % (const number<B, et_on>& a, const number<B, et_on>& b) | |
540 { | |
541 return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b); | |
542 } | |
543 template <class B, class V> | |
544 inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), | |
545 detail::expression<detail::modulus_immediates, number<B, et_on>, V > >::type | |
546 operator % (const number<B, et_on>& a, const V& b) | |
547 { | |
548 return detail::expression<detail::modulus_immediates, number<B, et_on>, V >(a, b); | |
549 } | |
550 template <class V, class B> | |
551 inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), | |
552 detail::expression<detail::modulus_immediates, V, number<B, et_on> > >::type | |
553 operator % (const V& a, const number<B, et_on>& b) | |
554 { | |
555 return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b); | |
556 } | |
557 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
558 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
559 detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
560 operator % (const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
561 { | |
562 return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
563 } | |
564 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> | |
565 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
566 detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type | |
567 operator % (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b) | |
568 { | |
569 return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); | |
570 } | |
571 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> | |
572 inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, | |
573 detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type | |
574 operator % (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) | |
575 { | |
576 return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); | |
577 } | |
578 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
579 inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value | |
580 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
581 detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type | |
582 operator % (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
583 { | |
584 return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b); | |
585 } | |
586 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
587 inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value | |
588 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
589 detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
590 operator % (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
591 { | |
592 return detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
593 } | |
594 // | |
595 // Left shift: | |
596 // | |
597 template <class B, class I> | |
598 inline typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), detail::expression<detail::shift_left, number<B, et_on>, I > >::type | |
599 operator << (const number<B, et_on>& a, const I& b) | |
600 { | |
601 return detail::expression<detail::shift_left, number<B, et_on>, I>(a, b); | |
602 } | |
603 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I> | |
604 inline typename enable_if_c<is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
605 detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type | |
606 operator << (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b) | |
607 { | |
608 return detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b); | |
609 } | |
610 // | |
611 // Right shift: | |
612 // | |
613 template <class B, class I> | |
614 inline typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), | |
615 detail::expression<detail::shift_right, number<B, et_on>, I > >::type | |
616 operator >> (const number<B, et_on>& a, const I& b) | |
617 { | |
618 return detail::expression<detail::shift_right, number<B, et_on>, I>(a, b); | |
619 } | |
620 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I> | |
621 inline typename enable_if_c<is_integral<I>::value | |
622 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
623 detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type | |
624 operator >> (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b) | |
625 { | |
626 return detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b); | |
627 } | |
628 // | |
629 // Bitwise AND: | |
630 // | |
631 template <class B> | |
632 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
633 detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> > >::type | |
634 operator & (const number<B, et_on>& a, const number<B, et_on>& b) | |
635 { | |
636 return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b); | |
637 } | |
638 template <class B, class V> | |
639 inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value | |
640 && (number_category<B>::value == number_kind_integer), | |
641 detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V > >::type | |
642 operator & (const number<B, et_on>& a, const V& b) | |
643 { | |
644 return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V >(a, b); | |
645 } | |
646 template <class V, class B> | |
647 inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value | |
648 && (number_category<B>::value == number_kind_integer), | |
649 detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> > >::type | |
650 operator & (const V& a, const number<B, et_on>& b) | |
651 { | |
652 return detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> >(a, b); | |
653 } | |
654 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
655 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
656 detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
657 operator & (const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
658 { | |
659 return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
660 } | |
661 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> | |
662 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
663 detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type | |
664 operator & (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b) | |
665 { | |
666 return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); | |
667 } | |
668 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> | |
669 inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, | |
670 detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type | |
671 operator & (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) | |
672 { | |
673 return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); | |
674 } | |
675 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
676 inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value | |
677 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
678 detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type | |
679 operator & (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
680 { | |
681 return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b); | |
682 } | |
683 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
684 inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value | |
685 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
686 detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
687 operator & (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
688 { | |
689 return detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
690 } | |
691 // | |
692 // Bitwise OR: | |
693 // | |
694 template <class B> | |
695 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
696 detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> > >::type | |
697 operator| (const number<B, et_on>& a, const number<B, et_on>& b) | |
698 { | |
699 return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b); | |
700 } | |
701 template <class B, class V> | |
702 inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value | |
703 && (number_category<B>::value == number_kind_integer), | |
704 detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V > >::type | |
705 operator| (const number<B, et_on>& a, const V& b) | |
706 { | |
707 return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V >(a, b); | |
708 } | |
709 template <class V, class B> | |
710 inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value | |
711 && (number_category<B>::value == number_kind_integer), | |
712 detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> > >::type | |
713 operator| (const V& a, const number<B, et_on>& b) | |
714 { | |
715 return detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> >(a, b); | |
716 } | |
717 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
718 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
719 detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
720 operator| (const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
721 { | |
722 return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
723 } | |
724 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> | |
725 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
726 detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type | |
727 operator| (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b) | |
728 { | |
729 return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); | |
730 } | |
731 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> | |
732 inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, | |
733 detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type | |
734 operator| (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) | |
735 { | |
736 return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); | |
737 } | |
738 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
739 inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value | |
740 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
741 detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type | |
742 operator| (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
743 { | |
744 return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b); | |
745 } | |
746 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
747 inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value | |
748 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
749 detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
750 operator| (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
751 { | |
752 return detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
753 } | |
754 // | |
755 // Bitwise XOR: | |
756 // | |
757 template <class B> | |
758 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
759 detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> > >::type | |
760 operator^ (const number<B, et_on>& a, const number<B, et_on>& b) | |
761 { | |
762 return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b); | |
763 } | |
764 template <class B, class V> | |
765 inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value | |
766 && (number_category<B>::value == number_kind_integer), | |
767 detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V > >::type | |
768 operator^ (const number<B, et_on>& a, const V& b) | |
769 { | |
770 return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V >(a, b); | |
771 } | |
772 template <class V, class B> | |
773 inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value | |
774 && (number_category<B>::value == number_kind_integer), | |
775 detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> > >::type | |
776 operator^ (const V& a, const number<B, et_on>& b) | |
777 { | |
778 return detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> >(a, b); | |
779 } | |
780 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
781 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
782 detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
783 operator^ (const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
784 { | |
785 return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
786 } | |
787 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> | |
788 inline typename enable_if_c<number_category<B>::value == number_kind_integer, | |
789 detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type | |
790 operator^ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b) | |
791 { | |
792 return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); | |
793 } | |
794 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> | |
795 inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, | |
796 detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type | |
797 operator^ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) | |
798 { | |
799 return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); | |
800 } | |
801 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> | |
802 inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value | |
803 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), | |
804 detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type | |
805 operator^ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) | |
806 { | |
807 return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b); | |
808 } | |
809 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> | |
810 inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value | |
811 && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type | |
812 operator^ (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) | |
813 { | |
814 return detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); | |
815 } | |
816 | |
817 }} // namespaces | |
818 | |
819 #endif |