Commit f9c3ff24 authored by Victor Zverovich's avatar Victor Zverovich

Merge branch 'header-only' of github.com:cppformat/cppformat

parents 6e3d7d9a 311251eb
...@@ -81,6 +81,12 @@ using fmt::internal::Arg; ...@@ -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( ...@@ -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( ...@@ -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[] = ...@@ -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[] = { ...@@ -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( ...@@ -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) { ...@@ -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( ...@@ -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( ...@@ -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) { ...@@ -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();
......
...@@ -505,8 +505,16 @@ FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong); ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 { ...@@ -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) { ...@@ -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) ...@@ -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_
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