/////////////////////////////////////////////////////////////////////////////// // Copyright 2011 John Maddock. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_MP_ET_OPS_HPP #define BOOST_MP_ET_OPS_HPP namespace boost { namespace multiprecision { // // Non-member operators for number: // // Unary operators first. // Note that these *must* return by value, even though that's somewhat against // existing practice. The issue is that in C++11 land one could easily and legitimately // write: // auto x = +1234_my_user_defined_suffix; // which would result in a dangling-reference-to-temporary if unary + returned a reference // to it's argument. While return-by-value is obviously inefficient in other situations // the reality is that no one ever uses unary operator+ anyway...! // template inline constexpr const number operator+(const number& v) { return v; } template inline constexpr const detail::expression operator+(const detail::expression& v) { return v; } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression > operator-(const number& v) { static_assert(is_signed_number::value, "Negating an unsigned type results in ill-defined behavior."); return detail::expression >(v); } // rvalue ops: template inline BOOST_MP_CXX14_CONSTEXPR number operator-(number&& v) { static_assert(is_signed_number::value, "Negating an unsigned type results in ill-defined behavior."); return detail::expression >(v); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression > operator-(const detail::expression& v) { static_assert((is_signed_number::result_type>::value), "Negating an unsigned type results in ill-defined behavior."); return detail::expression >(v); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression > >::type operator~(const number& v) { return detail::expression >(v); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator~(number&& v) { return detail::expression >(v); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value == number_kind_integer, detail::expression > >::type operator~(const detail::expression& v) { return detail::expression >(v); } // // Then addition: // template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator+(const number& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator+(number&& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator+(const number& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator+(number&& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && !is_equivalent_number_type >::value, detail::expression, V> >::type operator+(const number& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && !is_equivalent_number_type >::value, number >::type operator+(number&& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression > >::type operator+(const V& a, const number& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, number >::type operator+(const V& a, number&& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, detail::expression > operator+(const number& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, detail::expression >::result_type operator+(number&& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator+(const detail::expression& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number >::result_type operator+(const detail::expression& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, detail::expression > operator+(const detail::expression& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression, V> >::type operator+(const detail::expression& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression > >::type operator+(const V& a, const detail::expression& b) { return detail::expression >(a, b); } // // Fused multiply add: // template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression::left_type, typename detail::expression::right_type, V> >::type operator+(const V& a, const detail::expression& b) { return detail::expression::left_type, typename detail::expression::right_type, V>(b.left(), b.right(), a); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression::left_type, typename detail::expression::right_type, V> >::type operator+(const detail::expression& a, const V& b) { return detail::expression::left_type, typename detail::expression::right_type, V>(a.left(), a.right(), b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression::left_type, typename detail::expression::right_type, number > operator+(const number& a, const detail::expression& b) { return detail::expression::left_type, typename detail::expression::right_type, number >(b.left(), b.right(), a); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression::left_type, typename detail::expression::right_type, number >::result_type operator+(number&& a, const detail::expression& b) { return detail::expression::left_type, typename detail::expression::right_type, number >(b.left(), b.right(), a); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression::left_type, typename detail::expression::right_type, number > operator+(const detail::expression& a, const number& b) { return detail::expression::left_type, typename detail::expression::right_type, number >(a.left(), a.right(), b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression::left_type, typename detail::expression::right_type, number >::result_type operator+(const detail::expression& a, number&& b) { return detail::expression::left_type, typename detail::expression::right_type, number >(a.left(), a.right(), b); } // // Fused multiply subtract: // template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression::left_type, typename detail::expression::right_type, V> > >::type operator-(const V& a, const detail::expression& b) { return detail::expression::left_type, typename detail::expression::right_type, V> >(detail::expression::left_type, typename detail::expression::right_type, V>(b.left(), b.right(), a)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression::left_type, typename detail::expression::right_type, V> >::type operator-(const detail::expression& a, const V& b) { return detail::expression::left_type, typename detail::expression::right_type, V>(a.left(), a.right(), b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression::left_type, typename detail::expression::right_type, number > > operator-(const number& a, const detail::expression& b) { return detail::expression::left_type, typename detail::expression::right_type, number > >(detail::expression::left_type, typename detail::expression::right_type, number >(b.left(), b.right(), a)); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression::left_type, typename detail::expression::right_type, number > >::result_type operator-(number&& a, const detail::expression& b) { return detail::expression::left_type, typename detail::expression::right_type, number > >(detail::expression::left_type, typename detail::expression::right_type, number >(b.left(), b.right(), a)); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression::left_type, typename detail::expression::right_type, number > operator-(const detail::expression& a, const number& b) { return detail::expression::left_type, typename detail::expression::right_type, number >(a.left(), a.right(), b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression::left_type, typename detail::expression::right_type, number >::result_type operator-(const detail::expression& a, number&& b) { return detail::expression::left_type, typename detail::expression::right_type, number >(a.left(), a.right(), b); } // // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: // template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, Arg1> operator+(const number& a, const detail::expression& b) { return detail::expression, Arg1>(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, Arg1>::result_type operator+(number&& a, const detail::expression& b) { return detail::expression, Arg1>(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, Arg1> operator+(const detail::expression& a, const number& b) { return detail::expression, Arg1>(b, a.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, Arg1>::result_type operator+(const detail::expression& a, number&& b) { return detail::expression, Arg1>(b, a.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator+(const number& a, const detail::expression >& b) { return detail::expression, number >(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number >::result_type operator+(number&& a, const detail::expression >& b) { return detail::expression, number >(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator+(const detail::expression >& a, const number& b) { return detail::expression, number >(b, a.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number >::result_type operator+(const detail::expression >& a, number&& b) { return detail::expression, number >(b, a.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression > >::type operator+(const detail::expression >& a, const V& b) { return detail::expression >(b, a.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, detail::expression, number > >::type operator+(const detail::expression >& a, const number& b) { return detail::expression, number >(b, a.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, typename detail::expression, number >::result_type>::type operator+(const detail::expression >& a, number&& b) { return detail::expression, number >(b, a.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, detail::expression, number > >::type operator+(const number& a, const detail::expression >& b) { return detail::expression, number >(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, typename detail::expression, number >::result_type>::type operator+(number&& a, const detail::expression >& b) { return detail::expression, number >(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > > operator+(const detail::expression >& a, const detail::expression >& b) { return detail::expression, number > >(detail::expression, number >(a.left_ref(), b.left_ref())); } // // Subtraction: // template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator-(const number& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator-(number&& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator-(const number& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator-(number&& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && !is_equivalent_number_type >::value, detail::expression, V> >::type operator-(const number& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && !is_equivalent_number_type >::value, number >::type operator-(number&& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression > >::type operator-(const V& a, const number& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, number >::type operator-(const V& a, number&& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, detail::expression > operator-(const number& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, detail::expression >::result_type operator-(number&& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator-(const detail::expression& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number >::result_type operator-(const detail::expression& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, detail::expression > operator-(const detail::expression& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression, V> >::type operator-(const detail::expression& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression > >::type operator-(const V& a, const detail::expression& b) { return detail::expression >(a, b); } // // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: // template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, Arg1> operator-(const number& a, const detail::expression& b) { return detail::expression, Arg1>(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, Arg1>::result_type operator-(number&& a, const detail::expression& b) { return detail::expression, Arg1>(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, Arg1> > operator-(const detail::expression& a, const number& b) { return detail::expression, Arg1> >( detail::expression, Arg1>(b, a.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, Arg1> >::result_type operator-(const detail::expression& a, number&& b) { return detail::expression, Arg1> >( detail::expression, Arg1>(b, a.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator-(const number& a, const detail::expression >& b) { return detail::expression, number >(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number >::result_type operator-(number&& a, const detail::expression >& b) { return detail::expression, number >(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > > operator-(const detail::expression >& a, const number& b) { return detail::expression, number > >( detail::expression, number >(b, a.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number > >::result_type operator-(const detail::expression >& a, number&& b) { return detail::expression, number > >( detail::expression, number >(b, a.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression, V> > >::type operator-(const detail::expression >& a, const V& b) { return detail::expression, V> >(detail::expression, V>(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, detail::expression, number > > >::type operator-(const detail::expression >& a, const number& b) { return detail::expression, number > >(detail::expression, number >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, typename detail::expression, number > >::result_type>::type operator-(const detail::expression >& a, number&& b) { return detail::expression, number > >(detail::expression, number >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression > >::type operator-(const V& a, const detail::expression >& b) { return detail::expression >(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, detail::expression, number > >::type operator-(const number& a, const detail::expression >& b) { return detail::expression, number >(a, b.left_ref()); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, typename detail::expression, number >::result_type>::type operator-(number&& a, const detail::expression >& b) { return detail::expression, number >(a, b.left_ref()); } // // Multiplication: // template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator*(const number& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator*(number&& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator*(const number& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator*(number&& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && !is_equivalent_number_type >::value, detail::expression, V> >::type operator*(const number& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && !is_equivalent_number_type >::value, number >::type operator*(number&& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression > >::type operator*(const V& a, const number& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, number >::type operator*(const V& a, number&& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, detail::expression > operator*(const number& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, detail::expression >::result_type operator*(number&& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator*(const detail::expression& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number >::result_type operator*(const detail::expression& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, detail::expression > operator*(const detail::expression& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression, V> >::type operator*(const detail::expression& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression > >::type operator*(const V& a, const detail::expression& b) { return detail::expression >(a, b); } // // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: // template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, Arg1> > operator*(const number& a, const detail::expression& b) { return detail::expression, Arg1> >( detail::expression, Arg1>(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, Arg1> >::result_type operator*(number&& a, const detail::expression& b) { return detail::expression, Arg1> >( detail::expression, Arg1>(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, Arg1> > operator*(const detail::expression& a, const number& b) { return detail::expression, Arg1> >( detail::expression, Arg1>(b, a.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, Arg1> >::result_type operator*(const detail::expression& a, number&& b) { return detail::expression, Arg1> >( detail::expression, Arg1>(b, a.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > > operator*(const number& a, const detail::expression >& b) { return detail::expression, number > >( detail::expression, number >(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number > >::result_type operator*(number&& a, const detail::expression >& b) { return detail::expression, number > >( detail::expression, number >(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > > operator*(const detail::expression >& a, const number& b) { return detail::expression, number > >( detail::expression, number >(b, a.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number > >::result_type operator*(const detail::expression >& a, number&& b) { return detail::expression, number > >( detail::expression, number >(b, a.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression, V> > >::type operator*(const detail::expression >& a, const V& b) { return detail::expression, V> >( detail::expression, V>(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, detail::expression, number > > >::type operator*(const detail::expression >& a, const number& b) { return detail::expression, number > >( detail::expression, number >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, typename detail::expression, number > >::result_type>::type operator*(const detail::expression >& a, number&& b) { return detail::expression, number > >( detail::expression, number >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression, V> > >::type operator*(const V& a, const detail::expression >& b) { return detail::expression, V> >( detail::expression, V>(b.left_ref(), a)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, detail::expression, number > > >::type operator*(const number& a, const detail::expression >& b) { return detail::expression, number > >( detail::expression, number >(b.left_ref(), a)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, typename detail::expression, number > >::result_type>::type operator*(number&& a, const detail::expression >& b) { return detail::expression, number > >( detail::expression, number >(b.left_ref(), a)); } // // Division: // template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator/(const number& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator/(number&& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator/(const number& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR number operator/(number&& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && !is_equivalent_number_type >::value, detail::expression, V> >::type operator/(const number& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && !is_equivalent_number_type >::value, number >::type operator/(number&& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression > >::type operator/(const V& a, const number& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, number >::type operator/(const V& a, number&& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, detail::expression > operator/(const number& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, detail::expression >::result_type operator/(number&& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > operator/(const detail::expression& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number >::result_type operator/(const detail::expression& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, detail::expression > operator/(const detail::expression& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression, V> >::type operator/(const detail::expression& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value, detail::expression > >::type operator/(const V& a, const detail::expression& b) { return detail::expression >(a, b); } // // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: // template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, Arg1> > operator/(const number& a, const detail::expression& b) { return detail::expression, Arg1> >( detail::expression, Arg1>(a, b.left_ref())); } template inline typename detail::expression, Arg1> >::result_type operator/(number&& a, const detail::expression& b) { return detail::expression, Arg1> >( detail::expression, Arg1>(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression > > operator/(const detail::expression& a, const number& b) { return detail::expression > >( detail::expression >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression > >::result_type operator/(const detail::expression& a, number&& b) { return detail::expression > >( detail::expression >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > > operator/(const number& a, const detail::expression >& b) { return detail::expression, number > >( detail::expression, number >(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number > >::result_type operator/(number&& a, const detail::expression >& b) { return detail::expression, number > >( detail::expression, number >(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number > > operator/(const detail::expression >& a, const number& b) { return detail::expression, number > >( detail::expression, number >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, number > >::result_type operator/(const detail::expression >& a, number&& b) { return detail::expression, number > >( detail::expression, number >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression, V> > >::type operator/(const detail::expression >& a, const V& b) { return detail::expression, V> >( detail::expression, V>(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, detail::expression, number > > >::type operator/(const detail::expression >& a, const number& b) { return detail::expression, number > >( detail::expression, number >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, typename detail::expression, number > >::result_type>::type operator/(const detail::expression >& a, number&& b) { return detail::expression, number > >( detail::expression, number >(a.left_ref(), b)); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value, detail::expression > > >::type operator/(const V& a, const detail::expression >& b) { return detail::expression > >( detail::expression >(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, number >::value, detail::expression, number > > >::type operator/(const number& a, const detail::expression >& b) { return detail::expression, number > >( detail::expression, number >(a, b.left_ref())); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if, typename detail::expression, number > >::result_type>::value, number >::type operator/(number&& a, const detail::expression >& b) { return detail::expression, number > >( detail::expression, number >(a, b.left_ref())); } // // Modulus: // template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, number > >::type operator%(const number& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator%(number&& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator%(const number& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator%(number&& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer) && !is_equivalent_number_type >::value, detail::expression, V> >::type operator%(const number& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer) && !is_equivalent_number_type >::value, number >::type operator%(number&& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), detail::expression > >::type operator%(const V& a, const number& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), number >::type operator%(const V& a, number&& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, detail::expression > >::type operator%(const number& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, typename detail::expression, detail::expression >::result_type >::type operator%(number&& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, number > >::type operator%(const detail::expression& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, typename detail::expression, number >::result_type >::type operator%(const detail::expression& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value == number_kind_integer, detail::expression, detail::expression > >::type operator%(const detail::expression& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value && (number_category::result_type>::value == number_kind_integer), detail::expression, V> >::type operator%(const detail::expression& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value && (number_category::result_type>::value == number_kind_integer), detail::expression > >::type operator%(const V& a, const detail::expression& b) { return detail::expression >(a, b); } // // Left shift: // template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value && (number_category::value == number_kind_integer), detail::expression, I> >::type operator<<(const number& a, const I& b) { return detail::expression, I>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value && (number_category::value == number_kind_integer), number >::type operator<<(number&& a, const I& b) { return detail::expression, I>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value && (number_category::result_type>::value == number_kind_integer), detail::expression, I> >::type operator<<(const detail::expression& a, const I& b) { return detail::expression, I>(a, b); } // // Right shift: // template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value && (number_category::value == number_kind_integer), detail::expression, I> >::type operator>>(const number& a, const I& b) { return detail::expression, I>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value && (number_category::value == number_kind_integer), number >::type operator>>(number&& a, const I& b) { return detail::expression, I>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value && (number_category::result_type>::value == number_kind_integer), detail::expression, I> >::type operator>>(const detail::expression& a, const I& b) { return detail::expression, I>(a, b); } // // Bitwise AND: // template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, number > >::type operator&(const number& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator&(number&& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator&(const number& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator&(number&& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), detail::expression, V> >::type operator&(const number& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), number >::type operator&(number&& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), detail::expression > >::type operator&(const V& a, const number& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), number >::type operator&(const V& a, number&& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, detail::expression > >::type operator&(const number& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, typename detail::expression, detail::expression >::result_type >::type operator&(number&& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, number > >::type operator&(const detail::expression& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, typename detail::expression, number >::result_type >::type operator&(const detail::expression& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value == number_kind_integer, detail::expression, detail::expression > >::type operator&(const detail::expression& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value && (number_category::result_type>::value == number_kind_integer), detail::expression, V> >::type operator&(const detail::expression& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value && (number_category::result_type>::value == number_kind_integer), detail::expression > >::type operator&(const V& a, const detail::expression& b) { return detail::expression >(a, b); } // // Bitwise OR: // template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, number > >::type operator|(const number& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator|(number&& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator|(const number& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator|(number&& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), detail::expression, V> >::type operator|(const number& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), number >::type operator|(number&& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), detail::expression > >::type operator|(const V& a, const number& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), number >::type operator|(const V& a, number&& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, detail::expression > >::type operator|(const number& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, typename detail::expression, detail::expression >::result_type>::type operator|(number&& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, number > >::type operator|(const detail::expression& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, typename detail::expression, number >::result_type>::type operator|(const detail::expression& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value == number_kind_integer, detail::expression, detail::expression > >::type operator|(const detail::expression& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value && (number_category::result_type>::value == number_kind_integer), detail::expression, V> >::type operator|(const detail::expression& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value && (number_category::result_type>::value == number_kind_integer), detail::expression > >::type operator|(const V& a, const detail::expression& b) { return detail::expression >(a, b); } // // Bitwise XOR: // template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, number > >::type operator^(const number& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator^(number&& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator^(const number& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, number >::type operator^(number&& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), detail::expression, V> >::type operator^(const number& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), number >::type operator^(number&& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), detail::expression > >::type operator^(const V& a, const number& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if >::value && (number_category::value == number_kind_integer), number >::type operator^(const V& a, number&& b) { return detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, detail::expression > >::type operator^(const number& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, typename detail::expression, detail::expression >::result_type>::type operator^(number&& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, detail::expression, number > >::type operator^(const detail::expression& a, const number& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::value == number_kind_integer, typename detail::expression, number >::result_type>::type operator^(const detail::expression& a, number&& b) { return detail::expression, number >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value == number_kind_integer, detail::expression, detail::expression > >::type operator^(const detail::expression& a, const detail::expression& b) { return detail::expression, detail::expression >(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value && (number_category::result_type>::value == number_kind_integer), detail::expression, V> >::type operator^(const detail::expression& a, const V& b) { return detail::expression, V>(a, b); } template inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if::result_type>::value && (number_category::result_type>::value == number_kind_integer), detail::expression > >::type operator^(const V& a, const detail::expression& b) { return detail::expression >(a, b); } }} // namespace boost::multiprecision #endif