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>
operator +(const number<B,ExpressionTemplates> & v)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>
operator +(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & v)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>
operator -(const number<B,et_on> & v)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>
operator -(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & v)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
operator ~(const number<B,et_on> & v)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
operator ~(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & v)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> >
operator +(const number<B,et_on> & a,const number<B,et_on> & b)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
operator +(const number<B,et_on> & a,const V & b)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
operator +(const V & a,const number<B,et_on> & b)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> >
operator +(const number<B,ET> & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator +(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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> >
operator +(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const detail::expression<tag2,Arg1b,Arg2b,Arg3b,Arg4b> & b)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
operator +(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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
operator +(const V & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
operator +(const V & a,const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & b)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
operator +(const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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> >
operator +(const number<B,ET> & a,const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator +(const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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
operator -(const V & a,const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & b)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
operator -(const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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> > >
operator -(const number<B,ET> & a,const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator -(const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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>
operator +(const number<B,ET> & a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)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>
operator +(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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> >
operator +(const number<B,et_on> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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> >
operator +(const detail::expression<detail::negate,number<B,et_on>> & a,const number<B,et_on> & b)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
operator +(const detail::expression<detail::negate,number<B,et_on>> & a,const V & b)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
operator +(const detail::expression<detail::negate,number<B,et_on>> & a,const number<B2,ET> & b)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
operator +(const number<B2,ET> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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> > >
operator +(const detail::expression<detail::negate,number<B,et_on>> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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> >
operator -(const number<B,et_on> & a,const number<B,et_on> & b)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
operator -(const number<B,et_on> & a,const V & b)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
operator -(const V & a,const number<B,et_on> & b)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> >
operator -(const number<B,ET> & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator -(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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> >
operator -(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const detail::expression<tag2,Arg1b,Arg2b,Arg3b,Arg4b> & b)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
operator -(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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
operator -(const V & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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>
operator -(const number<B,ET> & a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator -(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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> >
operator -(const number<B,et_on> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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> > >
operator -(const detail::expression<detail::negate,number<B,et_on>> & a,const number<B,et_on> & b)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
operator -(const detail::expression<detail::negate,number<B,et_on>> & a,const V & b)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
operator -(const detail::expression<detail::negate,number<B,et_on>> & a,const number<B2,ET> & b)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
operator -(const V & a,const detail::expression<detail::negate,number<B,et_on>> & b)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
operator -(const number<B2,ET> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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> >
operator *(const number<B,et_on> & a,const number<B,et_on> & b)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
operator *(const number<B,et_on> & a,const V & b)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
operator *(const V & a,const number<B,et_on> & b)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> >
operator *(const number<B,ET> & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator *(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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> >
operator *(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const detail::expression<tag2,Arg1b,Arg2b,Arg3b,Arg4b> & b)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
operator *(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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
operator *(const V & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator *(const number<B,ET> & a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator *(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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> > >
operator *(const number<B,et_on> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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> > >
operator *(const detail::expression<detail::negate,number<B,et_on>> & a,const number<B,et_on> & b)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
operator *(const detail::expression<detail::negate,number<B,et_on>> & a,const V & b)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
operator *(const detail::expression<detail::negate,number<B,et_on>> & a,const number<B2,ET> & b)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
operator *(const V & a,const detail::expression<detail::negate,number<B,et_on>> & b)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
operator *(const number<B2,ET> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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> >
operator /(const number<B,et_on> & a,const number<B,et_on> & b)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
operator /(const number<B,et_on> & a,const V & b)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
operator /(const V & a,const number<B,et_on> & b)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> >
operator /(const number<B,ET> & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator /(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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> >
operator /(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const detail::expression<tag2,Arg1b,Arg2b,Arg3b,Arg4b> & b)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
operator /(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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
operator /(const V & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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> >
operator /(const number<B,ET> & a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)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> > >
operator /(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)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> > >
operator /(const number<B,et_on> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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> > >
operator /(const detail::expression<detail::negate,number<B,et_on>> & a,const number<B,et_on> & b)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
operator /(const detail::expression<detail::negate,number<B,et_on>> & a,const V & b)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
operator /(const detail::expression<detail::negate,number<B,et_on>> & a,const number<B2,ET> & b)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
operator /(const V & a,const detail::expression<detail::negate,number<B,et_on>> & b)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
operator /(const number<B2,ET> & a,const detail::expression<detail::negate,number<B,et_on>> & b)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
operator %(const number<B,et_on> & a,const number<B,et_on> & b)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
operator %(const number<B,et_on> & a,const V & b)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
operator %(const V & a,const number<B,et_on> & b)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
operator %(const number<B,et_on> & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
operator %(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const number<B,et_on> & b)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
operator %(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const detail::expression<tag2,Arg1b,Arg2b,Arg3b,Arg4b> & b)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
operator %(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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
operator %(const V & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
operator <<(const number<B,et_on> & a,const I & b)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
operator <<(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const I & b)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
operator >>(const number<B,et_on> & a,const I & b)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
operator >>(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const I & b)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
operator &(const number<B,et_on> & a,const number<B,et_on> & b)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
operator &(const number<B,et_on> & a,const V & b)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
operator &(const V & a,const number<B,et_on> & b)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
operator &(const number<B,et_on> & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
operator &(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const number<B,et_on> & b)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
operator &(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const detail::expression<tag2,Arg1b,Arg2b,Arg3b,Arg4b> & b)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
operator &(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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
operator &(const V & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
operator |(const number<B,et_on> & a,const number<B,et_on> & b)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
operator |(const number<B,et_on> & a,const V & b)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
operator |(const V & a,const number<B,et_on> & b)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
operator |(const number<B,et_on> & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
operator |(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const number<B,et_on> & b)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
operator |(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const detail::expression<tag2,Arg1b,Arg2b,Arg3b,Arg4b> & b)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
operator |(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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
operator |(const V & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
operator ^(const number<B,et_on> & a,const number<B,et_on> & b)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
operator ^(const number<B,et_on> & a,const V & b)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
operator ^(const V & a,const number<B,et_on> & b)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
operator ^(const number<B,et_on> & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
operator ^(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const number<B,et_on> & b)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
operator ^(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const detail::expression<tag2,Arg1b,Arg2b,Arg3b,Arg4b> & b)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
operator ^(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,const V & b)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
operator ^(const V & a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)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
820