Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / multiprecision / detail / precision.hpp
index c5d373a..e0cfc2d 100644 (file)
 #include <boost/multiprecision/detail/number_base.hpp>
 #include <boost/multiprecision/detail/digits.hpp>
 
-namespace boost{ namespace multiprecision{  namespace detail{
-
-   template <class B, boost::multiprecision::expression_template_option ET>
-   inline BOOST_CONSTEXPR unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>&, const mpl::false_&)
-   {
-      return std::numeric_limits<boost::multiprecision::number<B, ET> >::digits10;
-   }
-   template <class B, boost::multiprecision::expression_template_option ET>
-   inline unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>& 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);
-   }
+namespace boost { namespace multiprecision { namespace detail {
 
+template <class B, boost::multiprecision::expression_template_option ET>
+inline BOOST_CONSTEXPR unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>&, const mpl::false_&)
+{
+   return std::numeric_limits<boost::multiprecision::number<B, ET> >::digits10;
+}
+template <class B, boost::multiprecision::expression_template_option ET>
+inline BOOST_MP_CXX14_CONSTEXPR unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>& 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 <class B, boost::multiprecision::expression_template_option ET>
-   inline unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& n, const mpl::true_&)
-   {
-      return n.precision();
-   }
-   template <class B, boost::multiprecision::expression_template_option ET>
-   inline BOOST_CONSTEXPR unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& val, const mpl::false_&)
-   {
-      return current_precision_of_last_chance_imp(val, 
-         mpl::bool_<
-            std::numeric_limits<boost::multiprecision::number<B, ET> >::is_specialized 
-            && std::numeric_limits<boost::multiprecision::number<B, ET> >::is_integer 
-            && std::numeric_limits<boost::multiprecision::number<B, ET> >::is_exact 
-            && !std::numeric_limits<boost::multiprecision::number<B, ET> >::is_modulo>());
-   }
+template <class B, boost::multiprecision::expression_template_option ET>
+inline BOOST_MP_CXX14_CONSTEXPR unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& n, const mpl::true_&)
+{
+   return n.precision();
+}
+template <class B, boost::multiprecision::expression_template_option ET>
+inline BOOST_CONSTEXPR unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& val, const mpl::false_&)
+{
+   return current_precision_of_last_chance_imp(val,
+                                               mpl::bool_ <
+                                                       std::numeric_limits<boost::multiprecision::number<B, ET> >::is_specialized &&
+                                                   std::numeric_limits<boost::multiprecision::number<B, ET> >::is_integer && std::numeric_limits<boost::multiprecision::number<B, ET> >::is_exact && !std::numeric_limits<boost::multiprecision::number<B, ET> >::is_modulo > ());
+}
 
-   template <class Terminal>
-   inline BOOST_CONSTEXPR unsigned current_precision_of(const Terminal&)
-   {
-      return std::numeric_limits<Terminal>::digits10;
-   }
+template <class Terminal>
+inline BOOST_CONSTEXPR unsigned current_precision_of(const Terminal&)
+{
+   return std::numeric_limits<Terminal>::digits10;
+}
 
-   template <class Terminal, std::size_t N>
-   inline BOOST_CONSTEXPR unsigned current_precision_of(const Terminal(&)[N])
-   { // For string literals:
-      return 0;
-   }
+template <class Terminal, std::size_t N>
+inline BOOST_CONSTEXPR unsigned current_precision_of(const Terminal (&)[N])
+{ // For string literals:
+   return 0;
+}
 
-   template <class B, boost::multiprecision::expression_template_option ET>
-   inline BOOST_CONSTEXPR unsigned current_precision_of(const boost::multiprecision::number<B, ET>& n)
-   {
-      return current_precision_of_imp(n, boost::multiprecision::detail::is_variable_precision<boost::multiprecision::number<B, ET> >());
-   }
+template <class B, boost::multiprecision::expression_template_option ET>
+inline BOOST_CONSTEXPR unsigned current_precision_of(const boost::multiprecision::number<B, ET>& n)
+{
+   return current_precision_of_imp(n, boost::multiprecision::detail::is_variable_precision<boost::multiprecision::number<B, ET> >());
+}
 
-   template<class tag, class Arg1>
-   inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, void, void, void>& expr)
-   {
-      return current_precision_of(expr.left_ref());
-   }
+template <class tag, class Arg1>
+inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, void, void, void>& expr)
+{
+   return current_precision_of(expr.left_ref());
+}
 
-   template<class Arg1>
-   inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<terminal, Arg1, void, void, void>& expr)
-   {
-      return current_precision_of(expr.value());
-   }
+template <class Arg1>
+inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<terminal, Arg1, void, void, void>& expr)
+{
+   return current_precision_of(expr.value());
+}
 
-   template <class tag, class Arg1, class Arg2>
-   inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, Arg2, void, void>& expr)
-   {
-      return (std::max)(current_precision_of(expr.left_ref()), current_precision_of(expr.right_ref()));
-   }
+template <class tag, class Arg1, class Arg2>
+inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, Arg2, void, void>& expr)
+{
+   return (std::max)(current_precision_of(expr.left_ref()), current_precision_of(expr.right_ref()));
+}
 
-   template <class tag, class Arg1, class Arg2, class Arg3>
-   inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, Arg2, Arg3, void>& expr)
-   {
-      return (std::max)((std::max)(current_precision_of(expr.left_ref()), current_precision_of(expr.right_ref())), current_precision_of(expr.middle_ref()));
-   }
+template <class tag, class Arg1, class Arg2, class Arg3>
+inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, Arg2, Arg3, void>& 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)
+#pragma warning(disable : 4130)
 #endif
 
-   template <class R, bool = boost::multiprecision::detail::is_variable_precision<R>::value>
-   struct scoped_default_precision
+template <class R, bool = boost::multiprecision::detail::is_variable_precision<R>::value>
+struct scoped_default_precision
+{
+   template <class T>
+   BOOST_CONSTEXPR scoped_default_precision(const T&) {}
+   template <class T, class U>
+   BOOST_CONSTEXPR scoped_default_precision(const T&, const U&) {}
+   template <class T, class U, class V>
+   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
    {
-      template <class T>
-      BOOST_CONSTEXPR scoped_default_precision(const T&) {}
-      template <class T, class U>
-      BOOST_CONSTEXPR scoped_default_precision(const T&, const U&) {}
-      template <class T, class U, class V>
-      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; 
-      }
-   };
+      BOOST_ASSERT("This function should never be called!!" == 0);
+      return 0;
+   }
+};
 
 #ifdef BOOST_MSVC
 #pragma warning(pop)
 #endif
 
-   template <class R>
-   struct scoped_default_precision<R, true>
-   {
-      template <class T>
-      BOOST_CXX14_CONSTEXPR scoped_default_precision(const T& a) 
-      {
-         init(current_precision_of(a));
-      }
-      template <class T, class U>
-      BOOST_CXX14_CONSTEXPR scoped_default_precision(const T& a, const U& b)
-      {
-         init((std::max)(current_precision_of(a), current_precision_of(b)));
-      }
-      template <class T, class U, class V>
-      BOOST_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()
-      {
-         R::default_precision(m_old_prec);
-      }
-      BOOST_CXX14_CONSTEXPR unsigned precision()const
-      {
-         return m_new_prec;
-      }
-   private:
-      BOOST_CXX14_CONSTEXPR void init(unsigned p)
-      {
-         m_old_prec = R::default_precision();
-         if (p)
-         {
-            R::default_precision(p);
-            m_new_prec = p;
-         }
-         else
-            m_new_prec = m_old_prec;
-      }
-      unsigned m_old_prec, m_new_prec;
-   };
-
+template <class R>
+struct scoped_default_precision<R, true>
+{
    template <class T>
-   inline void maybe_promote_precision(T*, const mpl::false_&){}
+   BOOST_MP_CXX14_CONSTEXPR scoped_default_precision(const T& a)
+   {
+      init(current_precision_of(a));
+   }
+   template <class T, class U>
+   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 <class T, class U, class V>
+   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()
+   {
+      R::default_precision(m_old_prec);
+   }
+   BOOST_MP_CXX14_CONSTEXPR unsigned precision() const
+   {
+      return m_new_prec;
+   }
 
-   template <class T>
-   inline void maybe_promote_precision(T* obj, const mpl::true_&)
+ private:
+   BOOST_MP_CXX14_CONSTEXPR void init(unsigned p)
    {
-      if (obj->precision() != T::default_precision())
+      m_old_prec = R::default_precision();
+      if (p)
       {
-         obj->precision(T::default_precision());
+         R::default_precision(p);
+         m_new_prec = p;
       }
+      else
+         m_new_prec = m_old_prec;
    }
+   unsigned m_old_prec, m_new_prec;
+};
 
-   template <class T>
-   inline void maybe_promote_precision(T* obj)
+template <class T>
+inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T*, const mpl::false_&) {}
+
+template <class T>
+inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T* obj, const mpl::true_&)
+{
+   if (obj->precision() != T::default_precision())
    {
-      maybe_promote_precision(obj, boost::multiprecision::detail::is_variable_precision<T>());
+      obj->precision(T::default_precision());
    }
+}
+
+template <class T>
+inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T* obj)
+{
+   maybe_promote_precision(obj, mpl::bool_<boost::multiprecision::detail::is_variable_precision<T>::value>());
+}
 
 #ifndef BOOST_NO_CXX17_IF_CONSTEXPR
-#  define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) if constexpr (boost::multiprecision::detail::is_variable_precision<T>::value)
+#define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) \
+   if                                               \
+   constexpr(boost::multiprecision::detail::is_variable_precision<T>::value)
 #else
-#  define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) if(boost::multiprecision::detail::is_variable_precision<T>::value)
+#define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) if (boost::multiprecision::detail::is_variable_precision<T>::value)
 #endif
 
-
-}
 }
 }
+} // namespace boost::multiprecision::detail
 
 #endif // BOOST_MP_IS_BACKEND_HPP