diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index 71952e6..9ad7240 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -549,11 +549,14 @@ inline static_string to_static_string_int_impl(Integer value) noexcept { - char buffer[N]; - const auto digits_end = std::end(buffer); - const auto digits_begin = integer_to_string, Integer>( + static_string result; + char * const digits_end = result.data() + N; + char * const digits_begin = integer_to_string, Integer>( digits_end, value, std::is_signed{}); - return static_string(digits_begin, std::distance(digits_begin, digits_end)); + result.set_size(digits_end - digits_begin); + std::char_traits::move(result.data(), digits_begin, result.size()); + result.term(); + return result; } #ifdef BOOST_STATIC_STRING_HAS_WCHAR @@ -562,11 +565,14 @@ inline static_wstring to_static_wstring_int_impl(Integer value) noexcept { - wchar_t buffer[N]; - const auto digits_end = std::end(buffer); - const auto digits_begin = integer_to_wstring, Integer>( + static_wstring result; + wchar_t * const digits_end = result.data() + N; + wchar_t * const digits_begin = integer_to_wstring, Integer>( digits_end, value, std::is_signed{}); - return static_wstring(digits_begin, std::distance(digits_begin, digits_end)); + result.set_size(digits_end - digits_begin); + std::char_traits::move(result.data(), digits_begin, result.size()); + result.term(); + return result; } #endif @@ -595,11 +601,11 @@ to_static_string_float_impl(double value) noexcept // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - // extra one needed for null terminator - char buffer[N + 1]; + static_string result; // we know that a formatting error will not occur, so // we assume that the result is always positive - if (std::size_t(std::snprintf(buffer, N + 1, "%f", value)) > N) + std::size_t length = std::snprintf(result.data(), N + 1, "%f", value); + if (length > N) { // the + 4 is for the decimal, 'e', // its sign, and the sign of the integral portion @@ -609,10 +615,10 @@ to_static_string_float_impl(double value) noexcept const int precision = narrow > reserved_count ? N - reserved_count : 0; // switch to scientific notation - std::snprintf(buffer, N + 1, "%.*e", precision, value); + length = std::snprintf(result.data(), N + 1, "%.*e", precision, value); } - // this will not throw - return static_string(buffer); + result.set_size(length); + return result; } template @@ -624,13 +630,13 @@ to_static_string_float_impl(long double value) noexcept // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - // extra one needed for null terminator - char buffer[N + 1]; + static_string result; // snprintf returns the number of characters // that would have been written // we know that a formatting error will not occur, so // we assume that the result is always positive - if (std::size_t(std::snprintf(buffer, N + 1, "%Lf", value)) > N) + std::size_t length = std::snprintf(result.data(), N + 1, "%Lf", value); + if (length > N) { // the + 4 is for the decimal, 'e', // its sign, and the sign of the integral portion @@ -640,10 +646,10 @@ to_static_string_float_impl(long double value) noexcept const int precision = narrow > reserved_count ? N - reserved_count : 0; // switch to scientific notation - std::snprintf(buffer, N + 1, "%.*Le", precision, value); + length = std::snprintf(result.data(), N + 1, "%.*Le", precision, value); } - // this will not throw - return static_string(buffer); + result.set_size(length); + return result; } #ifdef BOOST_STATIC_STRING_HAS_WCHAR @@ -656,8 +662,7 @@ to_static_wstring_float_impl(double value) noexcept // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - // extra one needed for null terminator - wchar_t buffer[N + 1]; + static_wstring result; // swprintf returns a negative number if it can't // fit all the characters in the buffer. // mingw has a non-standard swprintf, so @@ -665,8 +670,8 @@ to_static_wstring_float_impl(double value) noexcept // circuit evaluation will ensure that the // second operand is not evaluated on conforming // implementations. - const long long num_written = - std::swprintf(buffer, N + 1, L"%f", value); + long long num_written = + std::swprintf(result.data(), N + 1, L"%f", value); if (num_written < 0 || num_written > narrow) { @@ -678,10 +683,10 @@ to_static_wstring_float_impl(double value) noexcept const int precision = narrow > reserved_count ? N - reserved_count : 0; // switch to scientific notation - std::swprintf(buffer, N + 1, L"%.*e", precision, value); + num_written = std::swprintf(result.data(), N + 1, L"%.*e", precision, value); } - // this will not throw - return static_wstring(buffer); + result.set_size(static_cast(num_written)); + return result; } template @@ -693,8 +698,7 @@ to_static_wstring_float_impl(long double value) noexcept // will require more than 2^63 chars to represent a float value. const long long narrow = static_cast(N); - // extra one needed for null terminator - wchar_t buffer[N + 1]; + static_wstring result; // swprintf returns a negative number if it can't // fit all the characters in the buffer. // mingw has a non-standard swprintf, so @@ -702,8 +706,8 @@ to_static_wstring_float_impl(long double value) noexcept // circuit evaluation will ensure that the // second operand is not evaluated on conforming // implementations. - const long long num_written = - std::swprintf(buffer, N + 1, L"%Lf", value); + long long num_written = + std::swprintf(result.data(), N + 1, L"%Lf", value); if (num_written < 0 || num_written > narrow) { @@ -715,10 +719,10 @@ to_static_wstring_float_impl(long double value) noexcept const int precision = narrow > reserved_count ? N - reserved_count : 0; // switch to scientific notation - std::swprintf(buffer, N + 1, L"%.*Le", precision, value); + num_written = std::swprintf(result.data(), N + 1, L"%.*Le", precision, value); } - // this will not throw - return static_wstring(buffer); + result.set_size(static_cast(num_written)); + return result; } #endif @@ -925,6 +929,37 @@ class basic_static_string private: template friend class basic_static_string; + + template + friend + static_string

+ detail::to_static_string_int_impl(Integer value) noexcept; + + template + friend + static_string

+ detail::to_static_string_float_impl(double value) noexcept; + + template + friend + static_string

+ detail::to_static_string_float_impl(long double value) noexcept; + +#ifdef BOOST_STATIC_STRING_HAS_WCHAR + template + friend static_wstring

+ detail::to_static_wstring_int_impl(Integer value) noexcept; + + template + friend + static_wstring

+ detail::to_static_wstring_float_impl(double value) noexcept; + + template + friend + static_wstring

+ detail::to_static_wstring_float_impl(long double value) noexcept; +#endif public: //-------------------------------------------------------------------------- //