mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Merge branch 'header-only' of github.com:cppformat/cppformat
This commit is contained in:
38
format.cc
38
format.cc
@ -81,6 +81,12 @@ using fmt::internal::Arg;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FMT_HEADER_ONLY
|
||||||
|
# define FMT_FUNC inline
|
||||||
|
#else
|
||||||
|
# define FMT_FUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
# pragma warning(disable: 4127) // conditional expression is constant
|
# pragma warning(disable: 4127) // conditional expression is constant
|
||||||
@ -355,7 +361,7 @@ inline Arg::StringValue<wchar_t> ignore_incompatible_str(
|
|||||||
Arg::StringValue<wchar_t> s) { return s; }
|
Arg::StringValue<wchar_t> s) { return s; }
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void fmt::SystemError::init(
|
FMT_FUNC void fmt::SystemError::init(
|
||||||
int error_code, StringRef format_str, ArgList args) {
|
int error_code, StringRef format_str, ArgList args) {
|
||||||
error_code_ = error_code;
|
error_code_ = error_code;
|
||||||
MemoryWriter w;
|
MemoryWriter w;
|
||||||
@ -392,7 +398,8 @@ int fmt::internal::CharTraits<wchar_t>::format_float(
|
|||||||
swprintf(buffer, size, format, width, precision, value);
|
swprintf(buffer, size, format, width, precision, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char fmt::internal::DIGITS[] =
|
template <typename T>
|
||||||
|
const char fmt::internal::BasicData<T>::DIGITS[] =
|
||||||
"0001020304050607080910111213141516171819"
|
"0001020304050607080910111213141516171819"
|
||||||
"2021222324252627282930313233343536373839"
|
"2021222324252627282930313233343536373839"
|
||||||
"4041424344454647484950515253545556575859"
|
"4041424344454647484950515253545556575859"
|
||||||
@ -410,8 +417,13 @@ const char fmt::internal::DIGITS[] =
|
|||||||
factor * 100000000, \
|
factor * 100000000, \
|
||||||
factor * 1000000000
|
factor * 1000000000
|
||||||
|
|
||||||
const uint32_t fmt::internal::POWERS_OF_10_32[] = {0, FMT_POWERS_OF_10(1)};
|
template <typename T>
|
||||||
const uint64_t fmt::internal::POWERS_OF_10_64[] = {
|
const uint32_t fmt::internal::BasicData<T>::POWERS_OF_10_32[] = {
|
||||||
|
0, FMT_POWERS_OF_10(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const uint64_t fmt::internal::BasicData<T>::POWERS_OF_10_64[] = {
|
||||||
0,
|
0,
|
||||||
FMT_POWERS_OF_10(1),
|
FMT_POWERS_OF_10(1),
|
||||||
FMT_POWERS_OF_10(ULongLong(1000000000)),
|
FMT_POWERS_OF_10(ULongLong(1000000000)),
|
||||||
@ -420,7 +432,7 @@ const uint64_t fmt::internal::POWERS_OF_10_64[] = {
|
|||||||
ULongLong(1000000000) * ULongLong(1000000000) * 10
|
ULongLong(1000000000) * ULongLong(1000000000) * 10
|
||||||
};
|
};
|
||||||
|
|
||||||
void fmt::internal::report_unknown_type(char code, const char *type) {
|
FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
|
||||||
if (std::isprint(static_cast<unsigned char>(code))) {
|
if (std::isprint(static_cast<unsigned char>(code))) {
|
||||||
FMT_THROW(fmt::FormatError(
|
FMT_THROW(fmt::FormatError(
|
||||||
fmt::format("unknown format code '{}' for {}", code, type)));
|
fmt::format("unknown format code '{}' for {}", code, type)));
|
||||||
@ -475,7 +487,7 @@ void fmt::WindowsError::init(
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void fmt::internal::format_system_error(
|
FMT_FUNC void fmt::internal::format_system_error(
|
||||||
fmt::Writer &out, int error_code,
|
fmt::Writer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT(true) {
|
fmt::StringRef message) FMT_NOEXCEPT(true) {
|
||||||
FMT_TRY {
|
FMT_TRY {
|
||||||
@ -628,7 +640,7 @@ inline Arg fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) {
|
|||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
Arg fmt::internal::FormatterBase::do_get_arg(
|
FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
|
||||||
unsigned arg_index, const char *&error) {
|
unsigned arg_index, const char *&error) {
|
||||||
Arg arg = args_[arg_index];
|
Arg arg = args_[arg_index];
|
||||||
if (arg.type == Arg::NONE)
|
if (arg.type == Arg::NONE)
|
||||||
@ -1051,7 +1063,7 @@ void fmt::BasicFormatter<Char>::format(
|
|||||||
write(writer_, start_, s);
|
write(writer_, start_, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fmt::report_system_error(
|
FMT_FUNC void fmt::report_system_error(
|
||||||
int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) {
|
int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) {
|
||||||
report_error(internal::format_system_error, error_code, message);
|
report_error(internal::format_system_error, error_code, message);
|
||||||
}
|
}
|
||||||
@ -1063,23 +1075,23 @@ void fmt::report_windows_error(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void fmt::print(std::FILE *f, StringRef format_str, ArgList args) {
|
FMT_FUNC void fmt::print(std::FILE *f, StringRef format_str, ArgList args) {
|
||||||
MemoryWriter w;
|
MemoryWriter w;
|
||||||
w.write(format_str, args);
|
w.write(format_str, args);
|
||||||
std::fwrite(w.data(), 1, w.size(), f);
|
std::fwrite(w.data(), 1, w.size(), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fmt::print(StringRef format_str, ArgList args) {
|
FMT_FUNC void fmt::print(StringRef format_str, ArgList args) {
|
||||||
print(stdout, format_str, args);
|
print(stdout, format_str, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fmt::print(std::ostream &os, StringRef format_str, ArgList args) {
|
FMT_FUNC void fmt::print(std::ostream &os, StringRef format_str, ArgList args) {
|
||||||
MemoryWriter w;
|
MemoryWriter w;
|
||||||
w.write(format_str, args);
|
w.write(format_str, args);
|
||||||
os.write(w.data(), w.size());
|
os.write(w.data(), w.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void fmt::print_colored(Color c, StringRef format, ArgList args) {
|
FMT_FUNC void fmt::print_colored(Color c, StringRef format, ArgList args) {
|
||||||
char escape[] = "\x1b[30m";
|
char escape[] = "\x1b[30m";
|
||||||
escape[3] = '0' + static_cast<char>(c);
|
escape[3] = '0' + static_cast<char>(c);
|
||||||
std::fputs(escape, stdout);
|
std::fputs(escape, stdout);
|
||||||
@ -1087,7 +1099,7 @@ void fmt::print_colored(Color c, StringRef format, ArgList args) {
|
|||||||
std::fputs(RESET_COLOR, stdout);
|
std::fputs(RESET_COLOR, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fmt::fprintf(std::FILE *f, StringRef format, ArgList args) {
|
FMT_FUNC int fmt::fprintf(std::FILE *f, StringRef format, ArgList args) {
|
||||||
MemoryWriter w;
|
MemoryWriter w;
|
||||||
printf(w, format, args);
|
printf(w, format, args);
|
||||||
std::size_t size = w.size();
|
std::size_t size = w.size();
|
||||||
|
42
format.h
42
format.h
@ -505,8 +505,16 @@ FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
|
|||||||
|
|
||||||
void report_unknown_type(char code, const char *type);
|
void report_unknown_type(char code, const char *type);
|
||||||
|
|
||||||
extern const uint32_t POWERS_OF_10_32[];
|
// Static data is placed in this class template to allow header-only
|
||||||
extern const uint64_t POWERS_OF_10_64[];
|
// configuration.
|
||||||
|
template <typename T = void>
|
||||||
|
struct BasicData {
|
||||||
|
static const uint32_t POWERS_OF_10_32[];
|
||||||
|
static const uint64_t POWERS_OF_10_64[];
|
||||||
|
static const char DIGITS[];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BasicData<> Data;
|
||||||
|
|
||||||
#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
|
#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__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
|
||||||
@ -515,13 +523,13 @@ 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 - __builtin_clzll(n | 1)) * 1233 >> 12;
|
unsigned t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12;
|
||||||
return t - (n < POWERS_OF_10_64[t]) + 1;
|
return t - (n < Data::POWERS_OF_10_64[t]) + 1;
|
||||||
}
|
}
|
||||||
# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
|
# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__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 - __builtin_clz(n | 1)) * 1233 >> 12;
|
uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12;
|
||||||
return t - (n < POWERS_OF_10_32[t]) + 1;
|
return t - (n < Data::POWERS_OF_10_32[t]) + 1;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
@ -542,8 +550,6 @@ inline unsigned count_digits(uint64_t n) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const char DIGITS[];
|
|
||||||
|
|
||||||
// Formats a decimal unsigned integer value writing into buffer.
|
// Formats a decimal unsigned integer value writing into buffer.
|
||||||
template <typename UInt, typename Char>
|
template <typename UInt, typename Char>
|
||||||
inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
|
inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
|
||||||
@ -554,8 +560,8 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
|
|||||||
// "Three Optimization Tips for C++". See speed-test for a comparison.
|
// "Three Optimization Tips for C++". See speed-test for a comparison.
|
||||||
unsigned index = (value % 100) * 2;
|
unsigned index = (value % 100) * 2;
|
||||||
value /= 100;
|
value /= 100;
|
||||||
buffer[num_digits] = DIGITS[index + 1];
|
buffer[num_digits] = Data::DIGITS[index + 1];
|
||||||
buffer[num_digits - 1] = DIGITS[index];
|
buffer[num_digits - 1] = Data::DIGITS[index];
|
||||||
num_digits -= 2;
|
num_digits -= 2;
|
||||||
}
|
}
|
||||||
if (value < 10) {
|
if (value < 10) {
|
||||||
@ -563,8 +569,8 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned index = static_cast<unsigned>(value * 2);
|
unsigned index = static_cast<unsigned>(value * 2);
|
||||||
buffer[1] = DIGITS[index + 1];
|
buffer[1] = Data::DIGITS[index + 1];
|
||||||
buffer[0] = DIGITS[index];
|
buffer[0] = Data::DIGITS[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -2228,16 +2234,16 @@ class FormatInt {
|
|||||||
// "Three Optimization Tips for C++". See speed-test for a comparison.
|
// "Three Optimization Tips for C++". See speed-test for a comparison.
|
||||||
unsigned index = (value % 100) * 2;
|
unsigned index = (value % 100) * 2;
|
||||||
value /= 100;
|
value /= 100;
|
||||||
*--buffer_end = internal::DIGITS[index + 1];
|
*--buffer_end = internal::Data::DIGITS[index + 1];
|
||||||
*--buffer_end = internal::DIGITS[index];
|
*--buffer_end = internal::Data::DIGITS[index];
|
||||||
}
|
}
|
||||||
if (value < 10) {
|
if (value < 10) {
|
||||||
*--buffer_end = static_cast<char>('0' + value);
|
*--buffer_end = static_cast<char>('0' + value);
|
||||||
return buffer_end;
|
return buffer_end;
|
||||||
}
|
}
|
||||||
unsigned index = static_cast<unsigned>(value * 2);
|
unsigned index = static_cast<unsigned>(value * 2);
|
||||||
*--buffer_end = internal::DIGITS[index + 1];
|
*--buffer_end = internal::Data::DIGITS[index + 1];
|
||||||
*--buffer_end = internal::DIGITS[index];
|
*--buffer_end = internal::Data::DIGITS[index];
|
||||||
return buffer_end;
|
return buffer_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2301,8 +2307,8 @@ inline void format_decimal(char *&buffer, T value) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned index = static_cast<unsigned>(abs_value * 2);
|
unsigned index = static_cast<unsigned>(abs_value * 2);
|
||||||
*buffer++ = internal::DIGITS[index];
|
*buffer++ = internal::Data::DIGITS[index];
|
||||||
*buffer++ = internal::DIGITS[index + 1];
|
*buffer++ = internal::Data::DIGITS[index + 1];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned num_digits = internal::count_digits(abs_value);
|
unsigned num_digits = internal::count_digits(abs_value);
|
||||||
@ -2433,4 +2439,8 @@ FMT_VARIADIC(int, fprintf, std::FILE *, StringRef)
|
|||||||
# pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FMT_HEADER_ONLY
|
||||||
|
# include "format.cc"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // FMT_FORMAT_H_
|
#endif // FMT_FORMAT_H_
|
||||||
|
Reference in New Issue
Block a user