Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:21

0001 ///////////////////////////////////////////////////////////////////////////////
0002 //  Copyright 2011 John Maddock. Distributed under the Boost
0003 //  Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_MP_ET_OPS_HPP
0007 #define BOOST_MP_ET_OPS_HPP
0008 
0009 namespace boost { namespace multiprecision {
0010 
0011 //
0012 // Non-member operators for number which return expression templates.
0013 // 
0014 // Note that operators taking rvalue-references DO NOT return expression templates
0015 // as this can lead to dangling references, see https://github.com/boostorg/multiprecision/issues/175.
0016 //
0017 // Unary operators first.
0018 // Note that these *must* return by value, even though that's somewhat against
0019 // existing practice.  The issue is that in C++11 land one could easily and legitimately
0020 // write:
0021 //    auto x = +1234_my_user_defined_suffix;
0022 // which would result in a dangling-reference-to-temporary if unary + returned a reference
0023 // to it's argument.  While return-by-value is obviously inefficient in other situations
0024 // the reality is that no one ever uses unary operator+ anyway...!
0025 //
0026 template <class B, expression_template_option ExpressionTemplates>
0027 inline constexpr const number<B, ExpressionTemplates> operator+(const number<B, ExpressionTemplates>& v) { return v; }
0028 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0029 inline constexpr const detail::expression<tag, Arg1, Arg2, Arg3, Arg4> operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return v; }
0030 template <class B>
0031 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, number<B, et_on> > operator-(const number<B, et_on>& v)
0032 {
0033    static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
0034    return detail::expression<detail::negate, number<B, et_on> >(v);
0035 }
0036 // rvalue ops:
0037 template <class B>
0038 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> operator-(number<B, et_on>&& v)
0039 {
0040    static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
0041    v.backend().negate();
0042    return std::move(v);
0043 }
0044 
0045 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0046 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)
0047 {
0048    static_assert((is_signed_number<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value), "Negating an unsigned type results in ill-defined behavior.");
0049    return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v);
0050 }
0051 template <class B>
0052 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
0053                             detail::expression<detail::complement_immediates, number<B, et_on> > >::type
0054 operator~(const number<B, et_on>& v) { return detail::expression<detail::complement_immediates, number<B, et_on> >(v); }
0055 
0056 template <class B>
0057 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
0058                             number<B, et_on> >::type
0059 operator~(number<B, et_on>&& v) 
0060 { 
0061    using default_ops::eval_complement;
0062    eval_complement(v.backend(), v.backend());
0063    return std::move(v);
0064 }
0065 
0066 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0067 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
0068                             detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
0069 operator~(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v); }
0070 //
0071 // Then addition:
0072 //
0073 template <class B>
0074 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >
0075 operator+(const number<B, et_on>& a, const number<B, et_on>& b)
0076 {
0077    return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b);
0078 }
0079 
0080 template <class B>
0081 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0082 operator+(number<B, et_on>&& a, const number<B, et_on>& b)
0083 {
0084    using default_ops::eval_add;
0085    eval_add(a.backend(), b.backend());
0086    return std::move(a);
0087 }
0088 template <class B>
0089 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0090 operator+(const number<B, et_on>& a, number<B, et_on>&& b)
0091 {
0092    using default_ops::eval_add;
0093    eval_add(b.backend(), a.backend());
0094    return std::move(b);
0095 }
0096 template <class B>
0097 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0098 operator+(number<B, et_on>&& a, number<B, et_on>&& b)
0099 {
0100    using default_ops::eval_add;
0101    eval_add(a.backend(), b.backend());
0102    return std::move(a);
0103 }
0104 
0105 template <class B, class V>
0106 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, detail::expression<detail::add_immediates, number<B, et_on>, V> >::type
0107 operator+(const number<B, et_on>& a, const V& b)
0108 {
0109    return detail::expression<detail::add_immediates, number<B, et_on>, V>(a, b);
0110 }
0111 
0112 template <class B, class V>
0113 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, number<B, et_on> >::type
0114 operator+(number<B, et_on>&& a, const V& b)
0115 {
0116    using default_ops::eval_add;
0117    eval_add(a.backend(), number<B, et_on>::canonical_value(b));
0118    return std::move(a);
0119 }
0120 
0121 template <class V, class B>
0122 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::add_immediates, V, number<B, et_on> > >::type
0123 operator+(const V& a, const number<B, et_on>& b)
0124 {
0125    return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b);
0126 }
0127 
0128 template <class V, class B>
0129 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, number<B, et_on> >::type
0130 operator+(const V& a, number<B, et_on>&& b)
0131 {
0132    using default_ops::eval_add;
0133    eval_add(b.backend(), number<B, et_on>::canonical_value(a));
0134    return std::move(b);
0135 }
0136 
0137 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0138 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
0139 operator+(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0140 {
0141    return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0142 }
0143 
0144 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0145 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< 
0146    std::is_same<typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET> >::value,
0147    typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
0148 operator+(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0149 {
0150    a += b;
0151    return std::move(a);
0152 }
0153 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0154 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< 
0155    !std::is_same<typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET> >::value,
0156    typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
0157 operator+(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0158 {
0159    return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0160 }
0161 
0162 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0163 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
0164 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
0165 {
0166    return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
0167 }
0168 
0169 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0170 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< 
0171    std::is_same<typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value,
0172    typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type
0173 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0174 {
0175    b += a;
0176    return std::move(b);
0177 }
0178 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0179 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< 
0180    !std::is_same<typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value,
0181    typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type
0182 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0183 {
0184    return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
0185 }
0186 
0187 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
0188 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
0189 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
0190 {
0191    return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
0192 }
0193 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
0194 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type
0195 operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
0196 {
0197    return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
0198 }
0199 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0200 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
0201 operator+(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0202 {
0203    return detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0204 }
0205 //
0206 // Fused multiply add:
0207 //
0208 template <class V, class Arg1, class Arg2, class Arg3, class Arg4>
0209 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value,
0210                           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
0211 operator+(const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
0212 {
0213    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);
0214 }
0215 template <class Arg1, class Arg2, class Arg3, class Arg4, class V>
0216 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value,
0217                           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
0218 operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
0219 {
0220    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);
0221 }
0222 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0223 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> >
0224 operator+(const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
0225 {
0226    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);
0227 }
0228 
0229 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0230 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0231    std::is_same<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, number<B, ET>>::value,
0232    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>::type
0233 operator+(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
0234 {
0235    a += b;
0236    return std::move(a);
0237 }
0238 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0239 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0240    !std::is_same<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, number<B, ET>>::value,
0241    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>::type
0242 operator+(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
0243 {
0244    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);
0245 }
0246 
0247 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0248 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> >
0249 operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
0250 {
0251    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);
0252 }
0253 
0254 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0255 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0256    std::is_same<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, number<B, ET>>::value,
0257    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>::type
0258 operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0259 {
0260    b += a;
0261    return std::move(b);
0262 }
0263 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0264 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0265    !std::is_same<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, number<B, ET>>::value,
0266    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>::type
0267 operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0268 {
0269    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);
0270 }
0271 
0272 //
0273 // Fused multiply subtract:
0274 //
0275 template <class V, class Arg1, class Arg2, class Arg3, class Arg4>
0276 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value,
0277                           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
0278 operator-(const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
0279 {
0280    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));
0281 }
0282 template <class Arg1, class Arg2, class Arg3, class Arg4, class V>
0283 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value,
0284                           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
0285 operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
0286 {
0287    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);
0288 }
0289 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0290 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> > >
0291 operator-(const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
0292 {
0293    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));
0294 }
0295 
0296 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0297 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0298    std::is_same<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, number<B, ET>>::value,
0299    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>::type
0300 operator-(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
0301 {
0302    a -= b;
0303    return std::move(a);
0304 }
0305 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0306 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0307    !std::is_same<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, number<B, ET>>::value,
0308    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>::type
0309 operator-(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
0310 {
0311    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));
0312 }
0313 
0314 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0315 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> >
0316 operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
0317 {
0318    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);
0319 }
0320 
0321 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0322 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
0323 operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0324 {
0325    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);
0326 }
0327 
0328 //
0329 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
0330 //
0331 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0332 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, number<B, ET>, Arg1>
0333 operator+(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
0334 {
0335    return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref());
0336 }
0337 
0338 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0339 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0340    std::is_same<typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value,
0341    typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type>::type
0342 operator+(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
0343 {
0344    a -= b.left_ref();
0345    return std::move(a);
0346 }
0347 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0348 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0349    !std::is_same<typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value,
0350    typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type>::type
0351 operator+(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
0352 {
0353    return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref());
0354 }
0355 
0356 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0357 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, number<B, ET>, Arg1>
0358 operator+(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
0359 {
0360    return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref());
0361 }
0362 
0363 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0364 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0365    std::is_same<typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value,
0366    typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type>::type
0367 operator+(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0368 {
0369    b -= a.left_ref();
0370    return std::move(b);
0371 }
0372 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0373 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0374    !std::is_same<typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value,
0375    typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type>::type
0376 operator+(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0377 {
0378    return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref());
0379 }
0380 
0381 template <class B>
0382 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >
0383 operator+(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0384 {
0385    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
0386 }
0387 
0388 template <class B>
0389 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >::result_type
0390 operator+(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0391 {
0392    using default_ops::eval_subtract;
0393    eval_subtract(a.backend(), b.left_ref().backend());
0394    return std::move(a);
0395 }
0396 
0397 template <class B>
0398 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >
0399 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
0400 {
0401    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref());
0402 }
0403 
0404 template <class B>
0405 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >::result_type
0406 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
0407 {
0408    using default_ops::eval_subtract;
0409    eval_subtract(b.backend(), a.left_ref().backend());
0410    return std::move(b);
0411 }
0412 
0413 template <class B, class V>
0414 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, V, number<B, et_on> > >::type
0415 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
0416 {
0417    return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(b, a.left_ref());
0418 }
0419 template <class B, class B2, expression_template_option ET>
0420 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> > >::type
0421 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
0422 {
0423    return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref());
0424 }
0425 
0426 template <class B, class B2, expression_template_option ET>
0427 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type
0428 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b)
0429 {
0430    return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref());
0431 }
0432 
0433 template <class B2, expression_template_option ET, class B>
0434 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> > >::type
0435 operator+(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0436 {
0437    return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
0438 }
0439 
0440 template <class B2, expression_template_option ET, class B>
0441 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type
0442 operator+(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0443 {
0444    return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
0445 }
0446 
0447 template <class B>
0448 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >
0449 operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0450 {
0451    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()));
0452 }
0453 //
0454 // Subtraction:
0455 //
0456 template <class B>
0457 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >
0458 operator-(const number<B, et_on>& a, const number<B, et_on>& b)
0459 {
0460    return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b);
0461 }
0462 
0463 template <class B>
0464 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0465 operator-(number<B, et_on>&& a, const number<B, et_on>& b)
0466 {
0467    using default_ops::eval_subtract;
0468    eval_subtract(a.backend(), b.backend());
0469    return std::move(a);
0470 }
0471 template <class B>
0472 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0473 operator-(const number<B, et_on>& a, number<B, et_on>&& b)
0474 {
0475    using default_ops::eval_subtract;
0476    eval_subtract(b.backend(), a.backend());
0477    b.backend().negate();
0478    return std::move(b);
0479 }
0480 template <class B>
0481 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0482 operator-(number<B, et_on>&& a, number<B, et_on>&& b)
0483 {
0484    using default_ops::eval_subtract;
0485    eval_subtract(a.backend(), b.backend());
0486    return std::move(a);
0487 }
0488 
0489 template <class B, class V>
0490 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, number<B, et_on>, V> >::type
0491 operator-(const number<B, et_on>& a, const V& b)
0492 {
0493    return detail::expression<detail::subtract_immediates, number<B, et_on>, V>(a, b);
0494 }
0495 
0496 template <class B, class V>
0497 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, number<B, et_on> >::type
0498 operator-(number<B, et_on>&& a, const V& b)
0499 {
0500    using default_ops::eval_subtract;
0501    eval_subtract(a.backend(), number<B, et_on>::canonical_value(b));
0502    return std::move(a);
0503 }
0504 
0505 template <class V, class B>
0506 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, V, number<B, et_on> > >::type
0507 operator-(const V& a, const number<B, et_on>& b)
0508 {
0509    return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(a, b);
0510 }
0511 
0512 template <class V, class B>
0513 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, number<B, et_on> >::type
0514 operator-(const V& a, number<B, et_on>&& b)
0515 {
0516    using default_ops::eval_subtract;
0517    eval_subtract(b.backend(), number<B, et_on>::canonical_value(a));
0518    b.backend().negate();
0519    return std::move(b);
0520 }
0521 
0522 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0523 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
0524 operator-(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0525 {
0526    return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0527 }
0528 
0529 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0530 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0531    std::is_same<typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value,
0532    typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
0533 operator-(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0534 {
0535    a -= b;
0536    return std::move(a);
0537 }
0538 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0539 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0540    !std::is_same<typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value,
0541    typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
0542 operator-(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0543 {
0544    return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0545 }
0546 
0547 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0548 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
0549 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
0550 {
0551    return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
0552 }
0553 
0554 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0555 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0556    std::is_same<typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value,
0557    typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type
0558 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0559 {
0560    b -= a;
0561    b.backend().negate();
0562    return std::move(b);
0563 }
0564 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0565 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0566    !std::is_same<typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value,
0567    typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type
0568 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0569 {
0570    return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
0571 }
0572 
0573 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
0574 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
0575 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
0576 {
0577    return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
0578 }
0579 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
0580 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type
0581 operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
0582 {
0583    return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
0584 }
0585 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0586 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
0587 operator-(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0588 {
0589    return detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0590 }
0591 //
0592 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
0593 //
0594 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0595 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, number<B, ET>, Arg1>
0596 operator-(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
0597 {
0598    return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref());
0599 }
0600 
0601 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0602 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0603    std::is_same<typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value,
0604    typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type>::type
0605 operator-(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
0606 {
0607    a += b.left_ref();
0608    return std::move(a);
0609 }
0610 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0611 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0612    !std::is_same<typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value,
0613    typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type>::type
0614 operator-(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
0615 {
0616    return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref());
0617 }
0618 
0619 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0620 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >
0621 operator-(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
0622 {
0623    return detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >(
0624        detail::expression<detail::plus, number<B, ET>, Arg1>(b, a.left_ref()));
0625 }
0626 
0627 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0628 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0629    std::is_same<typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type, number<B, ET>>::value,
0630    typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type>::type
0631 operator-(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0632 {
0633    b += a.left_ref();
0634    b.backend().negate();
0635    return std::move(b);
0636 }
0637 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0638 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0639    !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type, number<B, ET>>::value,
0640    typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type>::type
0641 operator-(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0642 {
0643    return detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >(detail::expression<detail::plus, number<B, ET>, Arg1>(b, a.left_ref()));
0644 }
0645 
0646 template <class B>
0647 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >
0648 operator-(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0649 {
0650    return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
0651 }
0652 
0653 template <class B>
0654 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >::result_type
0655 operator-(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0656 {
0657    using default_ops::eval_add;
0658    eval_add(a.backend(), b.left_ref().backend());
0659    return std::move(a);
0660 }
0661 
0662 template <class B>
0663 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >
0664 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
0665 {
0666    return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >(
0667        detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
0668 }
0669 
0670 template <class B>
0671 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0672    std::is_same<typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value,
0673    typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type
0674 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
0675 {
0676    using default_ops::eval_add;
0677    eval_add(b.backend(), a.left_ref().backend());
0678    b.backend().negate();
0679    return std::move(b);
0680 }
0681 template <class B>
0682 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0683    !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value,
0684    typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type
0685 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
0686 {
0687    return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >(
0688          detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
0689 }
0690 
0691 template <class B, class V>
0692 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, V> > >::type
0693 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
0694 {
0695    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));
0696 }
0697 template <class B, class B2, expression_template_option ET>
0698 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > > >::type
0699 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
0700 {
0701    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));
0702 }
0703 
0704 template <class B, class B2, expression_template_option ET>
0705 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type
0706 operator-(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b)
0707 {
0708    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));
0709 }
0710 
0711 template <class V, class B>
0712 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::add_immediates, V, number<B, et_on> > >::type
0713 operator-(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0714 {
0715    return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b.left_ref());
0716 }
0717 template <class B2, expression_template_option ET, class B>
0718 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> > >::type
0719 operator-(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0720 {
0721    return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
0722 }
0723 
0724 template <class B2, expression_template_option ET, class B>
0725 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type
0726 operator-(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0727 {
0728    return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
0729 }
0730 
0731 //
0732 // Multiplication:
0733 //
0734 template <class B>
0735 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >
0736 operator*(const number<B, et_on>& a, const number<B, et_on>& b)
0737 {
0738    return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b);
0739 }
0740 
0741 template <class B>
0742 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0743 operator*(number<B, et_on>&& a, const number<B, et_on>& b)
0744 {
0745    using default_ops::eval_multiply;
0746    eval_multiply(a.backend(), b.backend());
0747    return std::move(a);
0748 }
0749 template <class B>
0750 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0751 operator*(const number<B, et_on>& a, number<B, et_on>&& b)
0752 {
0753    using default_ops::eval_multiply;
0754    eval_multiply(b.backend(), a.backend());
0755    return std::move(b);
0756 }
0757 template <class B>
0758 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
0759 operator*(number<B, et_on>&& a, number<B, et_on>&& b)
0760 {
0761    using default_ops::eval_multiply;
0762    eval_multiply(a.backend(), b.backend());
0763    return std::move(a);
0764 }
0765 
0766 template <class B, class V>
0767 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, detail::expression<detail::multiply_immediates, number<B, et_on>, V> >::type
0768 operator*(const number<B, et_on>& a, const V& b)
0769 {
0770    return detail::expression<detail::multiply_immediates, number<B, et_on>, V>(a, b);
0771 }
0772 
0773 template <class B, class V>
0774 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, number<B, et_on> >::type
0775 operator*(number<B, et_on>&& a, const V& b)
0776 {
0777    using default_ops::eval_multiply;
0778    eval_multiply(a.backend(), number<B, et_on>::canonical_value(b));
0779    return std::move(a);
0780 }
0781 
0782 template <class V, class B>
0783 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::multiply_immediates, V, number<B, et_on> > >::type
0784 operator*(const V& a, const number<B, et_on>& b)
0785 {
0786    return detail::expression<detail::multiply_immediates, V, number<B, et_on> >(a, b);
0787 }
0788 
0789 template <class V, class B>
0790 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, number<B, et_on> >::type
0791 operator*(const V& a, number<B, et_on>&& b)
0792 {
0793    using default_ops::eval_multiply;
0794    eval_multiply(b.backend(), number<B, et_on>::canonical_value(a));
0795    return std::move(b);
0796 }
0797 
0798 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0799 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
0800 operator*(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0801 {
0802    return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0803 }
0804 
0805 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0806 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0807    std::is_same<typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value,
0808    typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
0809 operator*(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0810 {
0811    a *= b;
0812    return std::move(a);
0813 }
0814 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0815 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0816    !std::is_same<typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value,
0817    typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
0818 operator*(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0819 {
0820    return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0821 }
0822 
0823 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0824 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
0825 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
0826 {
0827    return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
0828 }
0829 
0830 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0831 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0832    std::is_same<typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value,
0833    typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type
0834 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0835 {
0836    b *= a;
0837    return std::move(b);
0838 }
0839 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0840 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0841    !std::is_same<typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value,
0842    typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type
0843 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0844 {
0845    return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
0846 }
0847 
0848 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
0849 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
0850 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
0851 {
0852    return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
0853 }
0854 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
0855 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type
0856 operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
0857 {
0858    return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
0859 }
0860 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
0861 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
0862 operator*(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
0863 {
0864    return detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
0865 }
0866 //
0867 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
0868 //
0869 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0870 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >
0871 operator*(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
0872 {
0873    return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
0874        detail::expression<detail::multiplies, number<B, ET>, Arg1>(a, b.left_ref()));
0875 }
0876 
0877 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
0878 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >::result_type
0879 operator*(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
0880 {
0881    return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
0882        detail::expression<detail::multiplies, number<B, ET>, Arg1>(a, b.left_ref()));
0883 }
0884 
0885 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0886 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >
0887 operator*(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
0888 {
0889    return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
0890        detail::expression<detail::multiplies, number<B, ET>, Arg1>(b, a.left_ref()));
0891 }
0892 
0893 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
0894 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >::result_type
0895 operator*(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
0896 {
0897    return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
0898        detail::expression<detail::multiplies, number<B, ET>, Arg1>(b, a.left_ref()));
0899 }
0900 
0901 template <class B>
0902 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >
0903 operator*(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0904 {
0905    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
0906        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
0907 }
0908 
0909 template <class B>
0910 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0911    std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value,
0912    typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type
0913 operator*(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0914 {
0915    a *= b.left_ref();
0916    a.backend().negate();
0917    return std::move(a);
0918 }
0919 template <class B>
0920 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0921    !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value,
0922    typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type
0923 operator*(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0924 {
0925    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
0926          detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
0927 }
0928 
0929 template <class B>
0930 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >
0931 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
0932 {
0933    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
0934        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
0935 }
0936 
0937 template <class B>
0938 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0939    std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value,
0940    typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type
0941 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
0942 {
0943    b *= a.left_ref();
0944    b.backend().negate();
0945    return std::move(b);
0946 }
0947 template <class B>
0948 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0949    !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value,
0950    typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type
0951 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
0952 {
0953    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
0954          detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
0955 }
0956 
0957 template <class B, class V>
0958 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> > >::type
0959 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
0960 {
0961    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> >(
0962        detail::expression<detail::multiply_immediates, number<B, et_on>, V>(a.left_ref(), b));
0963 }
0964 template <class B, class B2, expression_template_option ET>
0965 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > >::type
0966 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
0967 {
0968    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
0969        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
0970 }
0971 
0972 template <class B, class B2, expression_template_option ET>
0973 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type
0974 operator*(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b)
0975 {
0976    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
0977        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
0978 }
0979 
0980 template <class V, class B>
0981 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> > >::type
0982 operator*(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0983 {
0984    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> >(
0985        detail::expression<detail::multiply_immediates, number<B, et_on>, V>(b.left_ref(), a));
0986 }
0987 template <class B2, expression_template_option ET, class B>
0988 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > >::type
0989 operator*(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0990 {
0991    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
0992        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(b.left_ref(), a));
0993 }
0994 
0995 template <class B2, expression_template_option ET, class B>
0996 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type
0997 operator*(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
0998 {
0999    return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
1000        detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(b.left_ref(), a));
1001 }
1002 
1003 //
1004 // Division:
1005 //
1006 template <class B>
1007 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >
1008 operator/(const number<B, et_on>& a, const number<B, et_on>& b)
1009 {
1010    return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1011 }
1012 template <class B>
1013 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
1014 operator/(number<B, et_on>&& a, const number<B, et_on>& b)
1015 {
1016    using default_ops::eval_divide;
1017    eval_divide(a.backend(), b.backend());
1018    return std::move(a);
1019 }
1020 template <class B>
1021 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
1022 operator/(const number<B, et_on>& a, number<B, et_on>&& b)
1023 {
1024    return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1025 }
1026 template <class B>
1027 inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on>
1028 operator/(number<B, et_on>&& a, number<B, et_on>&& b)
1029 {
1030    using default_ops::eval_divide;
1031    eval_divide(a.backend(), b.backend());
1032    return std::move(a);
1033 }
1034 template <class B, class V>
1035 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, detail::expression<detail::divide_immediates, number<B, et_on>, V> >::type
1036 operator/(const number<B, et_on>& a, const V& b)
1037 {
1038    return detail::expression<detail::divide_immediates, number<B, et_on>, V>(a, b);
1039 }
1040 template <class B, class V>
1041 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, number<B, et_on> >::type
1042 operator/(number<B, et_on>&& a, const V& b)
1043 {
1044    using default_ops::eval_divide;
1045    eval_divide(a.backend(), number<B, et_on>::canonical_value(b));
1046    return std::move(a);
1047 }
1048 template <class V, class B>
1049 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::divide_immediates, V, number<B, et_on> > >::type
1050 operator/(const V& a, const number<B, et_on>& b)
1051 {
1052    return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b);
1053 }
1054 template <class V, class B>
1055 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, number<B, et_on> >::type
1056 operator/(const V& a, number<B, et_on>&& b)
1057 {
1058    return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b);
1059 }
1060 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1061 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
1062 operator/(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1063 {
1064    return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1065 }
1066 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1067 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1068    std::is_same<typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value,
1069    typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
1070 operator/(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1071 {
1072    a /= b;
1073    return std::move(a);
1074 }
1075 template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1076 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1077    !std::is_same<typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value,
1078    typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
1079 operator/(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1080 {
1081    return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1082 }
1083 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
1084 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
1085 operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
1086 {
1087    return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
1088 }
1089 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
1090 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type
1091 operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
1092 {
1093    return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
1094 }
1095 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1096 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
1097 operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1098 {
1099    return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1100 }
1101 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1102 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type
1103 operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1104 {
1105    return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1106 }
1107 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1108 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
1109 operator/(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1110 {
1111    return detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1112 }
1113 //
1114 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
1115 //
1116 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
1117 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >
1118 operator/(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
1119 {
1120    return detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >(
1121        detail::expression<detail::divides, number<B, ET>, Arg1>(a, b.left_ref()));
1122 }
1123 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
1124 inline typename std::enable_if<
1125    std::is_same<typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type, number<B, ET>>::value,
1126    typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type>::type
1127 operator/(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
1128 {
1129    a /= b.left_ref();
1130    a.backend().negate();
1131    return std::move(a);
1132 }
1133 template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
1134 inline typename std::enable_if<
1135    !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type, number<B, ET>>::value,
1136    typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type>::type
1137 operator/(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
1138 {
1139    return detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >(
1140          detail::expression<detail::divides, number<B, ET>, Arg1>(a, b.left_ref()));
1141 }
1142 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
1143 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >
1144 operator/(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
1145 {
1146    return detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >(
1147        detail::expression<detail::divides, Arg1, number<B, ET> >(a.left_ref(), b));
1148 }
1149 template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
1150 inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >::result_type
1151 operator/(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b)
1152 {
1153    return detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >(
1154        detail::expression<detail::divides, Arg1, number<B, ET> >(a.left_ref(), b));
1155 }
1156 template <class B>
1157 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >
1158 operator/(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
1159 {
1160    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
1161        detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
1162 }
1163 template <class B>
1164 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
1165 operator/(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
1166 {
1167    a /= b.left_ref();
1168    a.backend().negate();
1169    return std::move(a);
1170 }
1171 template <class B>
1172 inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >
1173 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
1174 {
1175    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
1176        detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b));
1177 }
1178 template <class B>
1179 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
1180 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b)
1181 {
1182    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
1183        detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b));
1184 }
1185 template <class B, class V>
1186 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V> > >::type
1187 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
1188 {
1189    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V> >(
1190        detail::expression<detail::divide_immediates, number<B, et_on>, V>(a.left_ref(), b));
1191 }
1192 template <class B, class B2, expression_template_option ET>
1193 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > > >::type
1194 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
1195 {
1196    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >(
1197        detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
1198 }
1199 template <class B, class B2, expression_template_option ET>
1200 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type
1201 operator/(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b)
1202 {
1203    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >(
1204        detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
1205 }
1206 template <class V, class B>
1207 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > > >::type
1208 operator/(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
1209 {
1210    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > >(
1211        detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b.left_ref()));
1212 }
1213 template <class B2, expression_template_option ET, class B>
1214 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > > >::type
1215 operator/(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
1216 {
1217    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >(
1218        detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()));
1219 }
1220 template <class B2, expression_template_option ET, class B>
1221 inline BOOST_MP_CXX14_CONSTEXPR typename std::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>::value, number<B, et_on> >::type
1222 operator/(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b)
1223 {
1224    return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >(
1225        detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()));
1226 }
1227 //
1228 // Modulus:
1229 //
1230 template <class B>
1231 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1232                             detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> > >::type
1233 operator%(const number<B, et_on>& a, const number<B, et_on>& b)
1234 {
1235    return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1236 }
1237 template <class B>
1238 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1239    number<B, et_on> >::type
1240 operator%(number<B, et_on>&& a, const number<B, et_on>& b)
1241 {
1242    using default_ops::eval_modulus;
1243    eval_modulus(a.backend(), b.backend());
1244    return std::move(a);
1245 }
1246 template <class B>
1247 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1248    number<B, et_on> >::type
1249 operator%(const number<B, et_on>& a, number<B, et_on>&& b)
1250 {
1251    return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1252 }
1253 template <class B>
1254 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1255    number<B, et_on> >::type
1256 operator%(number<B, et_on>&& a, number<B, et_on>&& b)
1257 {
1258    using default_ops::eval_modulus;
1259    eval_modulus(a.backend(), b.backend());
1260    return std::move(a);
1261 }
1262 template <class B, class V>
1263 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, number<B, et_on> >::value,
1264                             detail::expression<detail::modulus_immediates, number<B, et_on>, V> >::type
1265 operator%(const number<B, et_on>& a, const V& b)
1266 {
1267    return detail::expression<detail::modulus_immediates, number<B, et_on>, V>(a, b);
1268 }
1269 template <class B, class V>
1270 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, number<B, et_on> >::value,
1271    number<B, et_on> >::type
1272 operator%(number<B, et_on>&& a, const V& b)
1273 {
1274    using default_ops::eval_modulus;
1275    eval_modulus(a.backend(), number<B, et_on>::canonical_value(b));
1276    return std::move(a);
1277 }
1278 template <class V, class B>
1279 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1280                             detail::expression<detail::modulus_immediates, V, number<B, et_on> > >::type
1281 operator%(const V& a, const number<B, et_on>& b)
1282 {
1283    return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b);
1284 }
1285 template <class V, class B>
1286 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1287    number<B, et_on> >::type
1288 operator%(const V& a, number<B, et_on>&& b)
1289 {
1290    return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b);
1291 }
1292 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1293 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1294                             detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
1295 operator%(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1296 {
1297    return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1298 }
1299 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1300 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1301    std::is_same<typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value 
1302    && number_category<B>::value == number_kind_integer,
1303    typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type
1304 operator%(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1305 {
1306    a %= b;
1307    return std::move(a);
1308 }
1309 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1310 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1311    !std::is_same<typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value 
1312    && number_category<B>::value == number_kind_integer,
1313    typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type
1314 operator%(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1315 {
1316    return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1317 }
1318 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1319 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1320                             detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type
1321 operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
1322 {
1323    return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1324 }
1325 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1326 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1327    typename detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type >::type
1328 operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1329 {
1330    return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1331 }
1332 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1333 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
1334                             detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type
1335 operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1336 {
1337    return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1338 }
1339 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1340 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<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),
1341                             detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type
1342 operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1343 {
1344    return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1345 }
1346 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1347 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<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),
1348                             detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
1349 operator%(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1350 {
1351    return detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1352 }
1353 //
1354 // Left shift:
1355 //
1356 template <class B, class I>
1357 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), detail::expression<detail::shift_left, number<B, et_on>, I> >::type
1358 operator<<(const number<B, et_on>& a, const I& b)
1359 {
1360    return detail::expression<detail::shift_left, number<B, et_on>, I>(a, b);
1361 }
1362 template <class B, class I>
1363 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_on> >::type
1364 operator<<(number<B, et_on>&& a, const I& b)
1365 {
1366    using default_ops::eval_left_shift;
1367    eval_left_shift(a.backend(), b);
1368    return std::move(a);
1369 }
1370 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
1371 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1372                             detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type
1373 operator<<(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
1374 {
1375    return detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
1376 }
1377 //
1378 // Right shift:
1379 //
1380 template <class B, class I>
1381 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer),
1382                             detail::expression<detail::shift_right, number<B, et_on>, I> >::type
1383 operator>>(const number<B, et_on>& a, const I& b)
1384 {
1385    return detail::expression<detail::shift_right, number<B, et_on>, I>(a, b);
1386 }
1387 template <class B, class I>
1388 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer),
1389    number<B, et_on> >::type
1390 operator>>(number<B, et_on>&& a, const I& b)
1391 {
1392    using default_ops::eval_right_shift;
1393    eval_right_shift(a.backend(), b);
1394    return std::move(a);
1395 }
1396 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
1397 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
1398                             detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type
1399 operator>>(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
1400 {
1401    return detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
1402 }
1403 //
1404 // Bitwise AND:
1405 //
1406 template <class B>
1407 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1408                             detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> > >::type
1409 operator&(const number<B, et_on>& a, const number<B, et_on>& b)
1410 {
1411    return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1412 }
1413 template <class B>
1414 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1415    number<B, et_on> >::type
1416 operator&(number<B, et_on>&& a, const number<B, et_on>& b)
1417 {
1418    using default_ops::eval_bitwise_and;
1419    eval_bitwise_and(a.backend(), b.backend());
1420    return std::move(a);
1421 }
1422 template <class B>
1423 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1424    number<B, et_on> >::type
1425 operator&(const number<B, et_on>& a, number<B, et_on>&& b)
1426 {
1427    using default_ops::eval_bitwise_and;
1428    eval_bitwise_and(b.backend(), a.backend());
1429    return std::move(b);
1430 }
1431 template <class B>
1432 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1433    number<B, et_on> >::type
1434 operator&(number<B, et_on>&& a, number<B, et_on>&& b)
1435 {
1436    using default_ops::eval_bitwise_and;
1437    eval_bitwise_and(a.backend(), b.backend());
1438    return std::move(a);
1439 }
1440 template <class B, class V>
1441 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1442                             detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V> >::type
1443 operator&(const number<B, et_on>& a, const V& b)
1444 {
1445    return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V>(a, b);
1446 }
1447 template <class B, class V>
1448 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1449    number<B, et_on> >::type
1450 operator&(number<B, et_on>&& a, const V& b)
1451 {
1452    using default_ops::eval_bitwise_and;
1453    eval_bitwise_and(a.backend(), number<B, et_on>::canonical_value(b));
1454    return std::move(a);
1455 }
1456 template <class V, class B>
1457 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1458                             detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> > >::type
1459 operator&(const V& a, const number<B, et_on>& b)
1460 {
1461    return detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> >(a, b);
1462 }
1463 template <class V, class B>
1464 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1465    number<B, et_on> >::type
1466 operator&(const V& a, number<B, et_on>&& b)
1467 {
1468    using default_ops::eval_bitwise_and;
1469    eval_bitwise_and(b.backend(), number<B, et_on>::canonical_value(a));
1470    return std::move(b);
1471 }
1472 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1473 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1474                             detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
1475 operator&(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1476 {
1477    return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1478 }
1479 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1480 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1481    std::is_same<typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value
1482    && number_category<B>::value == number_kind_integer,
1483    typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type
1484 operator&(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1485 {
1486    a &= b;
1487    return std::move(a);
1488 }
1489 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1490 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1491    !std::is_same<typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value
1492    && number_category<B>::value == number_kind_integer,
1493    typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type
1494 operator&(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1495 {
1496    return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1497 }
1498 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1499 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1500                             detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type
1501 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
1502 {
1503    return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1504 }
1505 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1506 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1507    std::is_same<typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value
1508    && number_category<B>::value == number_kind_integer,
1509    typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type >::type
1510 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1511 {
1512    b &= a;
1513    return std::move(b);
1514 }
1515 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1516 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1517    !std::is_same<typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value
1518    && number_category<B>::value == number_kind_integer,
1519    typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type >::type
1520 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1521 {
1522    return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1523 }
1524 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1525 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
1526                             detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type
1527 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1528 {
1529    return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1530 }
1531 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1532 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<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),
1533                             detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type
1534 operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1535 {
1536    return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1537 }
1538 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1539 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<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),
1540                             detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
1541 operator&(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1542 {
1543    return detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1544 }
1545 //
1546 // Bitwise OR:
1547 //
1548 template <class B>
1549 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1550                             detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> > >::type
1551 operator|(const number<B, et_on>& a, const number<B, et_on>& b)
1552 {
1553    return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1554 }
1555 template <class B>
1556 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1557    number<B, et_on> >::type
1558 operator|(number<B, et_on>&& a, const number<B, et_on>& b)
1559 {
1560    using default_ops::eval_bitwise_or;
1561    eval_bitwise_or(a.backend(), b.backend());
1562    return std::move(a);
1563 }
1564 template <class B>
1565 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1566    number<B, et_on> >::type
1567 operator|(const number<B, et_on>& a, number<B, et_on>&& b)
1568 {
1569    using default_ops::eval_bitwise_or;
1570    eval_bitwise_or(b.backend(), a.backend());
1571    return std::move(b);
1572 }
1573 template <class B>
1574 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1575    number<B, et_on> >::type
1576 operator|(number<B, et_on>&& a, number<B, et_on>&& b)
1577 {
1578    using default_ops::eval_bitwise_or;
1579    eval_bitwise_or(a.backend(), b.backend());
1580    return std::move(a);
1581 }
1582 template <class B, class V>
1583 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1584                             detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V> >::type
1585 operator|(const number<B, et_on>& a, const V& b)
1586 {
1587    return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V>(a, b);
1588 }
1589 template <class B, class V>
1590 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1591    number<B, et_on> >::type
1592 operator|(number<B, et_on>&& a, const V& b)
1593 {
1594    using default_ops::eval_bitwise_or;
1595    eval_bitwise_or(a.backend(), number<B, et_on>::canonical_value(b));
1596    return std::move(a);
1597 }
1598 template <class V, class B>
1599 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1600                             detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> > >::type
1601 operator|(const V& a, const number<B, et_on>& b)
1602 {
1603    return detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> >(a, b);
1604 }
1605 template <class V, class B>
1606 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1607    number<B, et_on> >::type
1608 operator|(const V& a, number<B, et_on>&& b)
1609 {
1610    using default_ops::eval_bitwise_or;
1611    eval_bitwise_or(b.backend(), number<B, et_on>::canonical_value(a));
1612    return std::move(b);
1613 }
1614 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1615 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1616                             detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
1617 operator|(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1618 {
1619    return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1620 }
1621 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1622 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1623    std::is_same<typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value
1624    && number_category<B>::value == number_kind_integer,
1625    typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
1626 operator|(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1627 {
1628    a |= b;
1629    return std::move(a);
1630 }
1631 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1632 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1633    !std::is_same<typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value
1634    && number_category<B>::value == number_kind_integer,
1635    typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
1636 operator|(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1637 {
1638    return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1639 }
1640 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1641 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1642                             detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type
1643 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
1644 {
1645    return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1646 }
1647 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1648 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1649    std::is_same<typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value
1650    && number_category<B>::value == number_kind_integer,
1651    typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type
1652 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1653 {
1654    b |= a;
1655    return std::move(b);
1656 }
1657 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1658 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1659    !std::is_same<typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value
1660    && number_category<B>::value == number_kind_integer,
1661    typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type
1662 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1663 {
1664    return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1665 }
1666 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1667 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
1668                             detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type
1669 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1670 {
1671    return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1672 }
1673 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1674 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<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),
1675                             detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type
1676 operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1677 {
1678    return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1679 }
1680 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1681 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<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),
1682                             detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
1683 operator|(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1684 {
1685    return detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1686 }
1687 //
1688 // Bitwise XOR:
1689 //
1690 template <class B>
1691 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1692                             detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> > >::type
1693 operator^(const number<B, et_on>& a, const number<B, et_on>& b)
1694 {
1695    return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b);
1696 }
1697 template <class B>
1698 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1699    number<B, et_on> >::type
1700 operator^(number<B, et_on>&& a, const number<B, et_on>& b)
1701 {
1702    using default_ops::eval_bitwise_xor;
1703    eval_bitwise_xor(a.backend(), b.backend());
1704    return std::move(a);
1705 }
1706 template <class B>
1707 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1708    number<B, et_on> >::type
1709 operator^(const number<B, et_on>& a, number<B, et_on>&& b)
1710 {
1711    using default_ops::eval_bitwise_xor;
1712    eval_bitwise_xor(b.backend(), a.backend());
1713    return std::move(b);
1714 }
1715 template <class B>
1716 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1717    number<B, et_on> >::type
1718 operator^(number<B, et_on>&& a, number<B, et_on>&& b)
1719 {
1720    using default_ops::eval_bitwise_xor;
1721    eval_bitwise_xor(a.backend(), b.backend());
1722    return std::move(a);
1723 }
1724 template <class B, class V>
1725 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1726                             detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V> >::type
1727 operator^(const number<B, et_on>& a, const V& b)
1728 {
1729    return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V>(a, b);
1730 }
1731 template <class B, class V>
1732 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1733    number<B, et_on> >::type
1734 operator^(number<B, et_on>&& a, const V& b)
1735 {
1736    using default_ops::eval_bitwise_xor;
1737    eval_bitwise_xor(a.backend(), number<B, et_on>::canonical_value(b));
1738    return std::move(a);
1739 }
1740 template <class V, class B>
1741 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1742                             detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> > >::type
1743 operator^(const V& a, const number<B, et_on>& b)
1744 {
1745    return detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> >(a, b);
1746 }
1747 template <class V, class B>
1748 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
1749    number<B, et_on> >::type
1750 operator^(const V& a, number<B, et_on>&& b)
1751 {
1752    using default_ops::eval_bitwise_xor;
1753    eval_bitwise_xor(b.backend(), number<B, et_on>::canonical_value(a));
1754    return std::move(b);
1755 }
1756 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1757 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1758                             detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
1759 operator^(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1760 {
1761    return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1762 }
1763 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1764 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1765    std::is_same<typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value
1766    && number_category<B>::value == number_kind_integer,
1767    typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
1768 operator^(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1769 {
1770    a ^= b;
1771    return std::move(a);
1772 }
1773 template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1774 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1775    !std::is_same<typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value
1776    && number_category<B>::value == number_kind_integer,
1777    typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type
1778 operator^(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1779 {
1780    return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1781 }
1782 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1783 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer,
1784                             detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type
1785 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
1786 {
1787    return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1788 }
1789 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1790 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1791    std::is_same<typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value
1792    && number_category<B>::value == number_kind_integer,
1793    typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type
1794 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1795 {
1796    b ^= a;
1797    return std::move(b);
1798 }
1799 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
1800 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
1801    !std::is_same<typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value
1802    && number_category<B>::value == number_kind_integer,
1803    typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type
1804 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b)
1805 {
1806    return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
1807 }
1808 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
1809 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
1810                             detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type
1811 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
1812 {
1813    return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
1814 }
1815 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
1816 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<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),
1817                             detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type
1818 operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
1819 {
1820    return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b);
1821 }
1822 template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
1823 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<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
1824 operator^(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
1825 {
1826    return detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
1827 }
1828 
1829 }} // namespace boost::multiprecision
1830 
1831 #endif