From 5563d760ef7849c88f12d4d39d6e7f2b5c305703 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 27 Mar 2023 16:16:54 +0200 Subject: [PATCH] Implement general notation for non-integer results --- include/boost/charconv/detail/floff.hpp | 22 +++++++++++++++++++--- src/to_chars.cpp | 9 +++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/include/boost/charconv/detail/floff.hpp b/include/boost/charconv/detail/floff.hpp index 515944f..efa2bd8 100644 --- a/include/boost/charconv/detail/floff.hpp +++ b/include/boost/charconv/detail/floff.hpp @@ -22,6 +22,7 @@ #define BOOST_CHARCONV_DETAIL_FLOFF #include +#include #include #include #include @@ -2294,7 +2295,8 @@ namespace jkj { namespace floff { // precision means the number of decimal significand digits minus 1. // Assumes round-to-nearest, tie-to-even rounding. template - JKJ_SAFEBUFFERS char* floff(double const x, int const precision, char* buffer) noexcept { + JKJ_SAFEBUFFERS char* floff(double const x, int const precision, char* buffer, boost::charconv::chars_format fmt) noexcept + { assert(precision >= 0); using namespace detail; @@ -4562,14 +4564,28 @@ case n: ///////////////////////////////////////////////////////////////////////////////////////////////// fill_remaining_digits_with_0s: - std::memset(buffer, '0', remaining_digits); - buffer += remaining_digits; + if (fmt != boost::charconv::chars_format::general) + { + std::memset(buffer, '0', remaining_digits); + buffer += remaining_digits; + } insert_decimal_dot: buffer_starting_pos[0] = buffer_starting_pos[1]; buffer_starting_pos[1] = '.'; print_exponent_and_return: + if (fmt == boost::charconv::chars_format::general) + { + --buffer; + while (*buffer == '0') + { + --buffer; + } + + ++buffer; + } + if (decimal_exponent >= 0) { std::memcpy(buffer, "e+", 2); } diff --git a/src/to_chars.cpp b/src/to_chars.cpp index 0ca394a..2e1f880 100644 --- a/src/to_chars.cpp +++ b/src/to_chars.cpp @@ -290,7 +290,12 @@ 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, double value, boost::charconv::chars_format fmt, int precision) noexcept { - if (fmt == boost::charconv::chars_format::scientific) + if (fmt == boost::charconv::chars_format::general) + { + auto* ptr = jkj::floff::floff(value, std::numeric_limits::max_digits10 - 1, first, fmt); + return { ptr, 0 }; + } + else if (fmt == boost::charconv::chars_format::scientific) { if (precision == -1) { @@ -300,7 +305,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la { return { first, EOVERFLOW }; } - auto* ptr = jkj::floff::floff(value, precision, first); + auto* ptr = jkj::floff::floff(value, precision, first, fmt); return { ptr, 0 }; } else