// Copyright 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_DECIMAL_DETAIL_BUFFER_SIZING_HPP #define BOOST_DECIMAL_DETAIL_BUFFER_SIZING_HPP #include #include #include #ifndef BOOST_DECIMAL_BUILD_MODULE #include #endif namespace boost { namespace decimal { namespace detail { #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4127) // Conditional expression for BOOST_IF_CONSTEXPR will be constant in not C++17 #endif template constexpr int get_real_precision(const int my_precision = -1) noexcept { // If the user did not specify precision than we use the maximum representable amount // and remove trailing zeros at the end return my_precision == -1 ? std::numeric_limits::max_digits10 : my_precision; } // We don't need to use the full digit counting since the range of the exponents is well-defined template constexpr auto buffer_length_exp(Int x) noexcept -> std::enable_if_t::max_exponent >= 1000, int> { if (x < 10) return 1; if (x < 100) return 2; if (x < 1000) return 3; return 4; } template constexpr auto buffer_length_exp(Int x) noexcept -> std::enable_if_t::max_exponent >= 100 && std::numeric_limits::max_exponent < 1000, int> { if (x < 10) return 1; if (x < 100) return 2; return 3; } template constexpr auto buffer_length_exp(Int x) noexcept -> std::enable_if_t::max_exponent >= 10 && std::numeric_limits::max_exponent < 100, int> { if (x < 10) return 1; return 2; } template constexpr int total_buffer_length(int real_precision, Int exp, bool signed_value) noexcept { // Sign + integer part + '.' + precision of fraction part + e+/e- or p+/p- + exponent digits return static_cast(signed_value) + 1 + real_precision + 2 + buffer_length_exp(make_positive_unsigned(exp)); } #ifdef _MSC_VER # pragma warning(pop) #endif } //namespace detail } //namespace decimal } //namespace boost #endif //BOOST_DECIMAL_DETAIL_BUFFER_SIZING_HPP