/usr/include/boost/multiprecision/detail
Edit: /usr/include/boost/multiprecision/detail/et_ops.hpp (101821B)
///////////////////////////////////////////////////////////////////////////////
// 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 BOOST_CONSTEXPR const number operator+(const number& v) { return v; }
template
inline BOOST_CONSTEXPR const detail::expression operator+(const detail::expression& v) { return v; }
template
inline BOOST_MP_CXX14_CONSTEXPR detail::expression > operator-(const number& v)
{
BOOST_STATIC_ASSERT_MSG(is_signed_number::value, "Negating an unsigned type results in ill-defined behavior.");
return detail::expression >(v);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template
inline BOOST_MP_CXX14_CONSTEXPR number operator-(number&& v)
{
BOOST_STATIC_ASSERT_MSG(is_signed_number::value, "Negating an unsigned type results in ill-defined behavior.");
return detail::expression >(v);
}
#endif
template
inline BOOST_MP_CXX14_CONSTEXPR detail::expression > operator-(const detail::expression& v)
{
BOOST_STATIC_ASSERT_MSG((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 enable_if_c::value == number_kind_integer,
detail::expression > >::type
operator~(const number& v) { return detail::expression >(v); }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template
inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c::value == number_kind_integer,
number >::type
operator~(number&& v) { return detail::expression >(v); }
#endif
template
inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c::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);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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);
}
#endif
template
inline BOOST_MP_CXX14_CONSTEXPR typename enable_if >, detail::expression, V> >::type
operator+(const number& a, const V& b)
{
return detail::expression, V>(a, b);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template
inline BOOST_MP_CXX14_CONSTEXPR typename enable_if >, number >::type
operator+(number&& a, const V& b)
{
return detail::expression, V>(a, b);
}
#endif
template
inline BOOST_MP_CXX14_CONSTEXPR typename enable_if >, detail::expression > >::type
operator+(const V& a, const number& b)
{
return detail::expression >(a, b);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template
inline BOOST_MP_CXX14_CONSTEXPR typename enable_if >, number >::type
operator+(const V& a, number&& b)
{
return detail::expression >(a, b);
}
#endif
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);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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);
}
#endif
template
inline BOOST_MP_CXX14_CONSTEXPR detail::expression, number >
operator+(const detail::expression& a, const number& b)
{
return detail::expression, number >(a, b);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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);
}
#endif
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 enable_if::result_type>, 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 enable_if::result_type>, 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 enable_if::result_type>,
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 enable_if::result_type>,
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);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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);
}
#endif
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);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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);
}
#endif
//
// Fused multiply subtract:
//
template
inline BOOST_MP_CXX14_CONSTEXPR typename enable_if::result_type>,
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 enable_if::result_type>,
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));
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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));
}
#endif
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);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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);
}
#endif
//
// 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());
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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());
}
#endif
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());
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template
inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression, Arg1>::result_type
operator+(const detail::expression& a, number&& b)
{
return detail::expression