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)
6 #ifndef BOOST_MP_ET_OPS_HPP
7 #define BOOST_MP_ET_OPS_HPP
9 namespace boost{ namespace multiprecision{
12 // Non-member operators for number:
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
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...!
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; }
28 inline detail::expression<detail::negate, number<B, et_on> > operator - (const number<B, et_on>& v)
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);
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)
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);
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); }
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)
54 return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b);
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)
60 return detail::expression<detail::add_immediates, number<B, et_on>, V >(a, b);
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)
66 return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b);
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)
72 return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
78 return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
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)
84 return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
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)
90 return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
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)
96 return detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
99 // Fused multiply add:
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)
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);
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)
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);
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)
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);
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)
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);
128 // Fused multiply subtract:
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)
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));
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)
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);
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)
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));
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)
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);
159 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
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)
165 return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref());
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)
171 return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref());
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)
177 return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
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)
183 return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref());
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)
189 return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(b, a.left_ref());
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)
195 return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref());
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)
201 return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
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)
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()));
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)
216 return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b);
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)
222 return detail::expression<detail::subtract_immediates, number<B, et_on>, V >(a, b);
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)
228 return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(a, b);
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)
234 return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
240 return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
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)
246 return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
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)
252 return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
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)
258 return detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
261 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
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)
267 return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref());
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)
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()));
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)
280 return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
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)
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()));
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)
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));
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)
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));
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)
305 return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b.left_ref());
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)
311 return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
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)
320 return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b);
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)
326 return detail::expression<detail::multiply_immediates, number<B, et_on>, V >(a, b);
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)
332 return detail::expression<detail::multiply_immediates, V, number<B, et_on> >(a, b);
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)
338 return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
344 return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
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)
350 return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
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)
356 return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
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)
362 return detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
365 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
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)
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()));
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)
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()));
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)
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()));
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)
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()));
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)
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));
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)
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));
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)
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));
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)
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));
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)
430 return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b);
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)
436 return detail::expression<detail::divide_immediates, number<B, et_on>, V >(a, b);
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)
442 return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b);
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)
448 return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
454 return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
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)
460 return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
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)
466 return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
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)
472 return detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
475 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
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)
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()));
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)
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));
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)
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()));
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)
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));
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)
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));
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)
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));
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)
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()));
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)
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()));
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)
541 return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
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)
548 return detail::expression<detail::modulus_immediates, number<B, et_on>, V >(a, b);
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)
555 return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b);
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)
562 return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
569 return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
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)
576 return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
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)
584 return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
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)
592 return detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
601 return detail::expression<detail::shift_left, number<B, et_on>, I>(a, b);
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)
608 return detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
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)
618 return detail::expression<detail::shift_right, number<B, et_on>, I>(a, b);
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)
626 return detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, 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)
636 return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b);
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)
644 return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V >(a, b);
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)
652 return detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> >(a, b);
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)
659 return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
666 return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
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)
673 return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
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)
681 return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
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)
689 return detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, 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)
699 return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b);
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)
707 return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V >(a, b);
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)
715 return detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> >(a, b);
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)
722 return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
729 return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
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)
736 return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
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)
744 return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
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)
752 return detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, 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)
762 return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b);
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)
770 return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V >(a, b);
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)
778 return detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> >(a, b);
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)
785 return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
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)
792 return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
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)
799 return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
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)
807 return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
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)
814 return detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);