From ee937a42d1718c2801251ba5a112b7fb0ae22d24 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 12:13:53 -0400 Subject: [PATCH 1/9] Fix sign conversions in the parser --- include/boost/charconv/detail/parser.hpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/boost/charconv/detail/parser.hpp b/include/boost/charconv/detail/parser.hpp index d0fdb881b..3ddea1b1e 100644 --- a/include/boost/charconv/detail/parser.hpp +++ b/include/boost/charconv/detail/parser.hpp @@ -219,7 +219,7 @@ inline from_chars_result parser(const char* first, const char* last, bool& sign, } if (dot_position != 0 || fractional) { - exponent = static_cast(dot_position) - i + extra_zeros + leading_zero_powers; + exponent = static_cast(dot_position - i) + extra_zeros + leading_zero_powers; } else { @@ -252,7 +252,7 @@ inline from_chars_result parser(const char* first, const char* last, bool& sign, return {first, std::errc::invalid_argument}; } - exponent = i - 1; + exponent = static_cast(i - 1); std::size_t offset = i; bool round = false; // If more digits are present than representable in the significand of the target type @@ -303,7 +303,7 @@ inline from_chars_result parser(const char* first, const char* last, bool& sign, // Finally we get the exponent constexpr std::size_t exponent_buffer_size = 6; // Float128 min exp is −16382 char exponent_buffer[exponent_buffer_size] {}; - Integer significand_digits = i; + const auto significand_digits = i; i = 0; // Get the sign first @@ -343,7 +343,7 @@ inline from_chars_result parser(const char* first, const char* last, bool& sign, { if (fractional) { - exponent = static_cast(dot_position) - significand_digits; + exponent = static_cast(dot_position - significand_digits); } else { @@ -371,17 +371,18 @@ inline from_chars_result parser(const char* first, const char* last, bool& sign, if (fmt == chars_format::hex) { // In hex the number of digits parsed is possibly less than the number of digits in base10 - exponent -= num_digits(significand) - dot_position; + exponent -= num_digits(significand) - static_cast(dot_position); } else { - exponent -= significand_digits - dot_position; + exponent -= static_cast(significand_digits - dot_position); } } else { exponent += extra_zeros; } + return {next, std::errc()}; } } From 5046bbea4c8cf6814fc351c50725866becd643c0 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 12:37:37 -0400 Subject: [PATCH 2/9] Fix to_chars_integer sign conversions --- .../boost/charconv/detail/compute_float64.hpp | 2 +- .../charconv/detail/from_chars_float_impl.hpp | 2 +- .../detail/from_chars_integer_impl.hpp | 2 +- .../charconv/detail/to_chars_integer_impl.hpp | 23 +++++++++++-------- include/boost/charconv/to_chars.hpp | 3 ++- src/to_chars.cpp | 14 +++++------ 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/include/boost/charconv/detail/compute_float64.hpp b/include/boost/charconv/detail/compute_float64.hpp index a2518ffec..afa4006fb 100644 --- a/include/boost/charconv/detail/compute_float64.hpp +++ b/include/boost/charconv/detail/compute_float64.hpp @@ -177,7 +177,7 @@ inline double compute_float64(std::int64_t power, std::uint64_t i, bool negative } significand &= ~(UINT64_C(1) << 52); - const std::uint64_t real_exponent = exponent - leading_zeros; + const auto real_exponent = static_cast(exponent - leading_zeros); // We have to check that real_exponent is in range, otherwise fail if (BOOST_UNLIKELY((real_exponent < 1) || (real_exponent > 2046))) diff --git a/include/boost/charconv/detail/from_chars_float_impl.hpp b/include/boost/charconv/detail/from_chars_float_impl.hpp index 8a1eec453..0433d8989 100644 --- a/include/boost/charconv/detail/from_chars_float_impl.hpp +++ b/include/boost/charconv/detail/from_chars_float_impl.hpp @@ -101,7 +101,7 @@ inline from_chars_result from_chars_strtod(const char* first, const char* last, // If the string to be parsed does not fit into the 1024 byte static buffer than we have to allocate a buffer. // malloc is used here because it does not throw on allocation failure. - char* buffer = static_cast(std::malloc(last - first + 1)); + char* buffer = static_cast(std::malloc(static_cast(last - first + 1))); if (buffer == nullptr) { return {first, std::errc::not_enough_memory}; diff --git a/include/boost/charconv/detail/from_chars_integer_impl.hpp b/include/boost/charconv/detail/from_chars_integer_impl.hpp index fa15937c1..df78681b6 100644 --- a/include/boost/charconv/detail/from_chars_integer_impl.hpp +++ b/include/boost/charconv/detail/from_chars_integer_impl.hpp @@ -227,7 +227,7 @@ BOOST_CXX14_CONSTEXPR from_chars_result from_chars_integer_impl(const char* firs { if (is_negative) { - value = -(static_cast(value)); + value = static_cast(-(static_cast(value))); } } diff --git a/include/boost/charconv/detail/to_chars_integer_impl.hpp b/include/boost/charconv/detail/to_chars_integer_impl.hpp index aee8c60e6..d775efaa1 100644 --- a/include/boost/charconv/detail/to_chars_integer_impl.hpp +++ b/include/boost/charconv/detail/to_chars_integer_impl.hpp @@ -106,7 +106,7 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars_integer_impl(char* first, char } else { - unsigned_value = value; + unsigned_value = static_cast(value); } } else @@ -139,7 +139,8 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars_integer_impl(char* first, char *first++ = '-'; } - boost::charconv::detail::memcpy(first, buffer + (sizeof(buffer) - converted_value_digits), converted_value_digits); + boost::charconv::detail::memcpy(first, buffer + (sizeof(buffer) - static_cast(converted_value_digits)), + static_cast(converted_value_digits)); } else if (std::numeric_limits::digits <= std::numeric_limits::digits || static_cast(unsigned_value) <= (std::numeric_limits::max)()) @@ -165,7 +166,8 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars_integer_impl(char* first, char const int first_value_chars = num_digits(x); decompose32(x, buffer); - boost::charconv::detail::memcpy(first, buffer + (sizeof(buffer) - first_value_chars), first_value_chars); + boost::charconv::detail::memcpy(first, buffer + (sizeof(buffer) - static_cast(first_value_chars)), + static_cast(first_value_chars)); decompose32(y, buffer); boost::charconv::detail::memcpy(first + first_value_chars, buffer + 1, sizeof(buffer) - 1); @@ -240,13 +242,13 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars_128integer_impl(char* first, c } else { - unsigned_value = value; + unsigned_value = static_cast(value); } } else #endif { - unsigned_value = value; + unsigned_value = static_cast(value); } auto converted_value = static_cast(unsigned_value); @@ -284,8 +286,8 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars_128integer_impl(char* first, c } --i; - boost::charconv::detail::memcpy(first, buffer[i] + 10 - num_chars[i], num_chars[i]); - std::size_t offset = num_chars[i]; + auto offset = static_cast(num_chars[i]); + boost::charconv::detail::memcpy(first, buffer[i] + 10 - offset, offset); while (i > 0) { @@ -327,12 +329,12 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars_integer_impl(char* first, char } else { - unsigned_value = value; + unsigned_value = static_cast(value); } } else { - unsigned_value = value; + unsigned_value = static_cast(value); } constexpr Unsigned_Integer zero = 48U; // Char for '0' @@ -400,7 +402,8 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars_integer_impl(char* first, char return {last, std::errc::result_out_of_range}; } - boost::charconv::detail::memcpy(first, buffer + (buffer_size - num_chars), num_chars); + boost::charconv::detail::memcpy(first, buffer + (buffer_size - static_cast(num_chars)), + static_cast(num_chars)); return {first + num_chars, std::errc()}; } diff --git a/include/boost/charconv/to_chars.hpp b/include/boost/charconv/to_chars.hpp index e76223464..fd72ea2ef 100644 --- a/include/boost/charconv/to_chars.hpp +++ b/include/boost/charconv/to_chars.hpp @@ -455,7 +455,8 @@ to_chars_result to_chars_float_impl(char* first, char* last, Real value, chars_f // Bounds check if (value_struct.exponent < 0 && -value_struct.exponent < buffer_size) { - std::memmove(r.ptr + value_struct.exponent + 1, r.ptr + value_struct.exponent, -value_struct.exponent); + std::memmove(r.ptr + value_struct.exponent + 1, r.ptr + value_struct.exponent, + static_cast(-value_struct.exponent)); std::memset(r.ptr + value_struct.exponent, '.', 1); ++r.ptr; } diff --git a/src/to_chars.cpp b/src/to_chars.cpp index ef94bcbe9..fd4886fb8 100644 --- a/src/to_chars.cpp +++ b/src/to_chars.cpp @@ -105,11 +105,11 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det const auto head_digits = std::uint32_t(prod >> 32); // If s32 is of 8 digits, increase the exponent by 7. // Otherwise, increase it by 6. - exponent += (6 + unsigned(head_digits >= 10)); + exponent += static_cast(6 + unsigned(head_digits >= 10)); // Write the first digit and the decimal point. std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2); - // This third character may be overwritten later but we don't care. + // This third character may be overwritten later, but we don't care. buffer[2] = radix_table[head_digits * 2 + 1]; // Remaining 6 digits are all zero? @@ -171,7 +171,7 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det // If s32 is of 6 digits, increase the exponent by 5. // Otherwise, increase it by 4. - exponent += (4 + unsigned(head_digits >= 10)); + exponent += static_cast(4 + unsigned(head_digits >= 10)); // Write the first digit and the decimal point. std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2); @@ -372,7 +372,7 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2); buffer[2] = radix_table[head_digits * 2 + 1]; - exponent += (6 + unsigned(head_digits >= 10)); + exponent += static_cast(6 + unsigned(head_digits >= 10)); buffer += unsigned(head_digits >= 10); // Print remaining 6 digits. @@ -395,7 +395,7 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2); buffer[2] = radix_table[head_digits * 2 + 1]; - exponent += (4 + unsigned(head_digits >= 10)); + exponent += static_cast(4 + unsigned(head_digits >= 10)); buffer += unsigned(head_digits >= 10); // Print remaining 4 digits. @@ -416,7 +416,7 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2); buffer[2] = radix_table[head_digits * 2 + 1]; - exponent += (2 + unsigned(head_digits >= 10)); + exponent += static_cast(2 + unsigned(head_digits >= 10)); buffer += unsigned(head_digits >= 10); // Print remaining 2 digits. @@ -431,7 +431,7 @@ namespace boost { namespace charconv { namespace detail { namespace to_chars_det std::memcpy(buffer, radix_100_head_table + first_block * 2, 2); buffer[2] = radix_table[first_block * 2 + 1]; - exponent += unsigned(first_block >= 10); + exponent += (first_block >= 10); buffer += (2 + unsigned(first_block >= 10)); } From e6776d538a2157ff14aa36b98d50f06c43f01063 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 13:11:47 -0400 Subject: [PATCH 3/9] Add assertion to power computation --- .../boost/charconv/detail/dragonbox/dragonbox_common.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/boost/charconv/detail/dragonbox/dragonbox_common.hpp b/include/boost/charconv/detail/dragonbox/dragonbox_common.hpp index a0f0facbd..6eed37e54 100644 --- a/include/boost/charconv/detail/dragonbox/dragonbox_common.hpp +++ b/include/boost/charconv/detail/dragonbox/dragonbox_common.hpp @@ -302,9 +302,11 @@ struct signed_significand_bits // Some simple utilities for constexpr computation. //////////////////////////////////////////////////////////////////////////////////////// -template -BOOST_CHARCONV_CXX14_CONSTEXPR Int compute_power(Int a, unsigned exp) noexcept +template +BOOST_CHARCONV_CXX14_CONSTEXPR Int compute_power(Int a, Int2 exp) noexcept { + BOOST_CHARCONV_ASSERT(exp >= 0); + Int res = 1; while (exp > 0) { From 60760eb20306272a16995fade5a1feed15fb6d11 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 13:22:03 -0400 Subject: [PATCH 4/9] Fix conversion warnings in tests --- test/limits.cpp | 2 +- test/test_128bit_emulation.cpp | 2 +- test/to_chars_sprintf.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/limits.cpp b/test/limits.cpp index 512f6a557..2612d27c7 100644 --- a/test/limits.cpp +++ b/test/limits.cpp @@ -43,7 +43,7 @@ std::ostream& operator<<( std::ostream& os, boost::int128_type v ) if( v >= 0 ) { - p = mini_to_chars( buffer, v ); + p = mini_to_chars( buffer, static_cast(v) ); } else { diff --git a/test/test_128bit_emulation.cpp b/test/test_128bit_emulation.cpp index 33c6123f0..4ad94c552 100644 --- a/test/test_128bit_emulation.cpp +++ b/test/test_128bit_emulation.cpp @@ -42,7 +42,7 @@ std::ostream& operator<<( std::ostream& os, boost::int128_type v ) if( v >= 0 ) { - p = mini_to_chars( buffer, v ); + p = mini_to_chars( buffer, static_cast(v) ); } else { diff --git a/test/to_chars_sprintf.cpp b/test/to_chars_sprintf.cpp index 2ccd445c5..95845d30f 100644 --- a/test/to_chars_sprintf.cpp +++ b/test/to_chars_sprintf.cpp @@ -408,7 +408,7 @@ template void test_sprintf_int16() for( int i = 0; i < N; ++i ) { - std::int16_t w = static_cast( rng() ); + std::int16_t w = static_cast( rng() ); test_sprintf( static_cast( w ) ); } } @@ -430,7 +430,7 @@ template void test_sprintf_int32() for( int i = 0; i < N; ++i ) { - std::int32_t w = static_cast( rng() ); + std::int32_t w = static_cast( rng() ); test_sprintf( static_cast( w ) ); } } @@ -452,7 +452,7 @@ template void test_sprintf_int64() for( int i = 0; i < N; ++i ) { - std::int64_t w = static_cast( rng() ); + std::int64_t w = static_cast( rng() ); test_sprintf( static_cast( w ) ); } } From e25ef28412e752c9ca4533b8206e2374ec0f2c4e Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 13:44:25 -0400 Subject: [PATCH 5/9] More test conversion fixes --- test/from_chars_float2.cpp | 6 +++--- test/roundtrip.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/from_chars_float2.cpp b/test/from_chars_float2.cpp index fa2cd14bf..4a2216b02 100644 --- a/test/from_chars_float2.cpp +++ b/test/from_chars_float2.cpp @@ -35,7 +35,7 @@ template void zero_extend_test() { for( int j = 1; j <= N; ++j ) { - std::snprintf( buffer, sizeof( buffer ), "%llu%se-%d", v, std::string( j, '0' ).c_str(), j ); + std::snprintf( buffer, sizeof( buffer ), "%llu%se-%d", v, std::string( (size_t)j, '0' ).c_str(), j ); T w; auto r2 = boost::charconv::from_chars( buffer, buffer + std::strlen( buffer ), w ); @@ -52,7 +52,7 @@ template void zero_extend_test() for( int j = 1; j <= N; ++j ) { - std::snprintf( buffer, sizeof( buffer ), "%llu0e-%s1", v, std::string( j, '0' ).c_str() ); + std::snprintf( buffer, sizeof( buffer ), "%llu0e-%s1", v, std::string( (size_t)j, '0' ).c_str() ); T w; auto r2 = boost::charconv::from_chars( buffer, buffer + std::strlen( buffer ), w ); @@ -86,7 +86,7 @@ template void zero_extend_test() { for( int j = 1; j <= N; ++j ) { - std::snprintf( buffer, sizeof( buffer ), "0.%s%llue%d", std::string( j, '0' ).c_str(), v, j ); + std::snprintf( buffer, sizeof( buffer ), "0.%s%llue%d", std::string( (size_t)j, '0' ).c_str(), v, j ); T w; auto r2 = boost::charconv::from_chars( buffer, buffer + std::strlen( buffer ), w ); diff --git a/test/roundtrip.cpp b/test/roundtrip.cpp index 5bf03476f..7a13b94ab 100644 --- a/test/roundtrip.cpp +++ b/test/roundtrip.cpp @@ -42,7 +42,7 @@ std::ostream& operator<<( std::ostream& os, boost::int128_type v ) if( v >= 0 ) { - p = mini_to_chars( buffer, v ); + p = mini_to_chars( buffer, static_cast(v) ); } else { @@ -125,7 +125,7 @@ template void test_roundtrip_int16( int base ) for( int i = 0; i < N; ++i ) { - std::int16_t w = static_cast( rng() ); + std::int16_t w = static_cast( rng() ); test_roundtrip( static_cast( w ), base ); } } @@ -147,7 +147,7 @@ template void test_roundtrip_int32( int base ) for( int i = 0; i < N; ++i ) { - std::int32_t w = static_cast( rng() ); + std::int32_t w = static_cast( rng() ); test_roundtrip( static_cast( w ), base ); } } @@ -169,7 +169,7 @@ template void test_roundtrip_int64( int base ) for( int i = 0; i < N; ++i ) { - std::int64_t w = static_cast( rng() ); + std::int64_t w = static_cast( rng() ); test_roundtrip( static_cast( w ), base ); } } @@ -196,7 +196,7 @@ template void test_roundtrip_int128( int base ) { for( int i = 0; i < N; ++i ) { - boost::int128_type w = static_cast( concatenate(rng(), rng()) ); + boost::int128_type w = static_cast( concatenate(rng(), rng()) ); test_roundtrip( static_cast( w ), base ); } } @@ -301,7 +301,7 @@ int64_t ToOrdinal(FPType x) /* Start with the number of representable numbers in preceding normal exponent ranges. */ - int64_t count = (exponent - MinimumExponent) * NumbersPerExponent; + auto count = static_cast(static_cast(exponent - MinimumExponent) * NumbersPerExponent); /* For subnormal numbers, fraction * radix ** SignificandDigits is the number of representable numbers from 0 to x. For normal numbers, From f557e45fc097183dcf3d2186046a4bd757610b1a Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 13:49:00 -0400 Subject: [PATCH 6/9] Fix floff conversions --- .../boost/charconv/detail/dragonbox/floff.hpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/include/boost/charconv/detail/dragonbox/floff.hpp b/include/boost/charconv/detail/dragonbox/floff.hpp index c169f8aea..a44712ddc 100644 --- a/include/boost/charconv/detail/dragonbox/floff.hpp +++ b/include/boost/charconv/detail/dragonbox/floff.hpp @@ -176,18 +176,18 @@ struct fixed_point_calculator switch (number_of_blocks) { case 3: - mul_result = umul128(blocks_ptr[2], multiplier); + mul_result = umul128(blocks_ptr[2], static_cast(multiplier)); carry = mul_result.high; BOOST_FALLTHROUGH; case 2: - mul_result = umul128(blocks_ptr[1], multiplier); + mul_result = umul128(blocks_ptr[1], static_cast(multiplier)); mul_result += carry; carry = mul_result.high; BOOST_FALLTHROUGH; case 1: - mul_result = umul128(blocks_ptr[0], multiplier); + mul_result = umul128(blocks_ptr[0], static_cast(multiplier)); mul_result += carry; return static_cast(mul_result.high); @@ -196,11 +196,11 @@ struct fixed_point_calculator } } - auto mul_result = umul128(blocks_ptr[number_of_blocks - 1], multiplier); + auto mul_result = umul128(blocks_ptr[number_of_blocks - 1], static_cast(multiplier)); auto carry = mul_result.high; for (std::size_t i = 1; i < number_of_blocks; ++i) { - mul_result = umul128(blocks_ptr[number_of_blocks - i - 1], multiplier); + mul_result = umul128(blocks_ptr[number_of_blocks - i - 1], static_cast(multiplier)); mul_result += carry; carry = mul_result.high; } @@ -361,7 +361,7 @@ BOOST_FORCEINLINE std::uint8_t load_extended_cache(CacheBlockType* blocks_ptr, i std::memset(blocks_ptr, 0, number_of_leading_zero_blocks * sizeof(CacheBlockType)); } - start_bit_index += number_of_leading_zero_blocks * static_cast(ExtendedCache::cache_bits_unit); + start_bit_index += static_cast(number_of_leading_zero_blocks * ExtendedCache::cache_bits_unit); const auto src_start_block_index = static_cast(static_cast(src_start_bit_index) / @@ -370,7 +370,7 @@ BOOST_FORCEINLINE std::uint8_t load_extended_cache(CacheBlockType* blocks_ptr, i const auto src_start_block_bit_index = src_start_block_index * static_cast(ExtendedCache::cache_bits_unit); - first_cache_block_index = src_start_block_index; + first_cache_block_index = static_cast(src_start_block_index); if (start_bit_index < src_start_block_bit_index) { @@ -405,7 +405,7 @@ BOOST_FORCEINLINE std::uint8_t load_extended_cache(CacheBlockType* blocks_ptr, i if (end_bit_index > src_end_bit_index) { const auto number_of_trailing_zero_blocks = - static_cast(end_bit_index - src_end_bit_index / ExtendedCache::cache_bits_unit); + static_cast(end_bit_index - src_end_bit_index) / ExtendedCache::cache_bits_unit; excessive_bits_to_right = static_cast(end_bit_index - src_end_bit_index) % static_cast(ExtendedCache::cache_bits_unit); @@ -493,8 +493,8 @@ BOOST_FORCEINLINE std::uint8_t load_extended_cache(CacheBlockType* blocks_ptr, i // To compute ceil(2^Q * x / D), we need to check if // 2^Q * x / D = 2^(Q + e + k - eta - 1) * 5^(k - eta) is an integer or not. if (k < ExtendedCache::segment_length || - e + k + cache_block_count * static_cast(ExtendedCache::cache_bits_unit) - - excessive_bits_to_right < + e + k + static_cast(cache_block_count * ExtendedCache::cache_bits_unit) - + static_cast(excessive_bits_to_right) < ExtendedCache::segment_length + 1) { blocks_ptr[cache_block_count - 1] += (CacheBlockType(1) << excessive_bits_to_right); BOOST_CHARCONV_ASSERT(blocks_ptr[cache_block_count - 1] != 0); @@ -1362,7 +1362,7 @@ BOOST_CHARCONV_SAFEBUFFERS char* floff(const double x, const int precision, char else { std::memcpy(buffer, "0.", 2); // NOLINT : Specifically not null-terminating - std::memset(buffer + 2, '0', precision); // NOLINT : Specifically not null-terminating + std::memset(buffer + 2, '0', static_cast(precision)); // NOLINT : Specifically not null-terminating std::memcpy(buffer + 2 + precision, "e+00", 2); // NOLINT : Specifically not null-terminating return buffer + precision + 4; } @@ -2240,7 +2240,7 @@ BOOST_CHARCONV_SAFEBUFFERS char* floff(const double x, const int precision, char // Convert subsegment into fixed-point fractional form where the // integer part is of one digit. The integer part is ignored. // 42949673 = ceil(2^32/10^2) - auto prod = subsegment * UINT64_C(42949673); + auto prod = static_cast(subsegment) * UINT64_C(42949673); if (remaining_digits == 1) { @@ -2278,7 +2278,7 @@ BOOST_CHARCONV_SAFEBUFFERS char* floff(const double x, const int precision, char // Convert subsegment into fixed-point fractional form where the // integer part is of two digits. The integer part is ignored. // 429496730 = ceil(2^32/10^1) - auto prod = subsegment * UINT64_C(429496730); + auto prod = static_cast(subsegment) * UINT64_C(429496730); prod = static_cast(prod) * UINT64_C(10); const auto next_digits = static_cast(prod >> 32); @@ -3736,7 +3736,7 @@ BOOST_CHARCONV_SAFEBUFFERS char* floff(const double x, const int precision, char fill_remaining_digits_with_0s: if (fmt != boost::charconv::chars_format::general) { - std::memset(buffer, '0', remaining_digits); + std::memset(buffer, '0', static_cast(remaining_digits)); buffer += remaining_digits; } @@ -3773,7 +3773,7 @@ BOOST_CHARCONV_SAFEBUFFERS char* floff(const double x, const int precision, char // 6554 = ceil(2^16 / 10) auto prod = static_cast(decimal_exponent) * UINT32_C(6554); auto d1 = prod >> 16; - prod = static_cast(prod) * UINT32_C(5); // * 10 + prod = static_cast(prod) * UINT16_C(5); // * 10 auto d2 = prod >> 15; // >> 16 print_2_digits(d1, buffer); print_1_digit(d2, buffer + 2); @@ -3781,7 +3781,7 @@ BOOST_CHARCONV_SAFEBUFFERS char* floff(const double x, const int precision, char } else { - print_2_digits(decimal_exponent, buffer); + print_2_digits(static_cast(decimal_exponent), buffer); buffer += 2; } @@ -3852,7 +3852,7 @@ BOOST_CHARCONV_SAFEBUFFERS char* floff(const double x, const int precision, char } ++*(first_9_pos - 1); - std::memset(first_9_pos, '0', buffer - first_9_pos); + std::memset(first_9_pos, '0', static_cast(buffer - first_9_pos)); goto insert_decimal_dot; } @@ -3866,7 +3866,7 @@ BOOST_CHARCONV_SAFEBUFFERS char* floff(const double x, const int precision, char // Nolint is applied to the following two calls since we know they are not supposed to be null terminated std::memcpy(buffer_starting_pos, "1.", 2); // NOLINT - std::memset(buffer_starting_pos + 2, '0', buffer - buffer_starting_pos - 2); // NOLINT + std::memset(buffer_starting_pos + 2, '0', static_cast(buffer - buffer_starting_pos - 2)); // NOLINT goto print_exponent_and_return; } From a0c594ea18f4eef9e0ed4cadd99b1a6ddf57ef27 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 14:26:56 -0400 Subject: [PATCH 7/9] Ignore sign warning from parameter pack --- .../boost/charconv/detail/dragonbox/floff.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/boost/charconv/detail/dragonbox/floff.hpp b/include/boost/charconv/detail/dragonbox/floff.hpp index a44712ddc..d289ec750 100644 --- a/include/boost/charconv/detail/dragonbox/floff.hpp +++ b/include/boost/charconv/detail/dragonbox/floff.hpp @@ -545,6 +545,17 @@ BOOST_INLINE_VARIABLE constexpr uconst<9> uconst9; BOOST_INLINE_VARIABLE constexpr uconst<14> uconst14; BOOST_INLINE_VARIABLE constexpr uconst<16> uconst16; +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wsign-conversion" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsign-conversion" +#elif defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4365 4267) +#endif + template struct uint_with_known_number_of_digits; @@ -647,6 +658,14 @@ static BOOST_FORCEINLINE bool check_rounding_condition_subsegment_boundary_with_ ((current_digits & 1) != 0 || has_further_digits(args...)); } +#ifdef __clang__ +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#elif defined(BOOST_MSVC) +# pragma warning(pop) +#endif + #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable: 4307) // MSVC 14.1 emits warnings for uint64_t constants From 7aeffc808bafaea345c13516c490a992c62469dc Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 14:32:51 -0400 Subject: [PATCH 8/9] Fix value to unsigned_value conversion --- include/boost/charconv/detail/to_chars_integer_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/charconv/detail/to_chars_integer_impl.hpp b/include/boost/charconv/detail/to_chars_integer_impl.hpp index d775efaa1..26e2fa158 100644 --- a/include/boost/charconv/detail/to_chars_integer_impl.hpp +++ b/include/boost/charconv/detail/to_chars_integer_impl.hpp @@ -111,7 +111,7 @@ BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars_integer_impl(char* first, char } else { - unsigned_value = value; + unsigned_value = static_cast(value); } // If the type is less than 32 bits we can use this without change From 38cfa0e3a5fa72f02576e9cba84e0c0cccd51dff Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Mon, 14 Aug 2023 15:01:43 -0400 Subject: [PATCH 9/9] Fix warning for MSVC --- include/boost/charconv/detail/dragonbox/floff.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/charconv/detail/dragonbox/floff.hpp b/include/boost/charconv/detail/dragonbox/floff.hpp index d289ec750..ce183be3c 100644 --- a/include/boost/charconv/detail/dragonbox/floff.hpp +++ b/include/boost/charconv/detail/dragonbox/floff.hpp @@ -404,7 +404,7 @@ BOOST_FORCEINLINE std::uint8_t load_extended_cache(CacheBlockType* blocks_ptr, i // If the request window goes further than the right boundary of the source window, if (end_bit_index > src_end_bit_index) { - const auto number_of_trailing_zero_blocks = + const std::uint8_t number_of_trailing_zero_blocks = static_cast(end_bit_index - src_end_bit_index) / ExtendedCache::cache_bits_unit; excessive_bits_to_right = static_cast(end_bit_index - src_end_bit_index) % static_cast(ExtendedCache::cache_bits_unit);