From 47d942fddc044f60d56788391c3dc881cedfb409 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 20 Feb 2024 09:57:25 +0100 Subject: [PATCH 1/7] Add test set for negative precision --- test/Jamfile | 1 + test/github_issue_166.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 test/github_issue_166.cpp diff --git a/test/Jamfile b/test/Jamfile index 499363a4..c262e7a9 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -62,3 +62,4 @@ run github_issue_152_float128.cpp : : : [ check-target-builds ../config//has_flo run github_issue_154.cpp ; #run github_issue_156.cpp ; run github_issue_158.cpp ; +run github_issue_166.cpp ; diff --git a/test/github_issue_166.cpp b/test/github_issue_166.cpp new file mode 100644 index 00000000..bde1b0ae --- /dev/null +++ b/test/github_issue_166.cpp @@ -0,0 +1,37 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/charconv/issues/166 + +#include +#include + +template +void simple_test() +{ + for (int i = -1; i > -5; --i) + { + char buffer[256] {}; + boost::charconv::to_chars(buffer, buffer + sizeof(buffer), static_cast(9.99999L), boost::charconv::chars_format::fixed, i); + BOOST_TEST_CSTR_EQ(buffer, "9.999990"); + } +} + +int main() +{ + simple_test(); + simple_test(); + #if BOOST_CHARCONV_LDBL_BITS == 64 + simple_test(); + #endif + + #ifdef BOOST_CHARCONV_HAS_FLOAT32 + simple_test(); + #endif + #ifdef BOOST_CHARCONV_HAS_FLOAT64 + simple_test(); + #endif + + return boost::report_errors(); +} From 93628127f0fd9293fe2c8cad713555d2e7ff31e0 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 20 Feb 2024 10:30:57 +0100 Subject: [PATCH 2/7] Refactor to_chars_float_impl for 80 and 128 bit types --- src/to_chars_float_impl.hpp | 143 ++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/src/to_chars_float_impl.hpp b/src/to_chars_float_impl.hpp index f7e3f6d0..0cccaba0 100644 --- a/src/to_chars_float_impl.hpp +++ b/src/to_chars_float_impl.hpp @@ -689,6 +689,149 @@ to_chars_result to_chars_float_impl(char* first, char* last, Real value, chars_f return boost::charconv::detail::to_chars_hex(first, last, value, precision); } +#if (BOOST_CHARCONV_LDBL_BITS == 80 || BOOST_CHARCONV_LDBL_BITS == 128) + +template <> +to_chars_result to_chars_float_impl(char* first, char* last, long double value, chars_format fmt, int precision) noexcept +{ + static_assert(std::numeric_limits::is_iec559, "Long double must be IEEE 754 compliant"); + + const auto classification = std::fpclassify(value); + #if BOOST_CHARCONV_LDBL_BITS == 128 + if (classification == FP_NAN || classification == FP_INFINITE) + { + return boost::charconv::detail::to_chars_nonfinite(first, last, value, classification); + } + #else + if (classification == FP_NAN || classification == FP_INFINITE) + { + const auto fd128 = boost::charconv::detail::ryu::long_double_to_fd128(value); + const auto num_chars = boost::charconv::detail::ryu::generic_to_chars(fd128, first, last - first, fmt, precision); + + if (num_chars > 0) + { + return { first + num_chars, std::errc() }; + } + else + { + return {last, std::errc::value_too_large}; + } + } + #endif + + // Sanity check our bounds + const std::ptrdiff_t buffer_size = last - first; + auto real_precision = boost::charconv::detail::get_real_precision(precision); + if (buffer_size < real_precision || first > last) + { + return {last, std::errc::value_too_large}; + } + + if (fmt == boost::charconv::chars_format::general || fmt == boost::charconv::chars_format::scientific) + { + const auto fd128 = boost::charconv::detail::ryu::long_double_to_fd128(value); + const auto num_chars = boost::charconv::detail::ryu::generic_to_chars(fd128, first, last - first, fmt, precision); + + if (num_chars > 0) + { + return { first + num_chars, std::errc() }; + } + } + else if (fmt == boost::charconv::chars_format::hex) + { + return boost::charconv::detail::to_chars_hex(first, last, value, precision); + } + else if (fmt == boost::charconv::chars_format::fixed) + { + const auto fd128 = boost::charconv::detail::ryu::long_double_to_fd128(value); + const auto num_chars = boost::charconv::detail::ryu::generic_to_chars_fixed(fd128, first, last - first, precision); + + if (num_chars > 0) + { + return { first + num_chars, std::errc() }; + } + else if (num_chars == -static_cast(std::errc::value_too_large)) + { + return { last, std::errc::value_too_large }; + } + } + + // Fallback to printf methods + return boost::charconv::detail::to_chars_printf_impl(first, last, value, fmt, precision); +} + +#endif + +#ifdef BOOST_CHARCONV_HAS_FLOAT128 + +template <> +to_chars_result to_chars_float_impl(char* first, char* last, __float128 value, chars_format fmt, int precision) noexcept +{ + // Sanity check our bounds + if (first >= last) + { + return {last, std::errc::value_too_large}; + } + + char* const original_first = first; + + if (isnanq(value)) + { + return boost::charconv::detail::to_chars_nonfinite(first, last, value, FP_NAN); + } + else if (isinfq(value)) + { + return boost::charconv::detail::to_chars_nonfinite(first, last, value, FP_INFINITE); + } + + // Sanity check our bounds + const std::ptrdiff_t buffer_size = last - first; + auto real_precision = boost::charconv::detail::get_real_precision<__float128>(precision); + if (buffer_size < real_precision || first > last) + { + return {last, std::errc::value_too_large}; + } + + if ((fmt == boost::charconv::chars_format::general || fmt == boost::charconv::chars_format::scientific)) + { + const auto fd128 = boost::charconv::detail::ryu::float128_to_fd128(value); + const auto num_chars = boost::charconv::detail::ryu::generic_to_chars(fd128, first, last - first, fmt, precision); + + if (num_chars > 0) + { + return { first + num_chars, std::errc() }; + } + else if (num_chars == -1) + { + return {last, std::errc::value_too_large}; + } + } + else if (fmt == boost::charconv::chars_format::hex) + { + return boost::charconv::detail::to_chars_hex(first, last, value, precision); + } + else if (fmt == boost::charconv::chars_format::fixed) + { + const auto fd128 = boost::charconv::detail::ryu::float128_to_fd128(value); + const auto num_chars = boost::charconv::detail::ryu::generic_to_chars_fixed(fd128, first, last - first, precision); + + if (num_chars > 0) + { + return { first + num_chars, std::errc() }; + } + else if (num_chars == -static_cast(std::errc::value_too_large)) + { + return { last, std::errc::value_too_large }; + } + } + + first = original_first; + // Fallback to printf + return boost::charconv::detail::to_chars_printf_impl(first, last, value, fmt, precision); +} + +#endif + } // namespace detail } // namespace charconv } // namespace detail From dba9fb81abccbf3995079aab4e8e45f97c8f9604 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 20 Feb 2024 10:31:24 +0100 Subject: [PATCH 3/7] Add to_chars overloads without precision --- include/boost/charconv/to_chars.hpp | 43 ++++-- src/to_chars.cpp | 227 +++++++++++++--------------- 2 files changed, 143 insertions(+), 127 deletions(-) diff --git a/include/boost/charconv/to_chars.hpp b/include/boost/charconv/to_chars.hpp index 89e32223..3946e469 100644 --- a/include/boost/charconv/to_chars.hpp +++ b/include/boost/charconv/to_chars.hpp @@ -78,36 +78,61 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars(char* first, char* last, boost //---------------------------------------------------------------------------------------------------------------------- BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, float value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt = chars_format::general) noexcept; +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, double value, + chars_format fmt = chars_format::general) noexcept; +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, long double value, + chars_format fmt = chars_format::general) noexcept; + +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, float value, + chars_format fmt, int precision) noexcept; BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, double value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt, int precision) noexcept; BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, long double value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt, int precision) noexcept; #ifdef BOOST_CHARCONV_HAS_FLOAT128 BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, __float128 value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt = chars_format::general) noexcept; + +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, __float128 value, + chars_format fmt, int precision) noexcept; #endif #ifdef BOOST_CHARCONV_HAS_FLOAT16 +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::float16_t value, + chars_format fmt = chars_format::general) noexcept; + BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::float16_t value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt, int precision) noexcept; #endif #ifdef BOOST_CHARCONV_HAS_FLOAT32 +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::float32_t value, + chars_format fmt = chars_format::general) noexcept; + BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::float32_t value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt, int precision) noexcept; #endif #ifdef BOOST_CHARCONV_HAS_FLOAT64 +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::float64_t value, + chars_format fmt = chars_format::general) noexcept; + BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::float64_t value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt, int precision) noexcept; #endif #if defined(BOOST_CHARCONV_HAS_STDFLOAT128) && defined(BOOST_CHARCONV_HAS_FLOAT128) BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::float128_t value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt = chars_format::general) noexcept; + +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::float128_t value, + chars_format fmt, int precision) noexcept; #endif #ifdef BOOST_CHARCONV_HAS_BRAINFLOAT16 +BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::bfloat16_t value, + chars_format fmt = chars_format::general) noexcept; + BOOST_CHARCONV_DECL to_chars_result to_chars(char* first, char* last, std::bfloat16_t value, - chars_format fmt = chars_format::general, int precision = -1 ) noexcept; + chars_format fmt, int precision) noexcept; #endif } // namespace charconv diff --git a/src/to_chars.cpp b/src/to_chars.cpp index 8fa1f7f1..159fec62 100644 --- a/src/to_chars.cpp +++ b/src/to_chars.cpp @@ -548,95 +548,76 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det }}}} // Namespaces +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, float value, + boost::charconv::chars_format fmt) noexcept +{ + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt); +} + boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, float value, boost::charconv::chars_format fmt, int precision) noexcept { + if (precision < 0) + { + precision = 6; + } + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, precision); } +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, double value, + boost::charconv::chars_format fmt) noexcept +{ + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt); +} + boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, double value, boost::charconv::chars_format fmt, int precision) noexcept { + if (precision < 0) + { + precision = 6; + } + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, precision); } #if BOOST_CHARCONV_LDBL_BITS == 64 || defined(BOOST_MSVC) boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, long double value, - boost::charconv::chars_format fmt, int precision) noexcept + boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, precision); + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt); } -#elif (BOOST_CHARCONV_LDBL_BITS == 80 || BOOST_CHARCONV_LDBL_BITS == 128) - boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, long double value, boost::charconv::chars_format fmt, int precision) noexcept { - static_assert(std::numeric_limits::is_iec559, "Long double must be IEEE 754 compliant"); - - const auto classification = std::fpclassify(value); - #if BOOST_CHARCONV_LDBL_BITS == 128 - if (classification == FP_NAN || classification == FP_INFINITE) + if (precision < 0) { - return boost::charconv::detail::to_chars_nonfinite(first, last, value, classification); + precision = 6; } - #else - if (classification == FP_NAN || classification == FP_INFINITE) - { - const auto fd128 = boost::charconv::detail::ryu::long_double_to_fd128(value); - const auto num_chars = boost::charconv::detail::ryu::generic_to_chars(fd128, first, last - first, fmt, precision); - if (num_chars > 0) - { - return { first + num_chars, std::errc() }; - } - else - { - return {last, std::errc::value_too_large}; - } - } - #endif + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, precision); +} - // Sanity check our bounds - const std::ptrdiff_t buffer_size = last - first; - auto real_precision = boost::charconv::detail::get_real_precision(precision); - if (buffer_size < real_precision || first > last) - { - return {last, std::errc::value_too_large}; - } +#elif (BOOST_CHARCONV_LDBL_BITS == 80 || BOOST_CHARCONV_LDBL_BITS == 128) - if (fmt == boost::charconv::chars_format::general || fmt == boost::charconv::chars_format::scientific) - { - const auto fd128 = boost::charconv::detail::ryu::long_double_to_fd128(value); - const auto num_chars = boost::charconv::detail::ryu::generic_to_chars(fd128, first, last - first, fmt, precision); +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, long double value, + boost::charconv::chars_format fmt) noexcept +{ + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, -1); +} - if (num_chars > 0) - { - return { first + num_chars, std::errc() }; - } - } - else if (fmt == boost::charconv::chars_format::hex) +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, long double value, + boost::charconv::chars_format fmt, int precision) noexcept +{ + if (precision < 0) { - return boost::charconv::detail::to_chars_hex(first, last, value, precision); + precision = 6; } - else if (fmt == boost::charconv::chars_format::fixed) - { - const auto fd128 = boost::charconv::detail::ryu::long_double_to_fd128(value); - const auto num_chars = boost::charconv::detail::ryu::generic_to_chars_fixed(fd128, first, last - first, precision); - if (num_chars > 0) - { - return { first + num_chars, std::errc() }; - } - else if (num_chars == -static_cast(std::errc::value_too_large)) - { - return { last, std::errc::value_too_large }; - } - } - - // Fallback to printf methods - return boost::charconv::detail::to_chars_printf_impl(first, last, value, fmt, precision); + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, precision); } #else @@ -683,80 +664,49 @@ boost::charconv::to_chars_result boost::charconv::to_chars( char* first, char* l boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, __float128 value, boost::charconv::chars_format fmt, int precision) noexcept { - // Sanity check our bounds - if (first >= last) - { - return {last, std::errc::value_too_large}; - } - - char* const original_first = first; - - if (isnanq(value)) - { - return boost::charconv::detail::to_chars_nonfinite(first, last, value, FP_NAN); - } - else if (isinfq(value)) - { - return boost::charconv::detail::to_chars_nonfinite(first, last, value, FP_INFINITE); - } - - // Sanity check our bounds - const std::ptrdiff_t buffer_size = last - first; - auto real_precision = boost::charconv::detail::get_real_precision<__float128>(precision); - if (buffer_size < real_precision || first > last) - { - return {last, std::errc::value_too_large}; - } - - if ((fmt == boost::charconv::chars_format::general || fmt == boost::charconv::chars_format::scientific)) - { - const auto fd128 = boost::charconv::detail::ryu::float128_to_fd128(value); - const auto num_chars = boost::charconv::detail::ryu::generic_to_chars(fd128, first, last - first, fmt, precision); + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, -1); +} - if (num_chars > 0) - { - return { first + num_chars, std::errc() }; - } - else if (num_chars == -1) - { - return {last, std::errc::value_too_large}; - } - } - else if (fmt == boost::charconv::chars_format::hex) +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, __float128 value, boost::charconv::chars_format fmt, int precision) noexcept +{ + if (precision < 0) { - return boost::charconv::detail::to_chars_hex(first, last, value, precision); + precision = 6; } - else if (fmt == boost::charconv::chars_format::fixed) - { - const auto fd128 = boost::charconv::detail::ryu::float128_to_fd128(value); - const auto num_chars = boost::charconv::detail::ryu::generic_to_chars_fixed(fd128, first, last - first, precision); - if (num_chars > 0) - { - return { first + num_chars, std::errc() }; - } - else if (num_chars == -static_cast(std::errc::value_too_large)) - { - return { last, std::errc::value_too_large }; - } - } - - first = original_first; - // Fallback to printf - return boost::charconv::detail::to_chars_printf_impl(first, last, value, fmt, precision); + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, precision); } #endif #ifdef BOOST_CHARCONV_HAS_FLOAT16 + +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float16_t value, + boost::charconv::chars_format fmt) noexcept +{ + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt); +} + boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float16_t value, boost::charconv::chars_format fmt, int precision) noexcept { + if (precision < 0) + { + precision = 6; + } + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, precision); } #endif #ifdef BOOST_CHARCONV_HAS_FLOAT32 + +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float32_t value, + boost::charconv::chars_format fmt) noexcept +{ + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt); +} + boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float32_t value, boost::charconv::chars_format fmt, int precision) noexcept { @@ -764,34 +714,75 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la std::numeric_limits::min_exponent == FLT_MIN_EXP, "float and std::float32_t are not the same layout like they should be"); + if (precision < 0) + { + precision = 6; + } + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, precision); } #endif #ifdef BOOST_CHARCONV_HAS_FLOAT64 + +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float64_t value, + boost::charconv::chars_format fmt) noexcept +{ + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt); +} + boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float64_t value, boost::charconv::chars_format fmt, int precision) noexcept { static_assert(std::numeric_limits::digits == DBL_MANT_DIG && std::numeric_limits::min_exponent == DBL_MIN_EXP, "double and std::float64_t are not the same layout like they should be"); - + + if (precision < 0) + { + precision = 6; + } + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, precision); } #endif #if defined(BOOST_CHARCONV_HAS_STDFLOAT128) && defined(BOOST_CHARCONV_HAS_FLOAT128) + +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float128_t value, + boost::charconv::chars_format fmt) noexcept +{ + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast<__float128>(value), fmt, -1); +} + boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float128_t value, boost::charconv::chars_format fmt, int precision) noexcept { - return boost::charconv::to_chars(first, last, static_cast<__float128>(value), fmt, precision); + if (precision < 0) + { + precision = 6; + } + + return boost::charconv::to_chars_float_impl(first, last, static_cast<__float128>(value), fmt, precision); } #endif #ifdef BOOST_CHARCONV_HAS_BRAINFLOAT16 + +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::bfloat16_t value, + boost::charconv::chars_format fmt) noexcept +{ + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt); +} + boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::bfloat16_t value, boost::charconv::chars_format fmt, int precision) noexcept { + if (precision < 0) + { + precision = 6; + } + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, precision); } #endif From 6bac04d89b1d563c82723097e2df8569a56eccf9 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 20 Feb 2024 10:50:59 +0100 Subject: [PATCH 4/7] Remove default precision parameter --- src/to_chars.cpp | 14 +++++++------- src/to_chars_float_impl.hpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/to_chars.cpp b/src/to_chars.cpp index 159fec62..e2e38feb 100644 --- a/src/to_chars.cpp +++ b/src/to_chars.cpp @@ -551,7 +551,7 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, float value, boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt); + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, -1); } boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, float value, @@ -568,7 +568,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, double value, boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt); + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, -1); } boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, double value, @@ -587,7 +587,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, long double value, boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt); + return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, -1); } boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, long double value, @@ -684,7 +684,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float16_t value, boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt); + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, -1); } boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float16_t value, @@ -704,7 +704,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float32_t value, boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt); + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, -1); } boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float32_t value, @@ -728,7 +728,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float64_t value, boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt); + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, -1); } boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::float64_t value, @@ -772,7 +772,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::bfloat16_t value, boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt); + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, -1); } boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, std::bfloat16_t value, diff --git a/src/to_chars_float_impl.hpp b/src/to_chars_float_impl.hpp index 0cccaba0..f2f7a436 100644 --- a/src/to_chars_float_impl.hpp +++ b/src/to_chars_float_impl.hpp @@ -591,7 +591,7 @@ to_chars_result to_chars_fixed_impl(char* first, char* last, Real value, chars_f } template -to_chars_result to_chars_float_impl(char* first, char* last, Real value, chars_format fmt = chars_format::general, int precision = -1 ) noexcept +to_chars_result to_chars_float_impl(char* first, char* last, Real value, chars_format fmt, int precision) noexcept { using Unsigned_Integer = typename std::conditional::value, std::uint64_t, std::uint32_t>::type; From 2f8e4d022ba8b4c802be4bc2f717e345830613c5 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 20 Feb 2024 10:54:27 +0100 Subject: [PATCH 5/7] Fix for MSVC long double --- src/to_chars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/to_chars.cpp b/src/to_chars.cpp index e2e38feb..51362a4c 100644 --- a/src/to_chars.cpp +++ b/src/to_chars.cpp @@ -587,7 +587,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, long double value, boost::charconv::chars_format fmt) noexcept { - return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, -1); + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast(value), fmt, -1); } boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, long double value, From 9b18b7078b136196a2e8399c1efc0dff593c5fd7 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 20 Feb 2024 10:55:40 +0100 Subject: [PATCH 6/7] Fix for __float128 unused parameter --- src/to_chars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/to_chars.cpp b/src/to_chars.cpp index 51362a4c..2d9c0497 100644 --- a/src/to_chars.cpp +++ b/src/to_chars.cpp @@ -662,7 +662,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars( char* first, char* l #ifdef BOOST_CHARCONV_HAS_FLOAT128 -boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, __float128 value, boost::charconv::chars_format fmt, int precision) noexcept +boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, __float128 value, boost::charconv::chars_format fmt) noexcept { return boost::charconv::detail::to_chars_float_impl(first, last, value, fmt, -1); } From 340a72eb244f1e67a25576d777ddff62b1005b72 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Tue, 20 Feb 2024 11:50:29 +0100 Subject: [PATCH 7/7] Fix ADL issue --- src/to_chars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/to_chars.cpp b/src/to_chars.cpp index 2d9c0497..02931261 100644 --- a/src/to_chars.cpp +++ b/src/to_chars.cpp @@ -763,7 +763,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la precision = 6; } - return boost::charconv::to_chars_float_impl(first, last, static_cast<__float128>(value), fmt, precision); + return boost::charconv::detail::to_chars_float_impl(first, last, static_cast<__float128>(value), fmt, precision); } #endif