Commit 82d6813e authored by vitaut's avatar vitaut

Fix a bunch of Clang sign-conversion warnings

parent 2f12a32c
...@@ -529,6 +529,29 @@ class FormatError : public std::runtime_error { ...@@ -529,6 +529,29 @@ class FormatError : public std::runtime_error {
}; };
namespace internal { namespace internal {
// MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
template <typename T>
struct MakeUnsigned { typedef T Type; };
#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
template <> \
struct MakeUnsigned<T> { typedef U Type; }
FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
// Casts nonnegative integer to unsigned.
template <typename Int>
inline typename MakeUnsigned<Int>::Type to_unsigned(Int value) {
FMT_ASSERT(value >= 0, "negative value");
return static_cast<typename MakeUnsigned<Int>::Type>(value);
}
// The number of characters to store in the MemoryBuffer object itself // The number of characters to store in the MemoryBuffer object itself
// to avoid dynamic memory allocation. // to avoid dynamic memory allocation.
enum { INLINE_BUFFER_SIZE = 500 }; enum { INLINE_BUFFER_SIZE = 500 };
...@@ -618,8 +641,7 @@ class Buffer { ...@@ -618,8 +641,7 @@ class Buffer {
template <typename T> template <typename T>
template <typename U> template <typename U>
void Buffer<T>::append(const U *begin, const U *end) { void Buffer<T>::append(const U *begin, const U *end) {
assert(begin <= end); std::size_t new_size = size_ + internal::to_unsigned(end - begin);
std::size_t new_size = size_ + (end - begin);
if (new_size > capacity_) if (new_size > capacity_)
grow(new_size); grow(new_size);
std::uninitialized_copy(begin, end, std::uninitialized_copy(begin, end,
...@@ -791,21 +813,6 @@ struct IntTraits { ...@@ -791,21 +813,6 @@ struct IntTraits {
TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType; TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
}; };
// MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
template <typename T>
struct MakeUnsigned { typedef T Type; };
#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
template <> \
struct MakeUnsigned<T> { typedef U Type; }
FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
FMT_API void report_unknown_type(char code, const char *type); FMT_API void report_unknown_type(char code, const char *type);
// Static data is placed in this class template to allow header-only // Static data is placed in this class template to allow header-only
...@@ -819,15 +826,14 @@ struct FMT_API BasicData { ...@@ -819,15 +826,14 @@ struct FMT_API BasicData {
typedef BasicData<> Data; typedef BasicData<> 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 unsigned 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.
unsigned t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12; int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
return t - (n < Data::POWERS_OF_10_64[t]) + 1; return to_unsigned(t) - (n < Data::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.
...@@ -850,8 +856,8 @@ inline unsigned count_digits(uint64_t n) { ...@@ -850,8 +856,8 @@ inline unsigned count_digits(uint64_t n) {
#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 unsigned count_digits(uint32_t n) {
uint32_t t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12; int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
return t - (n < Data::POWERS_OF_10_32[t]) + 1; return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1;
} }
#endif #endif
...@@ -1826,7 +1832,7 @@ class FormatterBase { ...@@ -1826,7 +1832,7 @@ class FormatterBase {
// Returns the next argument. // Returns the next argument.
Arg next_arg(const char *&error) { Arg next_arg(const char *&error) {
if (next_arg_index_ >= 0) if (next_arg_index_ >= 0)
return do_get_arg(next_arg_index_++, error); return do_get_arg(static_cast<unsigned>(next_arg_index_++), error);
error = "cannot switch from manual to automatic argument indexing"; error = "cannot switch from manual to automatic argument indexing";
return Arg(); return Arg();
} }
...@@ -1849,7 +1855,7 @@ class FormatterBase { ...@@ -1849,7 +1855,7 @@ class FormatterBase {
template <typename Char> template <typename Char>
void write(BasicWriter<Char> &w, const Char *start, const Char *end) { void write(BasicWriter<Char> &w, const Char *start, const Char *end) {
if (start != end) if (start != end)
w << BasicStringRef<Char>(start, end - start); w << BasicStringRef<Char>(start, internal::to_unsigned(end - start));
} }
}; };
...@@ -2506,9 +2512,9 @@ void BasicWriter<Char>::write_str( ...@@ -2506,9 +2512,9 @@ void BasicWriter<Char>::write_str(
return; return;
} }
} }
std::size_t precision = spec.precision_; std::size_t precision = static_cast<std::size_t>(spec.precision_);
if (spec.precision_ >= 0 && precision < str_size) if (spec.precision_ >= 0 && precision < str_size)
str_size = spec.precision_; str_size = precision;
write_str(str_value, str_size, spec); write_str(str_value, str_size, spec);
} }
...@@ -2596,7 +2602,7 @@ template <typename T, typename Spec> ...@@ -2596,7 +2602,7 @@ template <typename T, typename Spec>
void BasicWriter<Char>::write_int(T value, Spec spec) { void BasicWriter<Char>::write_int(T value, Spec spec) {
unsigned prefix_size = 0; unsigned prefix_size = 0;
typedef typename internal::IntTraits<T>::MainType UnsignedType; typedef typename internal::IntTraits<T>::MainType UnsignedType;
UnsignedType abs_value = value; UnsignedType abs_value = static_cast<UnsignedType>(value);
char prefix[4] = ""; char prefix[4] = "";
if (internal::is_negative(value)) { if (internal::is_negative(value)) {
prefix[0] = '-'; prefix[0] = '-';
...@@ -2675,8 +2681,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) { ...@@ -2675,8 +2681,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
template <typename Char> template <typename Char>
template <typename T> template <typename T>
void BasicWriter<Char>::write_double( void BasicWriter<Char>::write_double(T value, const FormatSpec &spec) {
T value, const FormatSpec &spec) {
// Check type. // Check type.
char type = spec.type(); char type = spec.type();
bool upper = false; bool upper = false;
...@@ -2776,6 +2781,8 @@ void BasicWriter<Char>::write_double( ...@@ -2776,6 +2781,8 @@ void BasicWriter<Char>::write_double(
// Format using snprintf. // Format using snprintf.
Char fill = internal::CharTraits<Char>::cast(spec.fill()); Char fill = internal::CharTraits<Char>::cast(spec.fill());
unsigned n = 0;
Char *start = 0;
for (;;) { for (;;) {
std::size_t buffer_size = buffer_.capacity() - offset; std::size_t buffer_size = buffer_.capacity() - offset;
#ifdef _MSC_VER #ifdef _MSC_VER
...@@ -2787,10 +2794,20 @@ void BasicWriter<Char>::write_double( ...@@ -2787,10 +2794,20 @@ void BasicWriter<Char>::write_double(
buffer_size = buffer_.capacity() - offset; buffer_size = buffer_.capacity() - offset;
} }
#endif #endif
Char *start = &buffer_[offset]; start = &buffer_[offset];
int n = internal::CharTraits<Char>::format_float( int result = internal::CharTraits<Char>::format_float(
start, buffer_size, format, width_for_sprintf, spec.precision(), value); start, buffer_size, format, width_for_sprintf, spec.precision(), value);
if (n >= 0 && offset + n < buffer_.capacity()) { if (result >= 0) {
n = internal::to_unsigned(result);
if (offset + n < buffer_.capacity())
break; // The buffer is large enough - continue with formatting.
buffer_.reserve(offset + n + 1);
} else {
// If result is negative we ask to increase the capacity by at least 1,
// but as std::vector, the buffer grows exponentially.
buffer_.reserve(buffer_.capacity() + 1);
}
}
if (sign) { if (sign) {
if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) ||
*start != ' ') { *start != ' ') {
...@@ -2801,8 +2818,7 @@ void BasicWriter<Char>::write_double( ...@@ -2801,8 +2818,7 @@ void BasicWriter<Char>::write_double(
} }
++n; ++n;
} }
if (spec.align() == ALIGN_CENTER && if (spec.align() == ALIGN_CENTER && spec.width() > n) {
spec.width() > static_cast<unsigned>(n)) {
width = spec.width(); width = spec.width();
CharPtr p = grow_buffer(width); CharPtr p = grow_buffer(width);
std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char)); std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char));
...@@ -2816,12 +2832,6 @@ void BasicWriter<Char>::write_double( ...@@ -2816,12 +2832,6 @@ void BasicWriter<Char>::write_double(
*(start - 1) = sign; *(start - 1) = sign;
} }
grow_buffer(n); grow_buffer(n);
return;
}
// If n is negative we ask to increase the capacity by at least 1,
// but as std::vector, the buffer grows exponentially.
buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1);
}
} }
/** /**
...@@ -3164,10 +3174,10 @@ class FormatInt { ...@@ -3164,10 +3174,10 @@ class FormatInt {
explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {} explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {}
explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {} explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {}
/** /** Returns the number of characters written to the output buffer. */
Returns the number of characters written to the output buffer. std::size_t size() const {
*/ return internal::to_unsigned(buffer_ - str_ + BUFFER_SIZE - 1);
std::size_t size() const { return buffer_ - str_ + BUFFER_SIZE - 1; } }
/** /**
Returns a pointer to the output buffer content. No terminating null Returns a pointer to the output buffer content. No terminating null
...@@ -3197,7 +3207,8 @@ class FormatInt { ...@@ -3197,7 +3207,8 @@ class FormatInt {
// write a terminating null character. // write a terminating null character.
template <typename T> template <typename T>
inline void format_decimal(char *&buffer, T value) { inline void format_decimal(char *&buffer, T value) {
typename internal::IntTraits<T>::MainType abs_value = value; typedef typename internal::IntTraits<T>::MainType MainType;
MainType abs_value = static_cast<MainType>(value);
if (internal::is_negative(value)) { if (internal::is_negative(value)) {
*buffer++ = '-'; *buffer++ = '-';
abs_value = 0 - abs_value; abs_value = 0 - abs_value;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment