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 BOOST_MP_CXX14_CONSTEXPR 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 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
34 template <class B>
operator -(number<B,et_on> && v)35 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> operator-(number<B, et_on>&& v)
36 {
37    BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
38    return detail::expression<detail::negate, number<B, et_on> >(v);
39 }
40 #endif
41 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
operator -(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & v)42 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v)
43 {
44    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.");
45    return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v);
46 }
47 template <class B>
48 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
49                             detail::expression<detail::complement_immediates, number<B, et_on> > >::type
operator ~(const number<B,et_on> & v)50 operator~(const number<B, et_on>& v) { return detail::expression<detail::complement_immediates, number<B, et_on> >(v); }
51 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
52 template <class B>
53 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
54                             number<B, et_on> >::type
operator ~(number<B,et_on> && v)55 operator~(number<B, et_on>&& v) { return detail::expression<detail::complement_immediates, number<B, et_on> >(v); }
56 #endif
57 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
58 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
59                             detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
operator ~(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & v)60 operator~(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v); }
61 //
62 // Then addition:
63 //
64 template <class B>
65 inline BOOST_MP_CXX14_CONSTEXPR 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)66 operator+(const number<B, et_on>& a, const number<B, et_on>& b)
67 {
68    return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b);
69 }
70 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
71 template <class B>
72 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator +(number<B,et_on> && a,const number<B,et_on> & b)73 operator+(number<B, et_on>&& a, const number<B, et_on>& b)
74 {
75    return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b);
76 }
77 template <class B>
78 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator +(const number<B,et_on> & a,number<B,et_on> && b)79 operator+(const number<B, et_on>& a, number<B, et_on>&& b)
80 {
81    return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b);
82 }
83 template <class B>
84 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator +(number<B,et_on> && a,number<B,et_on> && b)85 operator+(number<B, et_on>&& a, number<B, et_on>&& b)
86 {
87    return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b);
88 }
89 #endif
90 template <class B, class V>
91 inline BOOST_MP_CXX14_CONSTEXPR 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)92 operator+(const number<B, et_on>& a, const V& b)
93 {
94    return detail::expression<detail::add_immediates, number<B, et_on>, V>(a, b);
95 }
96 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
97 template <class B, class V>
98 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, number<B, et_on> >::type
operator +(number<B,et_on> && a,const V & b)99 operator+(number<B, et_on>&& a, const V& b)
100 {
101    return detail::expression<detail::add_immediates, number<B, et_on>, V>(a, b);
102 }
103 #endif
104 template <class V, class B>
105 inline BOOST_MP_CXX14_CONSTEXPR 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)106 operator+(const V& a, const number<B, et_on>& b)
107 {
108    return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b);
109 }
110 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
111 template <class V, class B>
112 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, number<B, et_on> >::type
operator +(const V & a,number<B,et_on> && b)113 operator+(const V& a, number<B, et_on>&& b)
114 {
115    return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b);
116 }
117 #endif
118 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
119 inline BOOST_MP_CXX14_CONSTEXPR 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)120 operator+(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
121 {
122    return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
123 }
124 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
125 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
126 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type
operator +(number<B,ET> && a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)127 operator+(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
128 {
129    return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
130 }
131 #endif
132 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
133 inline BOOST_MP_CXX14_CONSTEXPR 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)134 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
135 {
136    return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
137 }
138 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
139 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
140 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type
operator +(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)141 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
142 {
143    return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
144 }
145 #endif
146 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
147 inline BOOST_MP_CXX14_CONSTEXPR 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)148 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
149 {
150    return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
151 }
152 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
153 inline BOOST_MP_CXX14_CONSTEXPR 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)154 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
155 {
156    return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
157 }
158 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
159 inline BOOST_MP_CXX14_CONSTEXPR 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)160 operator+(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
161 {
162    return detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
163 }
164 //
165 // Fused multiply add:
166 //
167 template <class V, class Arg1, class Arg2, class Arg3, class Arg4>
168 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
169                           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)170 operator+(const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
171 {
172    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);
173 }
174 template <class Arg1, class Arg2, class Arg3, class Arg4, class V>
175 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
176                           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)177 operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
178 {
179    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);
180 }
181 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
182 inline BOOST_MP_CXX14_CONSTEXPR 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)183 operator+(const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
184 {
185    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);
186 }
187 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
188 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
189 inline BOOST_MP_CXX14_CONSTEXPR typename 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> >::result_type
operator +(number<B,ET> && a,const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & b)190 operator+(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
191 {
192    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);
193 }
194 #endif
195 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
196 inline BOOST_MP_CXX14_CONSTEXPR 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)197 operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
198 {
199    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);
200 }
201 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
202 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
203 inline BOOST_MP_CXX14_CONSTEXPR typename 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> >::result_type
operator +(const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)204 operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
205 {
206    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);
207 }
208 #endif
209 //
210 // Fused multiply subtract:
211 //
212 template <class V, class Arg1, class Arg2, class Arg3, class Arg4>
213 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
214                           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)215 operator-(const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
216 {
217    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> >(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));
218 }
219 template <class Arg1, class Arg2, class Arg3, class Arg4, class V>
220 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
221                           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)222 operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
223 {
224    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);
225 }
226 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
227 inline BOOST_MP_CXX14_CONSTEXPR 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)228 operator-(const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
229 {
230    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> > >(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));
231 }
232 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
233 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
234 inline BOOST_MP_CXX14_CONSTEXPR typename 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> > >::result_type
operator -(number<B,ET> && a,const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & b)235 operator-(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
236 {
237    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> > >(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));
238 }
239 #endif
240 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
241 inline BOOST_MP_CXX14_CONSTEXPR 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)242 operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
243 {
244    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);
245 }
246 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
247 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
248 inline BOOST_MP_CXX14_CONSTEXPR typename 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> >::result_type
operator -(const detail::expression<detail::multiply_immediates,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)249 operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
250 {
251    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);
252 }
253 #endif
254 //
255 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
256 //
257 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
258 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, number<B, ET>, Arg1>
operator +(const number<B,ET> & a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)259 operator+(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
260 {
261    return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref());
262 }
263 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
264 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
265 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type
operator +(number<B,ET> && a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)266 operator+(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
267 {
268    return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref());
269 }
270 #endif
271 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
272 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, number<B, ET>, Arg1>
operator +(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,const number<B,ET> & b)273 operator+(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
274 {
275    return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref());
276 }
277 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
278 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
279 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type
operator +(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)280 operator+(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
281 {
282    return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref());
283 }
284 #endif
285 template <class B>
286 inline BOOST_MP_CXX14_CONSTEXPR 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)287 operator+(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
288 {
289    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
290 }
291 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
292 template <class B>
293 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >::result_type
operator +(number<B,et_on> && a,const detail::expression<detail::negate,number<B,et_on>> & b)294 operator+(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
295 {
296    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
297 }
298 #endif
299 template <class B>
300 inline BOOST_MP_CXX14_CONSTEXPR 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)301 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
302 {
303    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref());
304 }
305 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
306 template <class B>
307 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >::result_type
operator +(const detail::expression<detail::negate,number<B,et_on>> & a,number<B,et_on> && b)308 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
309 {
310    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref());
311 }
312 #endif
313 template <class B, class V>
314 inline BOOST_MP_CXX14_CONSTEXPR 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)315 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
316 {
317    return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(b, a.left_ref());
318 }
319 template <class B, class B2, expression_template_option ET>
320 inline BOOST_MP_CXX14_CONSTEXPR 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)321 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
322 {
323    return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref());
324 }
325 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
326 template <class B, class B2, expression_template_option ET>
327 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, typename detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type
operator +(const detail::expression<detail::negate,number<B,et_on>> & a,number<B2,ET> && b)328 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b)
329 {
330    return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref());
331 }
332 #endif
333 template <class B2, expression_template_option ET, class B>
334 inline BOOST_MP_CXX14_CONSTEXPR 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)335 operator+(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
336 {
337    return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
338 }
339 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
340 template <class B2, expression_template_option ET, class B>
341 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, typename detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type
operator +(number<B2,ET> && a,const detail::expression<detail::negate,number<B,et_on>> & b)342 operator+(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
343 {
344    return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
345 }
346 #endif
347 template <class B>
348 inline BOOST_MP_CXX14_CONSTEXPR 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)349 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const detail::expression<detail::negate, number<B, et_on> >& b)
350 {
351    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()));
352 }
353 //
354 // Subtraction:
355 //
356 template <class B>
357 inline BOOST_MP_CXX14_CONSTEXPR 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)358 operator-(const number<B, et_on>& a, const number<B, et_on>& b)
359 {
360    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b);
361 }
362 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
363 template <class B>
364 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator -(number<B,et_on> && a,const number<B,et_on> & b)365 operator-(number<B, et_on>&& a, const number<B, et_on>& b)
366 {
367    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b);
368 }
369 template <class B>
370 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator -(const number<B,et_on> & a,number<B,et_on> && b)371 operator-(const number<B, et_on>& a, number<B, et_on>&& b)
372 {
373    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b);
374 }
375 template <class B>
376 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator -(number<B,et_on> && a,number<B,et_on> && b)377 operator-(number<B, et_on>&& a, number<B, et_on>&& b)
378 {
379    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b);
380 }
381 #endif
382 template <class B, class V>
383 inline BOOST_MP_CXX14_CONSTEXPR 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)384 operator-(const number<B, et_on>& a, const V& b)
385 {
386    return detail::expression<detail::subtract_immediates, number<B, et_on>, V>(a, b);
387 }
388 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
389 template <class B, class V>
390 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, number<B, et_on> >::type
operator -(number<B,et_on> && a,const V & b)391 operator-(number<B, et_on>&& a, const V& b)
392 {
393    return detail::expression<detail::subtract_immediates, number<B, et_on>, V>(a, b);
394 }
395 #endif
396 template <class V, class B>
397 inline BOOST_MP_CXX14_CONSTEXPR 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)398 operator-(const V& a, const number<B, et_on>& b)
399 {
400    return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(a, b);
401 }
402 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
403 template <class V, class B>
404 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, number<B, et_on> >::type
operator -(const V & a,number<B,et_on> && b)405 operator-(const V& a, number<B, et_on>&& b)
406 {
407    return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(a, b);
408 }
409 #endif
410 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
411 inline BOOST_MP_CXX14_CONSTEXPR 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)412 operator-(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
413 {
414    return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
415 }
416 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
417 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
418 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type
operator -(number<B,ET> && a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)419 operator-(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
420 {
421    return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
422 }
423 #endif
424 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
425 inline BOOST_MP_CXX14_CONSTEXPR 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)426 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
427 {
428    return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
429 }
430 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
431 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
432 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type
operator -(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)433 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
434 {
435    return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
436 }
437 #endif
438 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
439 inline BOOST_MP_CXX14_CONSTEXPR 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)440 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
441 {
442    return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
443 }
444 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
445 inline BOOST_MP_CXX14_CONSTEXPR 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)446 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
447 {
448    return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
449 }
450 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
451 inline BOOST_MP_CXX14_CONSTEXPR 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)452 operator-(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
453 {
454    return detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
455 }
456 //
457 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
458 //
459 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
460 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, number<B, ET>, Arg1>
operator -(const number<B,ET> & a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)461 operator-(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
462 {
463    return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref());
464 }
465 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
466 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
467 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type
operator -(number<B,ET> && a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)468 operator-(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
469 {
470    return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref());
471 }
472 #endif
473 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
474 inline BOOST_MP_CXX14_CONSTEXPR 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)475 operator-(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
476 {
477    return detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >(
478        detail::expression<detail::plus, number<B, ET>, Arg1>(b, a.left_ref()));
479 }
480 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
481 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
482 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type
operator -(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)483 operator-(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
484 {
485    return detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >(
486        detail::expression<detail::plus, number<B, ET>, Arg1>(b, a.left_ref()));
487 }
488 #endif
489 template <class B>
490 inline BOOST_MP_CXX14_CONSTEXPR 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)491 operator-(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
492 {
493    return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
494 }
495 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
496 template <class B>
497 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >::result_type
operator -(number<B,et_on> && a,const detail::expression<detail::negate,number<B,et_on>> & b)498 operator-(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
499 {
500    return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
501 }
502 #endif
503 template <class B>
504 inline BOOST_MP_CXX14_CONSTEXPR 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)505 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
506 {
507    return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >(
508        detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
509 }
510 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
511 template <class B>
512 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type
operator -(const detail::expression<detail::negate,number<B,et_on>> & a,number<B,et_on> && b)513 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
514 {
515    return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >(
516        detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
517 }
518 #endif
519 template <class B, class V>
520 inline BOOST_MP_CXX14_CONSTEXPR 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)521 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
522 {
523    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));
524 }
525 template <class B, class B2, expression_template_option ET>
526 inline BOOST_MP_CXX14_CONSTEXPR 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)527 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
528 {
529    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));
530 }
531 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
532 template <class B, class B2, expression_template_option ET>
533 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type
operator -(const detail::expression<detail::negate,number<B,et_on>> & a,number<B2,ET> && b)534 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b)
535 {
536    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));
537 }
538 #endif
539 template <class V, class B>
540 inline BOOST_MP_CXX14_CONSTEXPR 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)541 operator-(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
542 {
543    return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b.left_ref());
544 }
545 template <class B2, expression_template_option ET, class B>
546 inline BOOST_MP_CXX14_CONSTEXPR 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)547 operator-(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
548 {
549    return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
550 }
551 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
552 template <class B2, expression_template_option ET, class B>
553 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, typename detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type
operator -(number<B2,ET> && a,const detail::expression<detail::negate,number<B,et_on>> & b)554 operator-(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
555 {
556    return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
557 }
558 #endif
559 //
560 // Multiplication:
561 //
562 template <class B>
563 inline BOOST_MP_CXX14_CONSTEXPR 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)564 operator*(const number<B, et_on>& a, const number<B, et_on>& b)
565 {
566    return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b);
567 }
568 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
569 template <class B>
570 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator *(number<B,et_on> && a,const number<B,et_on> & b)571 operator*(number<B, et_on>&& a, const number<B, et_on>& b)
572 {
573    return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b);
574 }
575 template <class B>
576 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator *(const number<B,et_on> & a,number<B,et_on> && b)577 operator*(const number<B, et_on>& a, number<B, et_on>&& b)
578 {
579    return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b);
580 }
581 template <class B>
582 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator *(number<B,et_on> && a,number<B,et_on> && b)583 operator*(number<B, et_on>&& a, number<B, et_on>&& b)
584 {
585    return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b);
586 }
587 #endif
588 template <class B, class V>
589 inline BOOST_MP_CXX14_CONSTEXPR 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)590 operator*(const number<B, et_on>& a, const V& b)
591 {
592    return detail::expression<detail::multiply_immediates, number<B, et_on>, V>(a, b);
593 }
594 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
595 template <class B, class V>
596 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, number<B, et_on> >::type
operator *(number<B,et_on> && a,const V & b)597 operator*(number<B, et_on>&& a, const V& b)
598 {
599    return detail::expression<detail::multiply_immediates, number<B, et_on>, V>(a, b);
600 }
601 #endif
602 template <class V, class B>
603 inline BOOST_MP_CXX14_CONSTEXPR 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)604 operator*(const V& a, const number<B, et_on>& b)
605 {
606    return detail::expression<detail::multiply_immediates, V, number<B, et_on> >(a, b);
607 }
608 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
609 template <class V, class B>
610 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, number<B, et_on> >::type
operator *(const V & a,number<B,et_on> && b)611 operator*(const V& a, number<B, et_on>&& b)
612 {
613    return detail::expression<detail::multiply_immediates, V, number<B, et_on> >(a, b);
614 }
615 #endif
616 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
617 inline BOOST_MP_CXX14_CONSTEXPR 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)618 operator*(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
619 {
620    return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
621 }
622 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
623 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
624 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type
operator *(number<B,ET> && a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)625 operator*(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
626 {
627    return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
628 }
629 #endif
630 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
631 inline BOOST_MP_CXX14_CONSTEXPR 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)632 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
633 {
634    return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
635 }
636 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
637 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
638 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type
operator *(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)639 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
640 {
641    return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
642 }
643 #endif
644 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
645 inline BOOST_MP_CXX14_CONSTEXPR 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)646 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
647 {
648    return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
649 }
650 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
651 inline BOOST_MP_CXX14_CONSTEXPR 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)652 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
653 {
654    return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
655 }
656 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
657 inline BOOST_MP_CXX14_CONSTEXPR 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)658 operator*(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
659 {
660    return detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
661 }
662 //
663 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
664 //
665 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
666 inline BOOST_MP_CXX14_CONSTEXPR 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)667 operator*(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
668 {
669    return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
670        detail::expression<detail::multiplies, number<B, ET>, Arg1>(a, b.left_ref()));
671 }
672 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
673 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
674 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >::result_type
operator *(number<B,ET> && a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)675 operator*(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
676 {
677    return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
678        detail::expression<detail::multiplies, number<B, ET>, Arg1>(a, b.left_ref()));
679 }
680 #endif
681 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
682 inline BOOST_MP_CXX14_CONSTEXPR 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)683 operator*(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
684 {
685    return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
686        detail::expression<detail::multiplies, number<B, ET>, Arg1>(b, a.left_ref()));
687 }
688 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
689 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
690 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >::result_type
operator *(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)691 operator*(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
692 {
693    return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
694        detail::expression<detail::multiplies, number<B, ET>, Arg1>(b, a.left_ref()));
695 }
696 #endif
697 template <class B>
698 inline BOOST_MP_CXX14_CONSTEXPR 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)699 operator*(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
700 {
701    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
702        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
703 }
704 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
705 template <class B>
706 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type
operator *(number<B,et_on> && a,const detail::expression<detail::negate,number<B,et_on>> & b)707 operator*(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
708 {
709    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
710        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
711 }
712 #endif
713 template <class B>
714 inline BOOST_MP_CXX14_CONSTEXPR 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)715 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
716 {
717    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
718        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
719 }
720 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
721 template <class B>
722 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type
operator *(const detail::expression<detail::negate,number<B,et_on>> & a,number<B,et_on> && b)723 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
724 {
725    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
726        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
727 }
728 #endif
729 template <class B, class V>
730 inline BOOST_MP_CXX14_CONSTEXPR 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)731 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
732 {
733    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> >(
734        detail::expression<detail::multiply_immediates, number<B, et_on>, V>(a.left_ref(), b));
735 }
736 template <class B, class B2, expression_template_option ET>
737 inline BOOST_MP_CXX14_CONSTEXPR 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)738 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
739 {
740    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
741        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
742 }
743 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
744 template <class B, class B2, expression_template_option ET>
745 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >::result_type >::type
operator *(const detail::expression<detail::negate,number<B,et_on>> & a,number<B2,ET> && b)746 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b)
747 {
748    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
749        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
750 }
751 #endif
752 template <class V, class B>
753 inline BOOST_MP_CXX14_CONSTEXPR 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)754 operator*(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
755 {
756    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> >(
757        detail::expression<detail::multiply_immediates, number<B, et_on>, V>(b.left_ref(), a));
758 }
759 template <class B2, expression_template_option ET, class B>
760 inline BOOST_MP_CXX14_CONSTEXPR 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)761 operator*(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
762 {
763    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
764        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(b.left_ref(), a));
765 }
766 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
767 template <class B2, expression_template_option ET, class B>
768 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type
operator *(number<B2,ET> && a,const detail::expression<detail::negate,number<B,et_on>> & b)769 operator*(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
770 {
771    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
772        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(b.left_ref(), a));
773 }
774 #endif
775 //
776 // Division:
777 //
778 template <class B>
779 inline BOOST_MP_CXX14_CONSTEXPR 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)780 operator/(const number<B, et_on>& a, const number<B, et_on>& b)
781 {
782    return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b);
783 }
784 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
785 template <class B>
786 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator /(number<B,et_on> && a,const number<B,et_on> & b)787 operator/(number<B, et_on>&& a, const number<B, et_on>& b)
788 {
789    return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b);
790 }
791 template <class B>
792 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator /(const number<B,et_on> & a,number<B,et_on> && b)793 operator/(const number<B, et_on>& a, number<B, et_on>&& b)
794 {
795    return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b);
796 }
797 template <class B>
798 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
operator /(number<B,et_on> && a,number<B,et_on> && b)799 operator/(number<B, et_on>&& a, number<B, et_on>&& b)
800 {
801    return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b);
802 }
803 #endif
804 template <class B, class V>
805 inline BOOST_MP_CXX14_CONSTEXPR 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)806 operator/(const number<B, et_on>& a, const V& b)
807 {
808    return detail::expression<detail::divide_immediates, number<B, et_on>, V>(a, b);
809 }
810 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
811 template <class B, class V>
812 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, number<B, et_on> >::type
operator /(number<B,et_on> && a,const V & b)813 operator/(number<B, et_on>&& a, const V& b)
814 {
815    return detail::expression<detail::divide_immediates, number<B, et_on>, V>(a, b);
816 }
817 #endif
818 template <class V, class B>
819 inline BOOST_MP_CXX14_CONSTEXPR 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)820 operator/(const V& a, const number<B, et_on>& b)
821 {
822    return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b);
823 }
824 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
825 template <class V, class B>
826 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, number<B, et_on> >::type
operator /(const V & a,number<B,et_on> && b)827 operator/(const V& a, number<B, et_on>&& b)
828 {
829    return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b);
830 }
831 #endif
832 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
833 inline BOOST_MP_CXX14_CONSTEXPR 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)834 operator/(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
835 {
836    return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
837 }
838 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
839 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
840 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type
operator /(number<B,ET> && a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)841 operator/(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
842 {
843    return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
844 }
845 #endif
846 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
847 inline BOOST_MP_CXX14_CONSTEXPR 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)848 operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
849 {
850    return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
851 }
852 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
853 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
854 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type
operator /(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)855 operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
856 {
857    return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
858 }
859 #endif
860 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
861 inline BOOST_MP_CXX14_CONSTEXPR 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)862 operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
863 {
864    return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
865 }
866 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
867 inline BOOST_MP_CXX14_CONSTEXPR 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)868 operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
869 {
870    return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
871 }
872 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
873 inline BOOST_MP_CXX14_CONSTEXPR 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)874 operator/(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
875 {
876    return detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
877 }
878 //
879 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
880 //
881 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
882 inline BOOST_MP_CXX14_CONSTEXPR 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)883 operator/(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
884 {
885    return detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >(
886        detail::expression<detail::divides, number<B, ET>, Arg1>(a, b.left_ref()));
887 }
888 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
889 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
890 inline typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type
operator /(number<B,ET> && a,const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & b)891 operator/(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
892 {
893    return detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >(
894        detail::expression<detail::divides, number<B, ET>, Arg1>(a, b.left_ref()));
895 }
896 #endif
897 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
898 inline BOOST_MP_CXX14_CONSTEXPR 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)899 operator/(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
900 {
901    return detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >(
902        detail::expression<detail::divides, Arg1, number<B, ET> >(a.left_ref(), b));
903 }
904 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
905 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
906 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >::result_type
operator /(const detail::expression<detail::negate,Arg1,Arg2,Arg3,Arg4> & a,number<B,ET> && b)907 operator/(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
908 {
909    return detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >(
910        detail::expression<detail::divides, Arg1, number<B, ET> >(a.left_ref(), b));
911 }
912 #endif
913 template <class B>
914 inline BOOST_MP_CXX14_CONSTEXPR 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)915 operator/(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
916 {
917    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
918        detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
919 }
920 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
921 template <class B>
922 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >::result_type
operator /(number<B,et_on> && a,const detail::expression<detail::negate,number<B,et_on>> & b)923 operator/(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
924 {
925    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
926        detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
927 }
928 #endif
929 template <class B>
930 inline BOOST_MP_CXX14_CONSTEXPR 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)931 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
932 {
933    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
934        detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b));
935 }
936 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
937 template <class B>
938 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >::result_type
operator /(const detail::expression<detail::negate,number<B,et_on>> & a,number<B,et_on> && b)939 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
940 {
941    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
942        detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b));
943 }
944 #endif
945 template <class B, class V>
946 inline BOOST_MP_CXX14_CONSTEXPR 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)947 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
948 {
949    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V> >(
950        detail::expression<detail::divide_immediates, number<B, et_on>, V>(a.left_ref(), b));
951 }
952 template <class B, class B2, expression_template_option ET>
953 inline BOOST_MP_CXX14_CONSTEXPR 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)954 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
955 {
956    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >(
957        detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
958 }
959 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
960 template <class B, class B2, expression_template_option ET>
961 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type
operator /(const detail::expression<detail::negate,number<B,et_on>> & a,number<B2,ET> && b)962 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b)
963 {
964    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >(
965        detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
966 }
967 #endif
968 template <class V, class B>
969 inline BOOST_MP_CXX14_CONSTEXPR 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)970 operator/(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
971 {
972    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > >(
973        detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b.left_ref()));
974 }
975 template <class B2, expression_template_option ET, class B>
976 inline BOOST_MP_CXX14_CONSTEXPR 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)977 operator/(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
978 {
979    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >(
980        detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()));
981 }
982 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
983 template <class B2, expression_template_option ET, class B>
984 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >::result_type >, number<B, et_on> >::type
operator /(number<B2,ET> && a,const detail::expression<detail::negate,number<B,et_on>> & b)985 operator/(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
986 {
987    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >(
988        detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()));
989 }
990 #endif
991 //
992 // Modulus:
993 //
994 template <class B>
995 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
996                             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)997 operator%(const number<B, et_on>& a, const number<B, et_on>& b)
998 {
999    return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1000 }
1001 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1002 template <class B>
1003 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1004    number<B, et_on> >::type
operator %(number<B,et_on> && a,const number<B,et_on> & b)1005 operator%(number<B, et_on>&& a, const number<B, et_on>& b)
1006 {
1007    return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1008 }
1009 template <class B>
1010 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1011    number<B, et_on> >::type
operator %(const number<B,et_on> & a,number<B,et_on> && b)1012 operator%(const number<B, et_on>& a, number<B, et_on>&& b)
1013 {
1014    return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1015 }
1016 template <class B>
1017 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1018    number<B, et_on> >::type
operator %(number<B,et_on> && a,number<B,et_on> && b)1019 operator%(number<B, et_on>&& a, number<B, et_on>&& b)
1020 {
1021    return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1022 }
1023 #endif
1024 template <class B, class V>
1025 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1026                             detail::expression<detail::modulus_immediates, number<B, et_on>, V> >::type
operator %(const number<B,et_on> & a,const V & b)1027 operator%(const number<B, et_on>& a, const V& b)
1028 {
1029    return detail::expression<detail::modulus_immediates, number<B, et_on>, V>(a, b);
1030 }
1031 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1032 template <class B, class V>
1033 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1034    number<B, et_on> >::type
operator %(number<B,et_on> && a,const V & b)1035 operator%(number<B, et_on>&& a, const V& b)
1036 {
1037    return detail::expression<detail::modulus_immediates, number<B, et_on>, V>(a, b);
1038 }
1039 #endif
1040 template <class V, class B>
1041 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1042                             detail::expression<detail::modulus_immediates, V, number<B, et_on> > >::type
operator %(const V & a,const number<B,et_on> & b)1043 operator%(const V& a, const number<B, et_on>& b)
1044 {
1045    return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b);
1046 }
1047 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1048 template <class V, class B>
1049 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1050    number<B, et_on> >::type
operator %(const V & a,number<B,et_on> && b)1051 operator%(const V& a, number<B, et_on>&& b)
1052 {
1053    return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b);
1054 }
1055 #endif
1056 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1057 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1058                             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)1059 operator%(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1060 {
1061    return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1062 }
1063 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1064 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1065 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1066    typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type
operator %(number<B,et_on> && a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)1067 operator%(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1068 {
1069    return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1070 }
1071 #endif
1072 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1073 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1074                             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)1075 operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
1076 {
1077    return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1078 }
1079 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1080 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1081 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1082    typename detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type >::type
operator %(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,number<B,et_on> && b)1083 operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1084 {
1085    return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1086 }
1087 #endif
1088 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1089 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
1090                             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)1091 operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1092 {
1093    return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1094 }
1095 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1096 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1097                             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)1098 operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1099 {
1100    return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1101 }
1102 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1103 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1104                             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)1105 operator%(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1106 {
1107    return detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1108 }
1109 //
1110 // Left shift:
1111 //
1112 template <class B, class I>
1113 inline BOOST_MP_CXX14_CONSTEXPR 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)1114 operator<<(const number<B, et_on>& a, const I& b)
1115 {
1116    return detail::expression<detail::shift_left, number<B, et_on>, I>(a, b);
1117 }
1118 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1119 template <class B, class I>
1120 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_on> >::type
operator <<(number<B,et_on> && a,const I & b)1121 operator<<(number<B, et_on>&& a, const I& b)
1122 {
1123    return detail::expression<detail::shift_left, number<B, et_on>, I>(a, b);
1124 }
1125 #endif
1126 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
1127 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1128                             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)1129 operator<<(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
1130 {
1131    return detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
1132 }
1133 //
1134 // Right shift:
1135 //
1136 template <class B, class I>
1137 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer),
1138                             detail::expression<detail::shift_right, number<B, et_on>, I> >::type
operator >>(const number<B,et_on> & a,const I & b)1139 operator>>(const number<B, et_on>& a, const I& b)
1140 {
1141    return detail::expression<detail::shift_right, number<B, et_on>, I>(a, b);
1142 }
1143 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1144 template <class B, class I>
1145 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer),
1146    number<B, et_on> >::type
operator >>(number<B,et_on> && a,const I & b)1147 operator>>(number<B, et_on>&& a, const I& b)
1148 {
1149    return detail::expression<detail::shift_right, number<B, et_on>, I>(a, b);
1150 }
1151 #endif
1152 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
1153 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1154                             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)1155 operator>>(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
1156 {
1157    return detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
1158 }
1159 //
1160 // Bitwise AND:
1161 //
1162 template <class B>
1163 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1164                             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)1165 operator&(const number<B, et_on>& a, const number<B, et_on>& b)
1166 {
1167    return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1168 }
1169 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1170 template <class B>
1171 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1172    number<B, et_on> >::type
operator &(number<B,et_on> && a,const number<B,et_on> & b)1173 operator&(number<B, et_on>&& a, const number<B, et_on>& b)
1174 {
1175    return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1176 }
1177 template <class B>
1178 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1179    number<B, et_on> >::type
operator &(const number<B,et_on> & a,number<B,et_on> && b)1180 operator&(const number<B, et_on>& a, number<B, et_on>&& b)
1181 {
1182    return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1183 }
1184 template <class B>
1185 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1186    number<B, et_on> >::type
operator &(number<B,et_on> && a,number<B,et_on> && b)1187 operator&(number<B, et_on>&& a, number<B, et_on>&& b)
1188 {
1189    return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1190 }
1191 #endif
1192 template <class B, class V>
1193 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1194                             detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V> >::type
operator &(const number<B,et_on> & a,const V & b)1195 operator&(const number<B, et_on>& a, const V& b)
1196 {
1197    return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V>(a, b);
1198 }
1199 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1200 template <class B, class V>
1201 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1202    number<B, et_on> >::type
operator &(number<B,et_on> && a,const V & b)1203 operator&(number<B, et_on>&& a, const V& b)
1204 {
1205    return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V>(a, b);
1206 }
1207 #endif
1208 template <class V, class B>
1209 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1210                             detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> > >::type
operator &(const V & a,const number<B,et_on> & b)1211 operator&(const V& a, const number<B, et_on>& b)
1212 {
1213    return detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> >(a, b);
1214 }
1215 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1216 template <class V, class B>
1217 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1218    number<B, et_on> >::type
operator &(const V & a,number<B,et_on> && b)1219 operator&(const V& a, number<B, et_on>&& b)
1220 {
1221    return detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> >(a, b);
1222 }
1223 #endif
1224 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1225 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1226                             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)1227 operator&(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1228 {
1229    return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1230 }
1231 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1232 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1233 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1234    typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type
operator &(number<B,et_on> && a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)1235 operator&(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1236 {
1237    return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1238 }
1239 #endif
1240 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1241 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1242                             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)1243 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
1244 {
1245    return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1246 }
1247 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1248 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1249 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1250    typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type >::type
operator &(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,number<B,et_on> && b)1251 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1252 {
1253    return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1254 }
1255 #endif
1256 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1257 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
1258                             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)1259 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1260 {
1261    return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1262 }
1263 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1264 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1265                             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)1266 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1267 {
1268    return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1269 }
1270 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1271 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1272                             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)1273 operator&(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1274 {
1275    return detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1276 }
1277 //
1278 // Bitwise OR:
1279 //
1280 template <class B>
1281 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1282                             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)1283 operator|(const number<B, et_on>& a, const number<B, et_on>& b)
1284 {
1285    return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1286 }
1287 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1288 template <class B>
1289 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1290    number<B, et_on> >::type
operator |(number<B,et_on> && a,const number<B,et_on> & b)1291 operator|(number<B, et_on>&& a, const number<B, et_on>& b)
1292 {
1293    return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1294 }
1295 template <class B>
1296 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1297    number<B, et_on> >::type
operator |(const number<B,et_on> & a,number<B,et_on> && b)1298 operator|(const number<B, et_on>& a, number<B, et_on>&& b)
1299 {
1300    return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1301 }
1302 template <class B>
1303 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1304    number<B, et_on> >::type
operator |(number<B,et_on> && a,number<B,et_on> && b)1305 operator|(number<B, et_on>&& a, number<B, et_on>&& b)
1306 {
1307    return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1308 }
1309 #endif
1310 template <class B, class V>
1311 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1312                             detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V> >::type
operator |(const number<B,et_on> & a,const V & b)1313 operator|(const number<B, et_on>& a, const V& b)
1314 {
1315    return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V>(a, b);
1316 }
1317 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1318 template <class B, class V>
1319 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1320    number<B, et_on> >::type
operator |(number<B,et_on> && a,const V & b)1321 operator|(number<B, et_on>&& a, const V& b)
1322 {
1323    return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V>(a, b);
1324 }
1325 #endif
1326 template <class V, class B>
1327 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1328                             detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> > >::type
operator |(const V & a,const number<B,et_on> & b)1329 operator|(const V& a, const number<B, et_on>& b)
1330 {
1331    return detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> >(a, b);
1332 }
1333 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1334 template <class V, class B>
1335 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1336    number<B, et_on> >::type
operator |(const V & a,number<B,et_on> && b)1337 operator|(const V& a, number<B, et_on>&& b)
1338 {
1339    return detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> >(a, b);
1340 }
1341 #endif
1342 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1343 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1344                             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)1345 operator|(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1346 {
1347    return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1348 }
1349 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1350 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1351 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1352    typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
operator |(number<B,et_on> && a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)1353 operator|(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1354 {
1355    return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1356 }
1357 #endif
1358 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1359 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1360                             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)1361 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
1362 {
1363    return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1364 }
1365 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1366 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1367 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1368    typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type
operator |(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,number<B,et_on> && b)1369 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1370 {
1371    return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1372 }
1373 #endif
1374 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1375 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
1376                             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)1377 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1378 {
1379    return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1380 }
1381 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1382 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1383                             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)1384 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1385 {
1386    return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1387 }
1388 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1389 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1390                             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)1391 operator|(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1392 {
1393    return detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1394 }
1395 //
1396 // Bitwise XOR:
1397 //
1398 template <class B>
1399 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1400                             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)1401 operator^(const number<B, et_on>& a, const number<B, et_on>& b)
1402 {
1403    return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1404 }
1405 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1406 template <class B>
1407 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1408    number<B, et_on> >::type
operator ^(number<B,et_on> && a,const number<B,et_on> & b)1409 operator^(number<B, et_on>&& a, const number<B, et_on>& b)
1410 {
1411    return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1412 }
1413 template <class B>
1414 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1415    number<B, et_on> >::type
operator ^(const number<B,et_on> & a,number<B,et_on> && b)1416 operator^(const number<B, et_on>& a, number<B, et_on>&& b)
1417 {
1418    return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1419 }
1420 template <class B>
1421 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1422    number<B, et_on> >::type
operator ^(number<B,et_on> && a,number<B,et_on> && b)1423 operator^(number<B, et_on>&& a, number<B, et_on>&& b)
1424 {
1425    return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1426 }
1427 #endif
1428 template <class B, class V>
1429 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1430                             detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V> >::type
operator ^(const number<B,et_on> & a,const V & b)1431 operator^(const number<B, et_on>& a, const V& b)
1432 {
1433    return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V>(a, b);
1434 }
1435 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1436 template <class B, class V>
1437 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1438    number<B, et_on> >::type
operator ^(number<B,et_on> && a,const V & b)1439 operator^(number<B, et_on>&& a, const V& b)
1440 {
1441    return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V>(a, b);
1442 }
1443 #endif
1444 template <class V, class B>
1445 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1446                             detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> > >::type
operator ^(const V & a,const number<B,et_on> & b)1447 operator^(const V& a, const number<B, et_on>& b)
1448 {
1449    return detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> >(a, b);
1450 }
1451 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1452 template <class V, class B>
1453 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1454    number<B, et_on> >::type
operator ^(const V & a,number<B,et_on> && b)1455 operator^(const V& a, number<B, et_on>&& b)
1456 {
1457    return detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> >(a, b);
1458 }
1459 #endif
1460 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1461 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1462                             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)1463 operator^(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1464 {
1465    return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1466 }
1467 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1468 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1469 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1470    typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
operator ^(number<B,et_on> && a,const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & b)1471 operator^(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1472 {
1473    return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1474 }
1475 #endif
1476 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1477 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1478                             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)1479 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
1480 {
1481    return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1482 }
1483 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1484 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1485 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<B>::value == number_kind_integer,
1486    typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type
operator ^(const detail::expression<tag,Arg1,Arg2,Arg3,Arg4> & a,number<B,et_on> && b)1487 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1488 {
1489    return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1490 }
1491 #endif
1492 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1493 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
1494                             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)1495 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1496 {
1497    return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1498 }
1499 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1500 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1501                             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)1502 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1503 {
1504    return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1505 }
1506 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1507 inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (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)1508 operator^(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1509 {
1510    return detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1511 }
1512 
1513 }} // namespace boost::multiprecision
1514 
1515 #endif
1516