/usr/include/boost/multiprecision/detail
Edit: /usr/include/boost/multiprecision/detail/precision.hpp (6886B)
///////////////////////////////////////////////////////////////////////////////
// Copyright 2018 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_PRECISION_HPP
#define BOOST_MP_PRECISION_HPP
#include
#include
#include
namespace boost { namespace multiprecision { namespace detail {
template
inline BOOST_CONSTEXPR unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number&, const mpl::false_&)
{
return std::numeric_limits >::digits10;
}
template
inline BOOST_MP_CXX14_CONSTEXPR unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number& val, const mpl::true_&)
{
//
// We have an arbitrary precision integer, take it's "precision" as the
// location of the most-significant-bit less the location of the
// least-significant-bit, ie the number of bits required to represent the
// the value assuming we will have an exponent to shift things by:
//
return val.is_zero() ? 1 : digits2_2_10(msb(abs(val)) - lsb(abs(val)) + 1);
}
template
inline BOOST_MP_CXX14_CONSTEXPR unsigned current_precision_of_imp(const boost::multiprecision::number& n, const mpl::true_&)
{
return n.precision();
}
template
inline BOOST_CONSTEXPR unsigned current_precision_of_imp(const boost::multiprecision::number& val, const mpl::false_&)
{
return current_precision_of_last_chance_imp(val,
mpl::bool_ <
std::numeric_limits >::is_specialized &&
std::numeric_limits >::is_integer && std::numeric_limits >::is_exact && !std::numeric_limits >::is_modulo > ());
}
template
inline BOOST_CONSTEXPR unsigned current_precision_of(const Terminal&)
{
return std::numeric_limits::digits10;
}
template
inline BOOST_CONSTEXPR unsigned current_precision_of(const Terminal (&)[N])
{ // For string literals:
return 0;
}
template
inline BOOST_CONSTEXPR unsigned current_precision_of(const boost::multiprecision::number& n)
{
return current_precision_of_imp(n, boost::multiprecision::detail::is_variable_precision >());
}
template
inline BOOST_CONSTEXPR unsigned current_precision_of(const expression& expr)
{
return current_precision_of(expr.left_ref());
}
template
inline BOOST_CONSTEXPR unsigned current_precision_of(const expression& expr)
{
return current_precision_of(expr.value());
}
template
inline BOOST_CONSTEXPR unsigned current_precision_of(const expression& expr)
{
return (std::max)(current_precision_of(expr.left_ref()), current_precision_of(expr.right_ref()));
}
template
inline BOOST_CONSTEXPR unsigned current_precision_of(const expression& expr)
{
return (std::max)((std::max)(current_precision_of(expr.left_ref()), current_precision_of(expr.right_ref())), current_precision_of(expr.middle_ref()));
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4130)
#endif
template ::value>
struct scoped_default_precision
{
template
BOOST_CONSTEXPR scoped_default_precision(const T&) {}
template
BOOST_CONSTEXPR scoped_default_precision(const T&, const U&) {}
template
BOOST_CONSTEXPR scoped_default_precision(const T&, const U&, const V&) {}
//
// This function is never called: in C++17 it won't be compiled either:
//
unsigned precision() const
{
BOOST_ASSERT("This function should never be called!!" == 0);
return 0;
}
};
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
template
struct scoped_default_precision
{
template
BOOST_MP_CXX14_CONSTEXPR scoped_default_precision(const T& a)
{
init(current_precision_of(a));
}
template
BOOST_MP_CXX14_CONSTEXPR scoped_default_precision(const T& a, const U& b)
{
init((std::max)(current_precision_of(a), current_precision_of(b)));
}
template
BOOST_MP_CXX14_CONSTEXPR scoped_default_precision(const T& a, const U& b, const V& c)
{
init((std::max)((std::max)(current_precision_of(a), current_precision_of(b)), current_precision_of(c)));
}
~scoped_default_precision()
{
if(m_new_prec != m_old_prec)
R::default_precision(m_old_prec);
}
BOOST_MP_CXX14_CONSTEXPR unsigned precision() const
{
return m_new_prec;
}
private:
BOOST_MP_CXX14_CONSTEXPR void init(unsigned p)
{
m_old_prec = R::default_precision();
if (p && (p != m_old_prec))
{
R::default_precision(p);
m_new_prec = p;
}
else
m_new_prec = m_old_prec;
}
unsigned m_old_prec, m_new_prec;
};
template
inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T*, const mpl::false_&) {}
template
inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T* obj, const mpl::true_&)
{
if (obj->precision() != T::default_precision())
{
obj->precision(T::default_precision());
}
}
template
inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T* obj)
{
maybe_promote_precision(obj, mpl::bool_::value>());
}
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
#define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) \
if \
constexpr(boost::multiprecision::detail::is_variable_precision::value)
#else
#define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) if (boost::multiprecision::detail::is_variable_precision::value)
#endif
}
}
} // namespace boost::multiprecision::detail
#endif // BOOST_MP_IS_BACKEND_HPP