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