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