mirror of
https://github.com/fmtlib/fmt.git
synced 2025-04-10 03:44:32 +00:00
Fix conversion warnings (#989)
* Fix sign conversion warnings * Ignore unused local typedefs * Remove cast reported as useless on GCC * Remove warning on unused variable * Enable conversion warning checking for pedantic build * Fix sign-conversion warnings in headers
This commit is contained in:
parent
77a7244804
commit
0bbdca5b8b
@ -74,10 +74,11 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|||||||
-Wcast-align -Wnon-virtual-dtor
|
-Wcast-align -Wnon-virtual-dtor
|
||||||
-Wctor-dtor-privacy -Wdisabled-optimization
|
-Wctor-dtor-privacy -Wdisabled-optimization
|
||||||
-Winvalid-pch -Woverloaded-virtual
|
-Winvalid-pch -Woverloaded-virtual
|
||||||
-Wno-ctor-dtor-privacy -Wno-dangling-else
|
-Wconversion
|
||||||
-Wno-format-nonliteral -Wno-sign-conversion -Wno-shadow)
|
-Wno-ctor-dtor-privacy -Wno-format-nonliteral -Wno-shadow)
|
||||||
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
|
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
|
||||||
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept)
|
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept
|
||||||
|
-Wno-dangling-else -Wno-unused-local-typedefs)
|
||||||
endif ()
|
endif ()
|
||||||
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
||||||
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wdouble-promotion
|
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wdouble-promotion
|
||||||
@ -92,7 +93,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic)
|
set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic -Wconversion -Wno-sign-conversion)
|
||||||
check_cxx_compiler_flag(-Wzero-as-null-pointer-constant HAS_NULLPTR_WARNING)
|
check_cxx_compiler_flag(-Wzero-as-null-pointer-constant HAS_NULLPTR_WARNING)
|
||||||
if (HAS_NULLPTR_WARNING)
|
if (HAS_NULLPTR_WARNING)
|
||||||
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS}
|
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS}
|
||||||
|
@ -250,7 +250,7 @@ struct chrono_formatter {
|
|||||||
void write(int value, int width) {
|
void write(int value, int width) {
|
||||||
typedef typename int_traits<int>::main_type main_type;
|
typedef typename int_traits<int>::main_type main_type;
|
||||||
main_type n = to_unsigned(value);
|
main_type n = to_unsigned(value);
|
||||||
int num_digits = static_cast<int>(internal::count_digits(n));
|
int num_digits = internal::count_digits(n);
|
||||||
if (width > num_digits)
|
if (width > num_digits)
|
||||||
out = std::fill_n(out, width - num_digits, '0');
|
out = std::fill_n(out, width - num_digits, '0');
|
||||||
out = format_decimal<char_type>(out, n, num_digits);
|
out = format_decimal<char_type>(out, n, num_digits);
|
||||||
@ -415,7 +415,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
|||||||
if (begin == end) return begin;
|
if (begin == end) return begin;
|
||||||
begin = internal::parse_width(begin, end, handler);
|
begin = internal::parse_width(begin, end, handler);
|
||||||
end = parse_chrono_format(begin, end, internal::chrono_format_checker());
|
end = parse_chrono_format(begin, end, internal::chrono_format_checker());
|
||||||
format_str = basic_string_view<Char>(&*begin, end - begin);
|
format_str = basic_string_view<Char>(&*begin, internal::to_unsigned(end - begin));
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,8 @@ struct color_type {
|
|||||||
}
|
}
|
||||||
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT
|
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT
|
||||||
: is_rgb(true), value{} {
|
: is_rgb(true), value{} {
|
||||||
value.rgb_color = (rgb_color.r << 16) + (rgb_color.g << 8) + rgb_color.b;
|
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16)
|
||||||
|
| (static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b;
|
||||||
}
|
}
|
||||||
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT
|
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT
|
||||||
: is_rgb(), value{} {
|
: is_rgb(), value{} {
|
||||||
@ -395,22 +396,22 @@ struct ansi_color_escape {
|
|||||||
// sequence.
|
// sequence.
|
||||||
if (!text_color.is_rgb) {
|
if (!text_color.is_rgb) {
|
||||||
bool is_background = esc == internal::data::BACKGROUND_COLOR;
|
bool is_background = esc == internal::data::BACKGROUND_COLOR;
|
||||||
uint8_t value = text_color.value.term_color;
|
uint32_t value = text_color.value.term_color;
|
||||||
// Background ASCII codes are the same as the foreground ones but with
|
// Background ASCII codes are the same as the foreground ones but with
|
||||||
// 10 more.
|
// 10 more.
|
||||||
if (is_background)
|
if (is_background)
|
||||||
value += 10;
|
value += 10u;
|
||||||
|
|
||||||
std::size_t index = 0;
|
std::size_t index = 0;
|
||||||
buffer[index++] = static_cast<Char>('\x1b');
|
buffer[index++] = static_cast<Char>('\x1b');
|
||||||
buffer[index++] = static_cast<Char>('[');
|
buffer[index++] = static_cast<Char>('[');
|
||||||
|
|
||||||
if (value >= 100) {
|
if (value >= 100u) {
|
||||||
buffer[index++] = static_cast<Char>('1');
|
buffer[index++] = static_cast<Char>('1');
|
||||||
value %= 100;
|
value %= 100u;
|
||||||
}
|
}
|
||||||
buffer[index++] = static_cast<Char>('0' + value / 10);
|
buffer[index++] = static_cast<Char>('0' + value / 10u);
|
||||||
buffer[index++] = static_cast<Char>('0' + value % 10);
|
buffer[index++] = static_cast<Char>('0' + value % 10u);
|
||||||
|
|
||||||
buffer[index++] = static_cast<Char>('m');
|
buffer[index++] = static_cast<Char>('m');
|
||||||
buffer[index++] = static_cast<Char>('\0');
|
buffer[index++] = static_cast<Char>('\0');
|
||||||
@ -452,7 +453,7 @@ struct ansi_color_escape {
|
|||||||
FMT_CONSTEXPR operator const Char *() const FMT_NOEXCEPT { return buffer; }
|
FMT_CONSTEXPR operator const Char *() const FMT_NOEXCEPT { return buffer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Char buffer[7 + 3 * 4 + 1];
|
Char buffer[7u + 3u * 4u + 1u];
|
||||||
|
|
||||||
static FMT_CONSTEXPR void to_esc(uint8_t c, Char *out,
|
static FMT_CONSTEXPR void to_esc(uint8_t c, Char *out,
|
||||||
char delimiter) FMT_NOEXCEPT {
|
char delimiter) FMT_NOEXCEPT {
|
||||||
|
@ -172,7 +172,7 @@ void format_error_code(internal::buffer &out, int error_code,
|
|||||||
abs_value = 0 - abs_value;
|
abs_value = 0 - abs_value;
|
||||||
++error_code_size;
|
++error_code_size;
|
||||||
}
|
}
|
||||||
error_code_size += internal::count_digits(abs_value);
|
error_code_size += internal::to_unsigned(internal::count_digits(abs_value));
|
||||||
writer w(out);
|
writer w(out);
|
||||||
if (message.size() <= inline_buffer_size - error_code_size) {
|
if (message.size() <= inline_buffer_size - error_code_size) {
|
||||||
w.write(message);
|
w.write(message);
|
||||||
@ -464,14 +464,14 @@ FMT_FUNC fp get_cached_power(int min_exponent, int &pow10_exponent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC bool grisu2_round(
|
FMT_FUNC bool grisu2_round(
|
||||||
char *buf, ptrdiff_t &size, size_t max_digits, uint64_t delta,
|
char *buf, int &size, int max_digits, uint64_t delta,
|
||||||
uint64_t remainder, uint64_t exp, uint64_t diff, int &exp10) {
|
uint64_t remainder, uint64_t exp, uint64_t diff, int &exp10) {
|
||||||
while (remainder < diff && delta - remainder >= exp &&
|
while (remainder < diff && delta - remainder >= exp &&
|
||||||
(remainder + exp < diff || diff - remainder > remainder + exp - diff)) {
|
(remainder + exp < diff || diff - remainder > remainder + exp - diff)) {
|
||||||
--buf[size - 1];
|
--buf[size - 1];
|
||||||
remainder += exp;
|
remainder += exp;
|
||||||
}
|
}
|
||||||
if (size > static_cast<ptrdiff_t>(max_digits)) {
|
if (size > max_digits) {
|
||||||
--size;
|
--size;
|
||||||
++exp10;
|
++exp10;
|
||||||
if (buf[size] >= '5')
|
if (buf[size] >= '5')
|
||||||
@ -482,8 +482,8 @@ FMT_FUNC bool grisu2_round(
|
|||||||
|
|
||||||
// Generates output using Grisu2 digit-gen algorithm.
|
// Generates output using Grisu2 digit-gen algorithm.
|
||||||
FMT_FUNC bool grisu2_gen_digits(
|
FMT_FUNC bool grisu2_gen_digits(
|
||||||
char *buf, ptrdiff_t &size, uint32_t hi, uint64_t lo, int &exp,
|
char *buf, int &size, uint32_t hi, uint64_t lo, int &exp,
|
||||||
uint64_t delta, const fp &one, const fp &diff, size_t max_digits) {
|
uint64_t delta, const fp &one, const fp &diff, int max_digits) {
|
||||||
// Generate digits for the most significant part (hi).
|
// Generate digits for the most significant part (hi).
|
||||||
while (exp > 0) {
|
while (exp > 0) {
|
||||||
uint32_t digit = 0;
|
uint32_t digit = 0;
|
||||||
@ -507,7 +507,7 @@ FMT_FUNC bool grisu2_gen_digits(
|
|||||||
buf[size++] = static_cast<char>('0' + digit);
|
buf[size++] = static_cast<char>('0' + digit);
|
||||||
--exp;
|
--exp;
|
||||||
uint64_t remainder = (static_cast<uint64_t>(hi) << -one.e) + lo;
|
uint64_t remainder = (static_cast<uint64_t>(hi) << -one.e) + lo;
|
||||||
if (remainder <= delta || size > static_cast<ptrdiff_t>(max_digits)) {
|
if (remainder <= delta || size > max_digits) {
|
||||||
return grisu2_round(
|
return grisu2_round(
|
||||||
buf, size, max_digits, delta, remainder,
|
buf, size, max_digits, delta, remainder,
|
||||||
static_cast<uint64_t>(data::POWERS_OF_10_32[exp]) << -one.e,
|
static_cast<uint64_t>(data::POWERS_OF_10_32[exp]) << -one.e,
|
||||||
@ -523,7 +523,7 @@ FMT_FUNC bool grisu2_gen_digits(
|
|||||||
buf[size++] = static_cast<char>('0' + digit);
|
buf[size++] = static_cast<char>('0' + digit);
|
||||||
lo &= one.f - 1;
|
lo &= one.f - 1;
|
||||||
--exp;
|
--exp;
|
||||||
if (lo < delta || size > static_cast<ptrdiff_t>(max_digits)) {
|
if (lo < delta || size > max_digits) {
|
||||||
return grisu2_round(buf, size, max_digits, delta, lo, one.f,
|
return grisu2_round(buf, size, max_digits, delta, lo, one.f,
|
||||||
diff.f * data::POWERS_OF_10_32[-exp], exp);
|
diff.f * data::POWERS_OF_10_32[-exp], exp);
|
||||||
}
|
}
|
||||||
@ -704,7 +704,7 @@ FMT_FUNC gen_digits_params process_specs(const core_format_specs &specs,
|
|||||||
++num_digits;
|
++num_digits;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
params.num_digits = to_unsigned(num_digits);
|
params.num_digits = num_digits;
|
||||||
char_counter counter{num_digits};
|
char_counter counter{num_digits};
|
||||||
grisu2_prettify(params, params.num_digits, exp - num_digits, counter);
|
grisu2_prettify(params, params.num_digits, exp - num_digits, counter);
|
||||||
buf.resize(to_unsigned(counter.size));
|
buf.resize(to_unsigned(counter.size));
|
||||||
@ -739,7 +739,7 @@ FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
|
|||||||
// hi (p1 in Grisu) contains the most significant digits of scaled_upper.
|
// hi (p1 in Grisu) contains the most significant digits of scaled_upper.
|
||||||
// hi = floor(upper / one).
|
// hi = floor(upper / one).
|
||||||
uint32_t hi = static_cast<uint32_t>(upper.f >> -one.e);
|
uint32_t hi = static_cast<uint32_t>(upper.f >> -one.e);
|
||||||
int exp = static_cast<int>(count_digits(hi)); // kappa in Grisu.
|
int exp = count_digits(hi); // kappa in Grisu.
|
||||||
gen_digits_params params = process_specs(specs, cached_exp + exp, buf);
|
gen_digits_params params = process_specs(specs, cached_exp + exp, buf);
|
||||||
fp_value.normalize();
|
fp_value.normalize();
|
||||||
fp scaled_value = fp_value * cached_pow;
|
fp scaled_value = fp_value * cached_pow;
|
||||||
@ -750,7 +750,7 @@ FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
|
|||||||
// lo (p2 in Grisu) contains the least significants digits of scaled_upper.
|
// lo (p2 in Grisu) contains the least significants digits of scaled_upper.
|
||||||
// lo = supper % one.
|
// lo = supper % one.
|
||||||
uint64_t lo = upper.f & (one.f - 1);
|
uint64_t lo = upper.f & (one.f - 1);
|
||||||
ptrdiff_t size = 0;
|
int size = 0;
|
||||||
if (!grisu2_gen_digits(buf.data(), size, hi, lo, exp, delta, one, diff,
|
if (!grisu2_gen_digits(buf.data(), size, hi, lo, exp, delta, one, diff,
|
||||||
params.num_digits)) {
|
params.num_digits)) {
|
||||||
buf.clear();
|
buf.clear();
|
||||||
|
@ -66,10 +66,6 @@
|
|||||||
// many valid cases.
|
// many valid cases.
|
||||||
# pragma GCC diagnostic ignored "-Wshadow"
|
# pragma GCC diagnostic ignored "-Wshadow"
|
||||||
|
|
||||||
// Disable the warning about implicit conversions that may change the sign of
|
|
||||||
// an integer; silencing it otherwise would require many explicit casts.
|
|
||||||
# pragma GCC diagnostic ignored "-Wsign-conversion"
|
|
||||||
|
|
||||||
// Disable the warning about nonliteral format strings because we construct
|
// Disable the warning about nonliteral format strings because we construct
|
||||||
// them dynamically when falling back to snprintf for FP formatting.
|
// them dynamically when falling back to snprintf for FP formatting.
|
||||||
# pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
# pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
@ -770,16 +766,16 @@ typedef basic_data<> data;
|
|||||||
#ifdef FMT_BUILTIN_CLZLL
|
#ifdef FMT_BUILTIN_CLZLL
|
||||||
// Returns the number of decimal digits in n. Leading zeros are not counted
|
// Returns the number of decimal digits in n. Leading zeros are not counted
|
||||||
// except for n == 0 in which case count_digits returns 1.
|
// except for n == 0 in which case count_digits returns 1.
|
||||||
inline unsigned count_digits(uint64_t n) {
|
inline int count_digits(uint64_t n) {
|
||||||
// Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
|
// Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
|
||||||
// and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
|
// and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
|
||||||
int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
|
int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
|
||||||
return to_unsigned(t) - (n < data::ZERO_OR_POWERS_OF_10_64[t]) + 1;
|
return t - (n < data::ZERO_OR_POWERS_OF_10_64[t]) + 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Fallback version of count_digits used when __builtin_clz is not available.
|
// Fallback version of count_digits used when __builtin_clz is not available.
|
||||||
inline unsigned count_digits(uint64_t n) {
|
inline int count_digits(uint64_t n) {
|
||||||
unsigned count = 1;
|
int count = 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// Integer division is slow so do it for a group of four digits instead
|
// Integer division is slow so do it for a group of four digits instead
|
||||||
// of for every digit. The idea comes from the talk by Alexandrescu
|
// of for every digit. The idea comes from the talk by Alexandrescu
|
||||||
@ -900,9 +896,9 @@ class decimal_formatter_null : public decimal_formatter {
|
|||||||
|
|
||||||
#ifdef FMT_BUILTIN_CLZ
|
#ifdef FMT_BUILTIN_CLZ
|
||||||
// Optional version of count_digits for better performance on 32-bit platforms.
|
// Optional version of count_digits for better performance on 32-bit platforms.
|
||||||
inline unsigned count_digits(uint32_t n) {
|
inline int count_digits(uint32_t n) {
|
||||||
int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
|
int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
|
||||||
return to_unsigned(t) - (n < data::ZERO_OR_POWERS_OF_10_32[t]) + 1;
|
return t - (n < data::ZERO_OR_POWERS_OF_10_32[t]) + 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -959,8 +955,9 @@ inline wchar_t thousands_sep(locale_ref loc) {
|
|||||||
// thousands_sep is a functor that is called after writing each char to
|
// thousands_sep is a functor that is called after writing each char to
|
||||||
// add a thousands separator if necessary.
|
// add a thousands separator if necessary.
|
||||||
template <typename UInt, typename Char, typename ThousandsSep>
|
template <typename UInt, typename Char, typename ThousandsSep>
|
||||||
inline Char *format_decimal(Char *buffer, UInt value, unsigned num_digits,
|
inline Char *format_decimal(Char *buffer, UInt value, int num_digits,
|
||||||
ThousandsSep thousands_sep) {
|
ThousandsSep thousands_sep) {
|
||||||
|
FMT_ASSERT(num_digits >= 0, "invalid digit count");
|
||||||
buffer += num_digits;
|
buffer += num_digits;
|
||||||
Char *end = buffer;
|
Char *end = buffer;
|
||||||
while (value >= 100) {
|
while (value >= 100) {
|
||||||
@ -988,7 +985,8 @@ inline Char *format_decimal(Char *buffer, UInt value, unsigned num_digits,
|
|||||||
template <typename OutChar, typename UInt, typename Iterator,
|
template <typename OutChar, typename UInt, typename Iterator,
|
||||||
typename ThousandsSep>
|
typename ThousandsSep>
|
||||||
inline Iterator format_decimal(
|
inline Iterator format_decimal(
|
||||||
Iterator out, UInt value, unsigned num_digits, ThousandsSep sep) {
|
Iterator out, UInt value, int num_digits, ThousandsSep sep) {
|
||||||
|
FMT_ASSERT(num_digits >= 0, "invalid digit count");
|
||||||
typedef typename ThousandsSep::char_type char_type;
|
typedef typename ThousandsSep::char_type char_type;
|
||||||
// Buffer should be large enough to hold all digits (<= digits10 + 1).
|
// Buffer should be large enough to hold all digits (<= digits10 + 1).
|
||||||
enum { max_size = std::numeric_limits<UInt>::digits10 + 1 };
|
enum { max_size = std::numeric_limits<UInt>::digits10 + 1 };
|
||||||
@ -999,25 +997,26 @@ inline Iterator format_decimal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutChar, typename It, typename UInt>
|
template <typename OutChar, typename It, typename UInt>
|
||||||
inline It format_decimal(It out, UInt value, unsigned num_digits) {
|
inline It format_decimal(It out, UInt value, int num_digits) {
|
||||||
return format_decimal<OutChar>(out, value, num_digits, no_thousands_sep());
|
return format_decimal<OutChar>(out, value, num_digits, no_thousands_sep());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned BASE_BITS, typename Char, typename UInt>
|
template <unsigned BASE_BITS, typename Char, typename UInt>
|
||||||
inline Char *format_uint(Char *buffer, UInt value, unsigned num_digits,
|
inline Char *format_uint(Char *buffer, UInt value, int num_digits,
|
||||||
bool upper = false) {
|
bool upper = false) {
|
||||||
buffer += num_digits;
|
buffer += num_digits;
|
||||||
Char *end = buffer;
|
Char *end = buffer;
|
||||||
do {
|
do {
|
||||||
const char *digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
|
const char *digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||||
unsigned digit = (value & ((1 << BASE_BITS) - 1));
|
unsigned digit = (value & ((1 << BASE_BITS) - 1));
|
||||||
*--buffer = static_cast<Char>(BASE_BITS < 4 ? '0' + digit : digits[digit]);
|
*--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
|
||||||
|
: digits[digit]);
|
||||||
} while ((value >>= BASE_BITS) != 0);
|
} while ((value >>= BASE_BITS) != 0);
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
|
template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
|
||||||
inline It format_uint(It out, UInt value, unsigned num_digits,
|
inline It format_uint(It out, UInt value, int num_digits,
|
||||||
bool upper = false) {
|
bool upper = false) {
|
||||||
// Buffer should be large enough to hold all digits (digits / BASE_BITS + 1)
|
// Buffer should be large enough to hold all digits (digits / BASE_BITS + 1)
|
||||||
// and null.
|
// and null.
|
||||||
@ -1979,7 +1978,7 @@ FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out) {
|
|||||||
template <>
|
template <>
|
||||||
inline bool find<false, char>(
|
inline bool find<false, char>(
|
||||||
const char *first, const char *last, char value, const char *&out) {
|
const char *first, const char *last, char value, const char *&out) {
|
||||||
out = static_cast<const char*>(std::memchr(first, value, last - first));
|
out = static_cast<const char*>(std::memchr(first, value, internal::to_unsigned(last - first)));
|
||||||
return out != FMT_NULL;
|
return out != FMT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2062,7 +2061,7 @@ class format_string_checker {
|
|||||||
public:
|
public:
|
||||||
explicit FMT_CONSTEXPR format_string_checker(
|
explicit FMT_CONSTEXPR format_string_checker(
|
||||||
basic_string_view<Char> format_str, ErrorHandler eh)
|
basic_string_view<Char> format_str, ErrorHandler eh)
|
||||||
: arg_id_(-1), context_(format_str, eh),
|
: arg_id_((std::numeric_limits<unsigned>::max)()), context_(format_str, eh),
|
||||||
parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
|
parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
|
||||||
|
|
||||||
FMT_CONSTEXPR void on_text(const Char *, const Char *) {}
|
FMT_CONSTEXPR void on_text(const Char *, const Char *) {}
|
||||||
@ -2082,7 +2081,7 @@ class format_string_checker {
|
|||||||
|
|
||||||
FMT_CONSTEXPR const Char *on_format_specs(const Char *begin, const Char *) {
|
FMT_CONSTEXPR const Char *on_format_specs(const Char *begin, const Char *) {
|
||||||
context_.advance_to(begin);
|
context_.advance_to(begin);
|
||||||
return to_unsigned(arg_id_) < NUM_ARGS ?
|
return arg_id_ < NUM_ARGS ?
|
||||||
parse_funcs_[arg_id_](context_) : begin;
|
parse_funcs_[arg_id_](context_) : begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2095,14 +2094,14 @@ class format_string_checker {
|
|||||||
enum { NUM_ARGS = sizeof...(Args) };
|
enum { NUM_ARGS = sizeof...(Args) };
|
||||||
|
|
||||||
FMT_CONSTEXPR void check_arg_id() {
|
FMT_CONSTEXPR void check_arg_id() {
|
||||||
if (internal::to_unsigned(arg_id_) >= NUM_ARGS)
|
if (arg_id_ >= NUM_ARGS)
|
||||||
context_.on_error("argument index out of range");
|
context_.on_error("argument index out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format specifier parsing function.
|
// Format specifier parsing function.
|
||||||
typedef const Char *(*parse_func)(parse_context_type &);
|
typedef const Char *(*parse_func)(parse_context_type &);
|
||||||
|
|
||||||
int arg_id_;
|
unsigned arg_id_;
|
||||||
parse_context_type context_;
|
parse_context_type context_;
|
||||||
parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
|
parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
|
||||||
};
|
};
|
||||||
@ -2324,9 +2323,9 @@ class basic_writer {
|
|||||||
// <left-padding><prefix><numeric-padding><digits><right-padding>
|
// <left-padding><prefix><numeric-padding><digits><right-padding>
|
||||||
// where <digits> are written by f(it).
|
// where <digits> are written by f(it).
|
||||||
template <typename Spec, typename F>
|
template <typename Spec, typename F>
|
||||||
void write_int(unsigned num_digits, string_view prefix,
|
void write_int(int num_digits, string_view prefix,
|
||||||
const Spec &spec, F f) {
|
const Spec &spec, F f) {
|
||||||
std::size_t size = prefix.size() + num_digits;
|
std::size_t size = prefix.size() + internal::to_unsigned(num_digits);
|
||||||
char_type fill = static_cast<char_type>(spec.fill());
|
char_type fill = static_cast<char_type>(spec.fill());
|
||||||
std::size_t padding = 0;
|
std::size_t padding = 0;
|
||||||
if (spec.align() == ALIGN_NUMERIC) {
|
if (spec.align() == ALIGN_NUMERIC) {
|
||||||
@ -2334,9 +2333,9 @@ class basic_writer {
|
|||||||
padding = spec.width() - size;
|
padding = spec.width() - size;
|
||||||
size = spec.width();
|
size = spec.width();
|
||||||
}
|
}
|
||||||
} else if (spec.precision > static_cast<int>(num_digits)) {
|
} else if (spec.precision > num_digits) {
|
||||||
size = prefix.size() + internal::to_unsigned(spec.precision);
|
size = prefix.size() + internal::to_unsigned(spec.precision);
|
||||||
padding = internal::to_unsigned(spec.precision) - num_digits;
|
padding = internal::to_unsigned(spec.precision - num_digits);
|
||||||
fill = static_cast<char_type>('0');
|
fill = static_cast<char_type>('0');
|
||||||
}
|
}
|
||||||
align_spec as = spec;
|
align_spec as = spec;
|
||||||
@ -2353,8 +2352,8 @@ class basic_writer {
|
|||||||
bool is_negative = internal::is_negative(value);
|
bool is_negative = internal::is_negative(value);
|
||||||
if (is_negative)
|
if (is_negative)
|
||||||
abs_value = 0 - abs_value;
|
abs_value = 0 - abs_value;
|
||||||
unsigned num_digits = internal::count_digits(abs_value);
|
int num_digits = internal::count_digits(abs_value);
|
||||||
auto &&it = reserve((is_negative ? 1 : 0) + num_digits);
|
auto &&it = reserve((is_negative ? 1 : 0) + static_cast<size_t>(num_digits));
|
||||||
if (is_negative)
|
if (is_negative)
|
||||||
*it++ = static_cast<char_type>('-');
|
*it++ = static_cast<char_type>('-');
|
||||||
it = internal::format_decimal<char_type>(it, abs_value, num_digits);
|
it = internal::format_decimal<char_type>(it, abs_value, num_digits);
|
||||||
@ -2375,9 +2374,9 @@ class basic_writer {
|
|||||||
|
|
||||||
// Counts the number of digits in abs_value. BITS = log2(radix).
|
// Counts the number of digits in abs_value. BITS = log2(radix).
|
||||||
template <unsigned BITS>
|
template <unsigned BITS>
|
||||||
unsigned count_digits() const {
|
int count_digits() const {
|
||||||
unsigned_type n = abs_value;
|
unsigned_type n = abs_value;
|
||||||
unsigned num_digits = 0;
|
int num_digits = 0;
|
||||||
do {
|
do {
|
||||||
++num_digits;
|
++num_digits;
|
||||||
} while ((n >>= BITS) != 0);
|
} while ((n >>= BITS) != 0);
|
||||||
@ -2399,7 +2398,7 @@ class basic_writer {
|
|||||||
|
|
||||||
struct dec_writer {
|
struct dec_writer {
|
||||||
unsigned_type abs_value;
|
unsigned_type abs_value;
|
||||||
unsigned num_digits;
|
int num_digits;
|
||||||
|
|
||||||
template <typename It>
|
template <typename It>
|
||||||
void operator()(It &&it) const {
|
void operator()(It &&it) const {
|
||||||
@ -2408,14 +2407,14 @@ class basic_writer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void on_dec() {
|
void on_dec() {
|
||||||
unsigned num_digits = internal::count_digits(abs_value);
|
int num_digits = internal::count_digits(abs_value);
|
||||||
writer.write_int(num_digits, get_prefix(), spec,
|
writer.write_int(num_digits, get_prefix(), spec,
|
||||||
dec_writer{abs_value, num_digits});
|
dec_writer{abs_value, num_digits});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hex_writer {
|
struct hex_writer {
|
||||||
int_writer &self;
|
int_writer &self;
|
||||||
unsigned num_digits;
|
int num_digits;
|
||||||
|
|
||||||
template <typename It>
|
template <typename It>
|
||||||
void operator()(It &&it) const {
|
void operator()(It &&it) const {
|
||||||
@ -2429,7 +2428,7 @@ class basic_writer {
|
|||||||
prefix[prefix_size++] = '0';
|
prefix[prefix_size++] = '0';
|
||||||
prefix[prefix_size++] = static_cast<char>(spec.type);
|
prefix[prefix_size++] = static_cast<char>(spec.type);
|
||||||
}
|
}
|
||||||
unsigned num_digits = count_digits<4>();
|
int num_digits = count_digits<4>();
|
||||||
writer.write_int(num_digits, get_prefix(), spec,
|
writer.write_int(num_digits, get_prefix(), spec,
|
||||||
hex_writer{*this, num_digits});
|
hex_writer{*this, num_digits});
|
||||||
}
|
}
|
||||||
@ -2437,7 +2436,7 @@ class basic_writer {
|
|||||||
template <int BITS>
|
template <int BITS>
|
||||||
struct bin_writer {
|
struct bin_writer {
|
||||||
unsigned_type abs_value;
|
unsigned_type abs_value;
|
||||||
unsigned num_digits;
|
int num_digits;
|
||||||
|
|
||||||
template <typename It>
|
template <typename It>
|
||||||
void operator()(It &&it) const {
|
void operator()(It &&it) const {
|
||||||
@ -2450,15 +2449,15 @@ class basic_writer {
|
|||||||
prefix[prefix_size++] = '0';
|
prefix[prefix_size++] = '0';
|
||||||
prefix[prefix_size++] = static_cast<char>(spec.type);
|
prefix[prefix_size++] = static_cast<char>(spec.type);
|
||||||
}
|
}
|
||||||
unsigned num_digits = count_digits<1>();
|
int num_digits = count_digits<1>();
|
||||||
writer.write_int(num_digits, get_prefix(), spec,
|
writer.write_int(num_digits, get_prefix(), spec,
|
||||||
bin_writer<1>{abs_value, num_digits});
|
bin_writer<1>{abs_value, num_digits});
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_oct() {
|
void on_oct() {
|
||||||
unsigned num_digits = count_digits<3>();
|
int num_digits = count_digits<3>();
|
||||||
if (spec.has(HASH_FLAG) &&
|
if (spec.has(HASH_FLAG) &&
|
||||||
spec.precision <= static_cast<int>(num_digits)) {
|
spec.precision <= num_digits) {
|
||||||
// Octal prefix '0' is counted as a digit, so only add it if precision
|
// Octal prefix '0' is counted as a digit, so only add it if precision
|
||||||
// is not greater than the number of digits.
|
// is not greater than the number of digits.
|
||||||
prefix[prefix_size++] = '0';
|
prefix[prefix_size++] = '0';
|
||||||
@ -2471,7 +2470,7 @@ class basic_writer {
|
|||||||
|
|
||||||
struct num_writer {
|
struct num_writer {
|
||||||
unsigned_type abs_value;
|
unsigned_type abs_value;
|
||||||
unsigned size;
|
int size;
|
||||||
char_type sep;
|
char_type sep;
|
||||||
|
|
||||||
template <typename It>
|
template <typename It>
|
||||||
@ -2483,9 +2482,9 @@ class basic_writer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void on_num() {
|
void on_num() {
|
||||||
unsigned num_digits = internal::count_digits(abs_value);
|
int num_digits = internal::count_digits(abs_value);
|
||||||
char_type sep = internal::thousands_sep<char_type>(writer.locale_);
|
char_type sep = internal::thousands_sep<char_type>(writer.locale_);
|
||||||
unsigned size = num_digits + SEP_SIZE * ((num_digits - 1) / 3);
|
int size = num_digits + SEP_SIZE * ((num_digits - 1) / 3);
|
||||||
writer.write_int(size, get_prefix(), spec,
|
writer.write_int(size, get_prefix(), spec,
|
||||||
num_writer{abs_value, size, sep});
|
num_writer{abs_value, size, sep});
|
||||||
}
|
}
|
||||||
@ -2909,9 +2908,9 @@ inline void format_decimal(char *&buffer, T value) {
|
|||||||
*buffer++ = internal::data::DIGITS[index + 1];
|
*buffer++ = internal::data::DIGITS[index + 1];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned num_digits = internal::count_digits(abs_value);
|
int num_digits = internal::count_digits(abs_value);
|
||||||
internal::format_decimal<char>(
|
internal::format_decimal<char>(
|
||||||
internal::make_checked(buffer, num_digits), abs_value, num_digits);
|
internal::make_checked(buffer, internal::to_unsigned(num_digits)), abs_value, num_digits);
|
||||||
buffer += num_digits;
|
buffer += num_digits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +631,7 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
|
|||||||
|
|
||||||
format_arg arg = get_arg(it, arg_index);
|
format_arg arg = get_arg(it, arg_index);
|
||||||
if (spec.has(HASH_FLAG) && visit_format_arg(internal::is_zero_int(), arg))
|
if (spec.has(HASH_FLAG) && visit_format_arg(internal::is_zero_int(), arg))
|
||||||
spec.flags &= ~internal::to_unsigned<int>(HASH_FLAG);
|
spec.flags = static_cast<uint_least8_t>(spec.flags & (~internal::to_unsigned<int>(HASH_FLAG)));
|
||||||
if (spec.fill_ == '0') {
|
if (spec.fill_ == '0') {
|
||||||
if (arg.is_arithmetic())
|
if (arg.is_arithmetic())
|
||||||
spec.align_ = ALIGN_NUMERIC;
|
spec.align_ = ALIGN_NUMERIC;
|
||||||
|
@ -122,7 +122,7 @@ struct formatter<std::tm, Char> {
|
|||||||
auto end = it;
|
auto end = it;
|
||||||
while (end != ctx.end() && *end != '}')
|
while (end != ctx.end() && *end != '}')
|
||||||
++end;
|
++end;
|
||||||
tm_format.reserve(end - it + 1);
|
tm_format.reserve(internal::to_unsigned(end - it + 1));
|
||||||
tm_format.append(it, end);
|
tm_format.append(it, end);
|
||||||
tm_format.push_back('\0');
|
tm_format.push_back('\0');
|
||||||
return end;
|
return end;
|
||||||
|
@ -492,7 +492,7 @@ class QString {
|
|||||||
|
|
||||||
inline fmt::basic_string_view<wchar_t> to_string_view(
|
inline fmt::basic_string_view<wchar_t> to_string_view(
|
||||||
const QString &s) FMT_NOEXCEPT {
|
const QString &s) FMT_NOEXCEPT {
|
||||||
return {reinterpret_cast<const wchar_t *>(s.utf16()),
|
return {s.utf16(),
|
||||||
static_cast<std::size_t>(s.size())};
|
static_cast<std::size_t>(s.size())};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1917,6 +1917,7 @@ TEST(FormatTest, Enum) {
|
|||||||
|
|
||||||
TEST(FormatTest, EnumFormatterUnambiguous) {
|
TEST(FormatTest, EnumFormatterUnambiguous) {
|
||||||
fmt::formatter<TestEnum> f;
|
fmt::formatter<TestEnum> f;
|
||||||
|
ASSERT_GE(sizeof(f), 0); // use f to avoid compiler warning
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FMT_HAS_FEATURE(cxx_strong_enums)
|
#if FMT_HAS_FEATURE(cxx_strong_enums)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user