diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 9abe7c4f..ee4801b5 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -696,7 +696,7 @@ inline int to_nonnegative_int(T value, int upper) { template ::value)> inline T mod(T x, int y) { - return x % y; + return x % static_cast(y); } template ::value)> inline T mod(T x, int y) { @@ -793,11 +793,7 @@ struct chrono_formatter { explicit chrono_formatter(FormatContext& ctx, OutputIt o, std::chrono::duration d) - : context(ctx), out(o), val(d.count()), negative(false) { - if (d.count() < 0) { - val = 0 - val; - negative = true; - } + : context(ctx), out(o), val(static_cast(std::abs(d.count()))), negative(d.count() < 0) { // this may overflow and/or the result may not fit in the // target type. @@ -1023,8 +1019,8 @@ struct formatter, Char> { void on_error(const char* msg) { FMT_THROW(format_error(msg)); } void on_fill(Char fill) { f.specs.fill[0] = fill; } void on_align(align_t align) { f.specs.align = align; } - void on_width(unsigned width) { f.specs.width = width; } - void on_precision(unsigned _precision) { f.precision = _precision; } + void on_width(int width) { f.specs.width = width; } + void on_precision(int _precision) { f.precision = _precision; } void end_precision() {} template void on_dynamic_width(Id arg_id) { diff --git a/include/fmt/compile.h b/include/fmt/compile.h index f65f5a74..aa30b726 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -116,11 +116,11 @@ class format_string_compiler : public error_handler { } FMT_CONSTEXPR void on_arg_id() { - part_ = part::make_arg_index(parse_context_.next_arg_id()); + part_ = part::make_arg_index(static_cast(parse_context_.next_arg_id())); } FMT_CONSTEXPR void on_arg_id(unsigned id) { - parse_context_.check_arg_id(id); + parse_context_.check_arg_id(static_cast(id)); part_ = part::make_arg_index(id); } @@ -141,7 +141,7 @@ class format_string_compiler : public error_handler { auto it = parse_format_specs(begin, end, handler); if (*it != '}') on_error("missing '}' in format string"); repl.arg_id = part_.part_kind == part::kind::arg_index - ? arg_ref(part_.val.arg_index) + ? arg_ref(static_cast(part_.val.arg_index)) : arg_ref(part_.val.str); auto part = part::make_replacement(repl); part.arg_id_end = begin; diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 646e328f..a7bdb9a2 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -19,6 +19,7 @@ #include #include // for std::memmove #include +#include // for std::uninitialized_fill_n #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) # include #endif @@ -478,8 +479,8 @@ FMT_FUNC fp get_cached_power(int min_exponent, int& pow10_exponent) { const uint64_t one_over_log2_10 = 0x4d104d42; // round(pow(2, 32) / log2(10)) int index = static_cast( static_cast( - (min_exponent + fp::significand_size - 1) * one_over_log2_10 + - ((uint64_t(1) << 32) - 1) // ceil + static_cast(min_exponent + fp::significand_size - 1) * one_over_log2_10 + + ((1ULL << 32) - 1) // ceil ) >> 32 // arithmetic shift ); @@ -527,14 +528,14 @@ class bigint { friend struct formatter; - void subtract_bigits(int index, bigit other, bigit& borrow) { + void subtract_bigits(size_t index, bigit other, bigit& borrow) { auto result = static_cast(bigits_[index]) - other - borrow; bigits_[index] = static_cast(result); borrow = static_cast(result >> (bigit_bits * 2 - 1)); } void remove_leading_zeros() { - int num_bigits = static_cast(bigits_.size()) - 1; + size_t num_bigits = bigits_.size() - 1; while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits; bigits_.resize(num_bigits + 1); } @@ -544,8 +545,8 @@ class bigint { FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints"); FMT_ASSERT(compare(*this, other) >= 0, ""); bigit borrow = 0; - int i = other.exp_ - exp_; - for (int j = 0, n = static_cast(other.bigits_.size()); j != n; + size_t i = static_cast(other.exp_ - exp_); + for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) { subtract_bigits(i, other.bigits_[j], borrow); } @@ -597,7 +598,7 @@ class bigint { } void assign(uint64_t n) { - int num_bigits = 0; + size_t num_bigits = 0; do { bigits_[num_bigits++] = n & ~bigit(0); n >>= bigit_bits; @@ -633,11 +634,11 @@ class bigint { int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits(); if (num_lhs_bigits != num_rhs_bigits) return num_lhs_bigits > num_rhs_bigits ? 1 : -1; - int i = static_cast(lhs.bigits_.size()) - 1; - int j = static_cast(rhs.bigits_.size()) - 1; - int end = i - j; - if (end < 0) end = 0; - for (; i >= end; --i, --j) { + size_t i = lhs.bigits_.size(); + size_t j = rhs.bigits_.size(); + while ((i != 0) && (j != 0)) { + -- i; + -- j; bigit lhs_bigit = lhs.bigits_[i], rhs_bigit = rhs.bigits_[j]; if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1; } @@ -653,7 +654,7 @@ class bigint { if (max_lhs_bigits + 1 < num_rhs_bigits) return -1; if (max_lhs_bigits > num_rhs_bigits) return 1; auto get_bigit = [](const bigint& n, int i) -> bigit { - return i >= n.exp_ && i < n.num_bigits() ? n.bigits_[i - n.exp_] : 0; + return i >= n.exp_ && i < n.num_bigits() ? n.bigits_[static_cast(i - n.exp_)] : 0; }; double_bigit borrow = 0; int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_); @@ -691,25 +692,25 @@ class bigint { void square() { basic_memory_buffer n(std::move(bigits_)); - int num_bigits = static_cast(bigits_.size()); - int num_result_bigits = 2 * num_bigits; + size_t num_bigits = bigits_.size(); + size_t num_result_bigits = 2 * num_bigits; bigits_.resize(num_result_bigits); using accumulator_t = conditional_t; auto sum = accumulator_t(); - for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) { + for (size_t bigit_index = 0; bigit_index < num_bigits; ++bigit_index) { // Compute bigit at position bigit_index of the result by adding // cross-product terms n[i] * n[j] such that i + j == bigit_index. - for (int i = 0, j = bigit_index; j >= 0; ++i, --j) { + for (size_t i = 0; i <= bigit_index; ++ i) { // Most terms are multiplied twice which can be optimized in the future. - sum += static_cast(n[i]) * n[j]; + sum += static_cast(n[i]) * n[bigit_index - i]; } bigits_[bigit_index] = static_cast(sum); sum >>= bits::value; // Compute the carry. } // Do the same for the top half. - for (int bigit_index = num_bigits; bigit_index < num_result_bigits; + for (size_t bigit_index = num_bigits; bigit_index < num_result_bigits; ++bigit_index) { - for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) + for (size_t j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) sum += static_cast(n[i++]) * n[j--]; bigits_[bigit_index] = static_cast(sum); sum >>= bits::value; @@ -724,16 +725,15 @@ class bigint { int divmod_assign(const bigint& divisor) { FMT_ASSERT(this != &divisor, ""); if (compare(*this, divisor) < 0) return 0; - int num_bigits = static_cast(bigits_.size()); + size_t num_bigits = bigits_.size(); FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1] != 0, ""); - int exp_difference = exp_ - divisor.exp_; - if (exp_difference > 0) { + if (exp_ > divisor.exp_) { + const auto exp_difference = static_cast(exp_ - divisor.exp_); // Align bigints by adding trailing zeros to simplify subtraction. bigits_.resize(num_bigits + exp_difference); - for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) - bigits_[j] = bigits_[i]; + std::memmove(&bigits_[exp_difference], &bigits_[0], num_bigits * sizeof(bigits_[0])); std::uninitialized_fill_n(bigits_.data(), exp_difference, 0); - exp_ -= exp_difference; + exp_ = divisor.exp_; } int quotient = 0; do { @@ -1008,7 +1008,7 @@ void fallback_format(Double d, buffer& buf, int& exp10) { if (!upper) upper = &lower; // Invariant: value == (numerator / denominator) * pow(10, exp10). bool even = (value.f & 1) == 0; - int num_digits = 0; + size_t num_digits = 0; char* data = buf.data(); for (;;) { int digit = numerator.divmod_assign(denominator); @@ -1026,7 +1026,7 @@ void fallback_format(Double d, buffer& buf, int& exp10) { ++data[num_digits - 1]; } buf.resize(num_digits); - exp10 -= num_digits - 1; + exp10 -= static_cast(num_digits - 1); return; } numerator *= 10; @@ -1068,7 +1068,7 @@ int format_float(T value, int precision, float_specs specs, buffer& buf) { fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed}; if (grisu_gen_digits(normalized, 1, exp, handler) == digits::error) return snprintf_float(value, precision, specs, buf); - int num_digits = handler.size; + auto num_digits = static_cast(handler.size); if (!fixed) { // Remove trailing zeros. while (num_digits > 0 && buf[num_digits - 1] == '0') { @@ -1076,7 +1076,7 @@ int format_float(T value, int precision, float_specs specs, buffer& buf) { ++exp; } } - buf.resize(to_unsigned(num_digits)); + buf.resize(num_digits); } else { fp fp_value; auto boundaries = specs.binary32 @@ -1175,10 +1175,10 @@ int snprintf_float(T value, int precision, float_specs specs, do { --p; } while (is_digit(*p)); - int fraction_size = static_cast(end - p - 1); - std::memmove(p, p + 1, fraction_size); + auto fraction_size = end - p - 1; + std::memmove(p, p + 1, static_cast(fraction_size)); buf.resize(size - 1); - return -fraction_size; + return static_cast(-fraction_size); } if (specs.format == float_format::hex) { buf.resize(size + offset); @@ -1203,10 +1203,10 @@ int snprintf_float(T value, int precision, float_specs specs, auto fraction_end = exp_pos - 1; while (*fraction_end == '0') --fraction_end; // Move the fractional part left to get rid of the decimal point. - int fraction_size = static_cast(fraction_end - begin - 1); + const auto fraction_size = static_cast(fraction_end - begin - 1); std::memmove(begin + 1, begin + 2, fraction_size); buf.resize(fraction_size + offset + 1); - exp -= fraction_size; + exp -= static_cast(fraction_size); } return exp; } diff --git a/include/fmt/format.h b/include/fmt/format.h index e57b2b2c..2ada7e15 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1216,7 +1216,7 @@ int snprintf_float(T value, int precision, float_specs specs, buffer& buf); template T promote_float(T value) { return value; } -inline double promote_float(float value) { return value; } +inline double promote_float(float value) { return static_cast(value); } template FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) { @@ -2599,11 +2599,11 @@ class format_string_checker { FMT_CONSTEXPR void on_text(const Char*, const Char*) {} FMT_CONSTEXPR void on_arg_id() { - arg_id_ = context_.next_arg_id(); + arg_id_ = static_cast(context_.next_arg_id()); check_arg_id(); } FMT_CONSTEXPR void on_arg_id(int id) { - arg_id_ = id; + arg_id_ = static_cast(id); context_.check_arg_id(id); check_arg_id(); } diff --git a/include/fmt/printf.h b/include/fmt/printf.h index cdbb65e6..2eb177c7 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -355,7 +355,7 @@ template class basic_printf_context { OutputIt out() { return out_; } void advance_to(OutputIt it) { out_ = it; } - format_arg arg(unsigned id) const { return args_.get(id); } + format_arg arg(int id) const { return args_.get(id); } basic_format_parse_context& parse_context() { return parse_ctx_; } @@ -399,10 +399,10 @@ template typename basic_printf_context::format_arg basic_printf_context::get_arg(unsigned arg_index) { if (arg_index == internal::max_value()) - arg_index = parse_ctx_.next_arg_id(); + arg_index = static_cast(parse_ctx_.next_arg_id()); else - parse_ctx_.check_arg_id(--arg_index); - return internal::get_arg(*this, arg_index); + parse_ctx_.check_arg_id(static_cast(--arg_index)); + return internal::get_arg(*this, static_cast(arg_index)); } template @@ -414,10 +414,10 @@ unsigned basic_printf_context::parse_header( // Parse an argument index (if followed by '$') or a width possibly // preceded with '0' flag(s). internal::error_handler eh; - unsigned value = parse_nonnegative_int(it, end, eh); + int value = parse_nonnegative_int(it, end, eh); if (it != end && *it == '$') { // value is an argument index ++it; - arg_index = value; + arg_index = static_cast(value); } else { if (c == '0') specs.fill[0] = '0'; if (value != 0) { @@ -436,8 +436,8 @@ unsigned basic_printf_context::parse_header( specs.width = parse_nonnegative_int(it, end, eh); } else if (*it == '*') { ++it; - specs.width = visit_format_arg( - internal::printf_width_handler(specs), get_arg()); + specs.width = static_cast(visit_format_arg( + internal::printf_width_handler(specs), get_arg())); } } return arg_index; @@ -473,11 +473,11 @@ OutputIt basic_printf_context::format() { c = it != end ? *it : 0; if ('0' <= c && c <= '9') { internal::error_handler eh; - specs.precision = static_cast(parse_nonnegative_int(it, end, eh)); + specs.precision = parse_nonnegative_int(it, end, eh); } else if (c == '*') { ++it; specs.precision = - visit_format_arg(internal::printf_precision_handler(), get_arg()); + static_cast(visit_format_arg(internal::printf_precision_handler(), get_arg())); } else { specs.precision = 0; } diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc index cdba7699..1dcc8be8 100644 --- a/test/format-impl-test.cc +++ b/test/format-impl-test.cc @@ -224,19 +224,23 @@ TEST(FPTest, Normalize) { } TEST(FPTest, ComputeFloatBoundaries) { + /* + * TODO: investigate why changing type of x to 'float' and removing the + * static casts causes the test to fail. + */ struct { double x, lower, upper; } tests[] = { // regular - {1.5f, 1.4999999403953552, 1.5000000596046448}, + {static_cast(1.5f), 1.4999999403953552, 1.5000000596046448}, // boundary - {1.0f, 0.9999999701976776, 1.0000000596046448}, + {static_cast(1.0f), 0.9999999701976776, 1.0000000596046448}, // min normal - {1.1754944e-38f, 1.1754942807573643e-38, 1.1754944208872107e-38}, + {static_cast(1.1754944e-38f), 1.1754942807573643e-38, 1.1754944208872107e-38}, // max subnormal - {1.1754942e-38f, 1.1754941406275179e-38, 1.1754942807573643e-38}, + {static_cast(1.1754942e-38f), 1.1754941406275179e-38, 1.1754942807573643e-38}, // min subnormal - {1e-45f, 7.006492321624085e-46, 2.1019476964872256e-45}, + {static_cast(1e-45f), 7.006492321624085e-46, 2.1019476964872256e-45}, }; for (auto test : tests) { fp vlower = normalize(fp(test.lower)); @@ -277,7 +281,7 @@ TEST(FPTest, GetRoundDirection) { EXPECT_EQ(fmt::internal::up, get_round_direction(100, 51, 0)); EXPECT_EQ(fmt::internal::down, get_round_direction(100, 40, 10)); EXPECT_EQ(fmt::internal::up, get_round_direction(100, 60, 10)); - for (int i = 41; i < 60; ++i) + for (size_t i = 41; i < 60; ++i) EXPECT_EQ(fmt::internal::unknown, get_round_direction(100, i, 10)); uint64_t max = max_value(); EXPECT_THROW(get_round_direction(100, 100, 0), assertion_failure); diff --git a/test/format-test.cc b/test/format-test.cc index e747a407..57f9e15a 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1851,7 +1851,7 @@ TEST(FormatTest, Dynamic) { std::string result = fmt::vformat( "{} and {} and {}", fmt::basic_format_args( - args.data(), static_cast(args.size()))); + args.data(), static_cast(args.size()))); EXPECT_EQ("42 and abc1 and 1.5", result); } diff --git a/test/scan.h b/test/scan.h index 50ac0941..061c5449 100644 --- a/test/scan.h +++ b/test/scan.h @@ -6,6 +6,7 @@ // For the license information refer to format.h. #include +#include #include "fmt/format.h" @@ -135,21 +136,20 @@ struct scan_handler : error_handler { char c = *it++; if (c < '0' || c > '9') on_error("invalid input"); // TODO: check overflow - value = value * 10 + (c - '0'); + value = value * 10 + static_cast(c - '0'); } scan_ctx_.advance_to(it); return value; } template T read_int() { - T value = 0; auto it = scan_ctx_.begin(), end = scan_ctx_.end(); bool negative = it != end && *it == '-'; if (negative) ++it; scan_ctx_.advance_to(it); - value = read_uint::type>(); - if (negative) value = -value; - return value; + const auto value = read_uint::type>(); + if (negative) return -static_cast(value); + return static_cast(value); } public: @@ -159,7 +159,7 @@ struct scan_handler : error_handler { const char* pos() const { return scan_ctx_.begin(); } void on_text(const char* begin, const char* end) { - auto size = end - begin; + auto size = static_cast(end - begin); auto it = scan_ctx_.begin(); if (it + size > scan_ctx_.end() || !std::equal(begin, end, make_checked(it, size))) { @@ -197,7 +197,7 @@ struct scan_handler : error_handler { case scan_type::string_view_type: { auto s = it; while (it != end && *it != ' ') ++it; - *arg_.string_view = fmt::string_view(s, it - s); + *arg_.string_view = fmt::string_view(s, static_cast(it - s)); scan_ctx_.advance_to(it); break; } diff --git a/test/std-format-test.cc b/test/std-format-test.cc index a95f244e..b0c6abf7 100644 --- a/test/std-format-test.cc +++ b/test/std-format-test.cc @@ -110,7 +110,7 @@ template <> struct std::formatter { char c = get_char(); if (!isdigit(c) || (++iter, get_char()) != '}') throw format_error("invalid format"); - width_arg_id = c - '0'; + width_arg_id = static_cast(c - '0'); ctx.check_arg_id(width_arg_id); return ++iter; }