clang-format for header files

- Google Style, Cpp 11
- Break for template and param/arguments
This commit is contained in:
luncliff 2018-12-19 15:42:25 +09:00
parent 3e01376e08
commit 8671608b83
14 changed files with 1854 additions and 1567 deletions

12
.clang-format Normal file
View File

@ -0,0 +1,12 @@
BasedOnStyle: Google
Language: Cpp
Standard: Cpp11
ColumnLimit: 80
AlwaysBreakTemplateDeclarations: true
AllowShortIfStatementsOnASingleLine: false
AlignAfterOpenBracket: AlwaysBreak
BinPackArguments: false
BinPackParameters: false

View File

@ -18,7 +18,7 @@
FMT_BEGIN_NAMESPACE
namespace internal{
namespace internal {
enum class numeric_system {
standard,
@ -28,152 +28,154 @@ enum class numeric_system {
// Parses a put_time-like format string and invokes handler actions.
template <typename Char, typename Handler>
FMT_CONSTEXPR const Char *parse_chrono_format(
const Char *begin, const Char *end, Handler &&handler) {
FMT_CONSTEXPR const Char *parse_chrono_format(const Char *begin,
const Char *end,
Handler &&handler) {
auto ptr = begin;
while (ptr != end) {
auto c = *ptr;
if (c == '}') break;
if (c == '}')
break;
if (c != '%') {
++ptr;
continue;
}
if (begin != ptr)
handler.on_text(begin, ptr);
++ptr; // consume '%'
++ptr; // consume '%'
if (ptr == end)
throw format_error("invalid format");
c = *ptr++;
switch (c) {
case '%':
handler.on_text(ptr - 1, ptr);
break;
case 'n': {
const char newline[] = "\n";
handler.on_text(newline, newline + 1);
break;
}
case 't': {
const char tab[] = "\t";
handler.on_text(tab, tab + 1);
break;
}
// Day of the week:
case 'a':
handler.on_abbr_weekday();
break;
case 'A':
handler.on_full_weekday();
break;
case 'w':
handler.on_dec0_weekday(numeric_system::standard);
break;
case 'u':
handler.on_dec1_weekday(numeric_system::standard);
break;
// Month:
case 'b':
handler.on_abbr_month();
break;
case 'B':
handler.on_full_month();
break;
// Hour, minute, second:
case 'H':
handler.on_24_hour(numeric_system::standard);
break;
case 'I':
handler.on_12_hour(numeric_system::standard);
break;
case 'M':
handler.on_minute(numeric_system::standard);
break;
case 'S':
handler.on_second(numeric_system::standard);
break;
// Other:
case 'c':
handler.on_datetime(numeric_system::standard);
break;
case 'x':
handler.on_loc_date(numeric_system::standard);
break;
case 'X':
handler.on_loc_time(numeric_system::standard);
break;
case 'D':
handler.on_us_date();
break;
case 'F':
handler.on_iso_date();
break;
case 'r':
handler.on_12_hour_time();
break;
case 'R':
handler.on_24_hour_time();
break;
case 'T':
handler.on_iso_time();
break;
case 'p':
handler.on_am_pm();
break;
case 'z':
handler.on_utc_offset();
break;
case 'Z':
handler.on_tz_name();
break;
// Alternative representation:
case 'E': {
if (ptr == end)
throw format_error("invalid format");
c = *ptr++;
switch (c) {
case 'c':
handler.on_datetime(numeric_system::alternative);
case '%':
handler.on_text(ptr - 1, ptr);
break;
case 'x':
handler.on_loc_date(numeric_system::alternative);
case 'n': {
const char newline[] = "\n";
handler.on_text(newline, newline + 1);
break;
case 'X':
handler.on_loc_time(numeric_system::alternative);
break;
default:
throw format_error("invalid format");
}
break;
}
case 'O':
if (ptr == end)
throw format_error("invalid format");
c = *ptr++;
switch (c) {
case 't': {
const char tab[] = "\t";
handler.on_text(tab, tab + 1);
break;
}
// Day of the week:
case 'a':
handler.on_abbr_weekday();
break;
case 'A':
handler.on_full_weekday();
break;
case 'w':
handler.on_dec0_weekday(numeric_system::alternative);
handler.on_dec0_weekday(numeric_system::standard);
break;
case 'u':
handler.on_dec1_weekday(numeric_system::alternative);
handler.on_dec1_weekday(numeric_system::standard);
break;
// Month:
case 'b':
handler.on_abbr_month();
break;
case 'B':
handler.on_full_month();
break;
// Hour, minute, second:
case 'H':
handler.on_24_hour(numeric_system::alternative);
handler.on_24_hour(numeric_system::standard);
break;
case 'I':
handler.on_12_hour(numeric_system::alternative);
handler.on_12_hour(numeric_system::standard);
break;
case 'M':
handler.on_minute(numeric_system::alternative);
handler.on_minute(numeric_system::standard);
break;
case 'S':
handler.on_second(numeric_system::alternative);
handler.on_second(numeric_system::standard);
break;
// Other:
case 'c':
handler.on_datetime(numeric_system::standard);
break;
case 'x':
handler.on_loc_date(numeric_system::standard);
break;
case 'X':
handler.on_loc_time(numeric_system::standard);
break;
case 'D':
handler.on_us_date();
break;
case 'F':
handler.on_iso_date();
break;
case 'r':
handler.on_12_hour_time();
break;
case 'R':
handler.on_24_hour_time();
break;
case 'T':
handler.on_iso_time();
break;
case 'p':
handler.on_am_pm();
break;
case 'z':
handler.on_utc_offset();
break;
case 'Z':
handler.on_tz_name();
break;
// Alternative representation:
case 'E': {
if (ptr == end)
throw format_error("invalid format");
c = *ptr++;
switch (c) {
case 'c':
handler.on_datetime(numeric_system::alternative);
break;
case 'x':
handler.on_loc_date(numeric_system::alternative);
break;
case 'X':
handler.on_loc_time(numeric_system::alternative);
break;
default:
throw format_error("invalid format");
}
break;
}
case 'O':
if (ptr == end)
throw format_error("invalid format");
c = *ptr++;
switch (c) {
case 'w':
handler.on_dec0_weekday(numeric_system::alternative);
break;
case 'u':
handler.on_dec1_weekday(numeric_system::alternative);
break;
case 'H':
handler.on_24_hour(numeric_system::alternative);
break;
case 'I':
handler.on_12_hour(numeric_system::alternative);
break;
case 'M':
handler.on_minute(numeric_system::alternative);
break;
case 'S':
handler.on_second(numeric_system::alternative);
break;
default:
throw format_error("invalid format");
}
break;
default:
throw format_error("invalid format");
}
break;
default:
throw format_error("invalid format");
}
begin = ptr;
}
@ -213,7 +215,8 @@ struct chrono_format_checker {
template <typename Int>
inline int to_int(Int value) {
FMT_ASSERT(value >= (std::numeric_limits<int>::min)() &&
value <= (std::numeric_limits<int>::max)(), "invalid value");
value <= (std::numeric_limits<int>::max)(),
"invalid value");
return static_cast<int>(value);
}
@ -227,7 +230,7 @@ struct chrono_formatter {
typedef typename FormatContext::char_type char_type;
explicit chrono_formatter(FormatContext &ctx)
: context(ctx), out(ctx.out()) {}
: context(ctx), out(ctx.out()) {}
int hour() const { return to_int((s.count() / 3600) % 24); }
@ -341,30 +344,84 @@ struct chrono_formatter {
};
} // namespace internal
template <typename Period> FMT_CONSTEXPR const char *get_units() {
template <typename Period>
FMT_CONSTEXPR const char *get_units() {
return FMT_NULL;
}
template <> FMT_CONSTEXPR const char *get_units<std::atto>() { return "as"; }
template <> FMT_CONSTEXPR const char *get_units<std::femto>() { return "fs"; }
template <> FMT_CONSTEXPR const char *get_units<std::pico>() { return "ps"; }
template <> FMT_CONSTEXPR const char *get_units<std::nano>() { return "ns"; }
template <> FMT_CONSTEXPR const char *get_units<std::micro>() { return "µs"; }
template <> FMT_CONSTEXPR const char *get_units<std::milli>() { return "ms"; }
template <> FMT_CONSTEXPR const char *get_units<std::centi>() { return "cs"; }
template <> FMT_CONSTEXPR const char *get_units<std::deci>() { return "ds"; }
template <> FMT_CONSTEXPR const char *get_units<std::ratio<1>>() { return "s"; }
template <> FMT_CONSTEXPR const char *get_units<std::deca>() { return "das"; }
template <> FMT_CONSTEXPR const char *get_units<std::hecto>() { return "hs"; }
template <> FMT_CONSTEXPR const char *get_units<std::kilo>() { return "ks"; }
template <> FMT_CONSTEXPR const char *get_units<std::mega>() { return "Ms"; }
template <> FMT_CONSTEXPR const char *get_units<std::giga>() { return "Gs"; }
template <> FMT_CONSTEXPR const char *get_units<std::tera>() { return "Ts"; }
template <> FMT_CONSTEXPR const char *get_units<std::peta>() { return "Ps"; }
template <> FMT_CONSTEXPR const char *get_units<std::exa>() { return "Es"; }
template <> FMT_CONSTEXPR const char *get_units<std::ratio<60>>() {
template <>
FMT_CONSTEXPR const char *get_units<std::atto>() {
return "as";
}
template <>
FMT_CONSTEXPR const char *get_units<std::femto>() {
return "fs";
}
template <>
FMT_CONSTEXPR const char *get_units<std::pico>() {
return "ps";
}
template <>
FMT_CONSTEXPR const char *get_units<std::nano>() {
return "ns";
}
template <>
FMT_CONSTEXPR const char *get_units<std::micro>() {
return "µs";
}
template <>
FMT_CONSTEXPR const char *get_units<std::milli>() {
return "ms";
}
template <>
FMT_CONSTEXPR const char *get_units<std::centi>() {
return "cs";
}
template <>
FMT_CONSTEXPR const char *get_units<std::deci>() {
return "ds";
}
template <>
FMT_CONSTEXPR const char *get_units<std::ratio<1>>() {
return "s";
}
template <>
FMT_CONSTEXPR const char *get_units<std::deca>() {
return "das";
}
template <>
FMT_CONSTEXPR const char *get_units<std::hecto>() {
return "hs";
}
template <>
FMT_CONSTEXPR const char *get_units<std::kilo>() {
return "ks";
}
template <>
FMT_CONSTEXPR const char *get_units<std::mega>() {
return "Ms";
}
template <>
FMT_CONSTEXPR const char *get_units<std::giga>() {
return "Gs";
}
template <>
FMT_CONSTEXPR const char *get_units<std::tera>() {
return "Ts";
}
template <>
FMT_CONSTEXPR const char *get_units<std::peta>() {
return "Ps";
}
template <>
FMT_CONSTEXPR const char *get_units<std::exa>() {
return "Es";
}
template <>
FMT_CONSTEXPR const char *get_units<std::ratio<60>>() {
return "m";
}
template <> FMT_CONSTEXPR const char *get_units<std::ratio<3600>>() {
template <>
FMT_CONSTEXPR const char *get_units<std::ratio<3600>>() {
return "h";
}
@ -409,10 +466,12 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
FMT_CONSTEXPR auto parse(basic_parse_context<Char> &ctx)
-> decltype(ctx.begin()) {
auto begin = ctx.begin(), end = ctx.end();
if (begin == end) return begin;
if (begin == end)
return begin;
spec_handler handler{*this, ctx};
begin = internal::parse_align(begin, end, handler);
if (begin == end) return begin;
if (begin == end)
return begin;
begin = internal::parse_width(begin, end, handler);
end = parse_chrono_format(begin, end, internal::chrono_format_checker());
format_str = basic_string_view<Char>(&*begin, end - begin);
@ -420,8 +479,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
}
template <typename FormatContext>
auto format(const duration &d, FormatContext &ctx)
-> decltype(ctx.out()) {
auto format(const duration &d, FormatContext &ctx) -> decltype(ctx.out()) {
auto begin = format_str.begin(), end = format_str.end();
if (begin == end || *begin == '}') {
memory_buffer buf;
@ -433,8 +491,8 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
format_to(buf, "{}[{}/{}]s", d.count(), Period::num, Period::den);
typedef output_range<decltype(ctx.out()), Char> range;
basic_writer<range> w(range(ctx.out()));
internal::handle_dynamic_spec<internal::width_checker>(
spec.width_, width_ref, ctx);
internal::handle_dynamic_spec<internal::width_checker>(spec.width_,
width_ref, ctx);
w.write(buf.data(), buf.size(), spec);
return w.out();
}

View File

@ -20,12 +20,12 @@ FMT_API void vprint_colored(color c, string_view format, format_args args);
FMT_API void vprint_colored(color c, wstring_view format, wformat_args args);
template <typename... Args>
inline void print_colored(color c, string_view format_str,
const Args & ... args) {
const Args&... args) {
vprint_colored(c, format_str, make_format_args(args...));
}
template <typename... Args>
inline void print_colored(color c, wstring_view format_str,
const Args & ... args) {
const Args&... args) {
vprint_colored(c, format_str, make_format_args<wformat_context>(args...));
}
@ -47,6 +47,8 @@ inline void vprint_colored(color c, wstring_view format, wformat_args args) {
#else
// clang-format off
enum class color : uint32_t {
alice_blue = 0xF0F8FF, // rgb(240,248,255)
antique_white = 0xFAEBD7, // rgb(250,235,215)
@ -191,6 +193,8 @@ enum class color : uint32_t {
yellow_green = 0x9ACD32 // rgb(154,205,50)
}; // enum class color
// clang-format on
enum class terminal_color : uint8_t {
black = 30,
red,
@ -223,12 +227,13 @@ enum class emphasis : uint8_t {
struct rgb {
FMT_CONSTEXPR_DECL rgb() : r(0), g(0), b(0) {}
FMT_CONSTEXPR_DECL rgb(uint8_t r_, uint8_t g_, uint8_t b_)
: r(r_), g(g_), b(b_) {}
: r(r_), g(g_), b(b_) {}
FMT_CONSTEXPR_DECL rgb(uint32_t hex)
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b((hex) & 0xFF) {}
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b((hex)&0xFF) {}
FMT_CONSTEXPR_DECL rgb(color hex)
: r((uint32_t(hex) >> 16) & 0xFF), g((uint32_t(hex) >> 8) & 0xFF),
b(uint32_t(hex) & 0xFF) {}
: r((uint32_t(hex) >> 16) & 0xFF),
g((uint32_t(hex) >> 8) & 0xFF),
b(uint32_t(hex) & 0xFF) {}
uint8_t r;
uint8_t g;
uint8_t b;
@ -238,18 +243,16 @@ namespace internal {
// color is a struct of either a rgb color or a terminal color.
struct color_type {
FMT_CONSTEXPR color_type() FMT_NOEXCEPT
: is_rgb(), value{} {}
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT
: is_rgb(true), value{} {
FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {}
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true),
value{} {
value.rgb_color = static_cast<uint32_t>(rgb_color);
}
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT
: is_rgb(true), value{} {
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} {
value.rgb_color = (rgb_color.r << 16) + (rgb_color.g << 8) + rgb_color.b;
}
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT
: is_rgb(), value{} {
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(),
value{} {
value.term_color = static_cast<uint8_t>(term_color);
}
bool is_rgb;
@ -258,13 +261,15 @@ struct color_type {
uint32_t rgb_color;
} value;
};
} // namespace internal
} // namespace internal
// Experimental text formatting support.
class text_style {
public:
FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT
: set_foreground_color(), set_background_color(), ems(em) {}
: set_foreground_color(),
set_background_color(),
ems(em) {}
FMT_CONSTEXPR text_style &operator|=(const text_style &rhs) {
if (!set_foreground_color) {
@ -290,8 +295,8 @@ class text_style {
return *this;
}
friend FMT_CONSTEXPR
text_style operator|(text_style lhs, const text_style &rhs) {
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
const text_style &rhs) {
return lhs |= rhs;
}
@ -319,8 +324,8 @@ class text_style {
return *this;
}
friend FMT_CONSTEXPR
text_style operator&(text_style lhs, const text_style &rhs) {
friend FMT_CONSTEXPR text_style operator&(text_style lhs,
const text_style &rhs) {
return lhs &= rhs;
}
@ -346,20 +351,20 @@ class text_style {
return ems;
}
private:
FMT_CONSTEXPR text_style(bool is_foreground,
internal::color_type text_color) FMT_NOEXCEPT
: set_foreground_color(),
set_background_color(),
ems() {
if (is_foreground) {
foreground_color = text_color;
set_foreground_color = true;
} else {
background_color = text_color;
set_background_color = true;
}
}
private:
FMT_CONSTEXPR text_style(bool is_foreground,
internal::color_type text_color) FMT_NOEXCEPT
: set_foreground_color(),
set_background_color(),
ems() {
if (is_foreground) {
foreground_color = text_color;
set_foreground_color = true;
} else {
background_color = text_color;
set_background_color = true;
}
}
friend FMT_CONSTEXPR_DECL text_style fg(internal::color_type foreground)
FMT_NOEXCEPT;
@ -390,7 +395,7 @@ namespace internal {
template <typename Char>
struct ansi_color_escape {
FMT_CONSTEXPR ansi_color_escape(internal::color_type text_color,
const char * esc) FMT_NOEXCEPT {
const char *esc) FMT_NOEXCEPT {
// If we have a terminal color, we need to output another escape code
// sequence.
if (!text_color.is_rgb) {
@ -421,7 +426,7 @@ struct ansi_color_escape {
buffer[i] = static_cast<Char>(esc[i]);
}
rgb color(text_color.value.rgb_color);
to_esc(color.r, buffer + 7, ';');
to_esc(color.r, buffer + 7, ';');
to_esc(color.g, buffer + 11, ';');
to_esc(color.b, buffer + 15, 'm');
buffer[19] = static_cast<Char>(0);
@ -451,7 +456,7 @@ struct ansi_color_escape {
}
FMT_CONSTEXPR operator const Char *() const FMT_NOEXCEPT { return buffer; }
private:
private:
Char buffer[7 + 3 * 4 + 1];
static FMT_CONSTEXPR void to_esc(uint8_t c, Char *out,
@ -464,20 +469,19 @@ private:
};
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char>
make_foreground_color(internal::color_type foreground) FMT_NOEXCEPT {
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
internal::color_type foreground) FMT_NOEXCEPT {
return ansi_color_escape<Char>(foreground, internal::data::FOREGROUND_COLOR);
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char>
make_background_color(internal::color_type background) FMT_NOEXCEPT {
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
internal::color_type background) FMT_NOEXCEPT {
return ansi_color_escape<Char>(background, internal::data::BACKGROUND_COLOR);
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char>
make_emphasis(emphasis em) FMT_NOEXCEPT {
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) FMT_NOEXCEPT {
return ansi_color_escape<Char>(em);
}
@ -509,22 +513,20 @@ template <>
struct is_string<std::FILE *> : std::false_type {};
template <>
struct is_string<const std::FILE *> : std::false_type {};
} // namespace internal
} // namespace internal
template <
typename S, typename Char = typename internal::char_t<S>::type>
template <typename S, typename Char = typename internal::char_t<S>::type>
void vprint(std::FILE *f, const text_style &ts, const S &format,
basic_format_args<typename buffer_context<Char>::type> args) {
bool has_style = false;
if (ts.has_emphasis()) {
has_style = true;
internal::fputs<Char>(
internal::make_emphasis<Char>(ts.get_emphasis()), f);
internal::fputs<Char>(internal::make_emphasis<Char>(ts.get_emphasis()), f);
}
if (ts.has_foreground()) {
has_style = true;
internal::fputs<Char>(
internal::make_foreground_color<Char>(ts.get_foreground()), f);
internal::make_foreground_color<Char>(ts.get_foreground()), f);
}
if (ts.has_background()) {
has_style = true;
@ -564,8 +566,7 @@ typename std::enable_if<internal::is_string<String>::value>::type print(
*/
template <typename String, typename... Args>
typename std::enable_if<internal::is_string<String>::value>::type print(
const text_style &ts, const String &format_str,
const Args &... args) {
const text_style &ts, const String &format_str, const Args &... args) {
return print(stdout, ts, format_str, args...);
}

File diff suppressed because it is too large Load Diff

View File

@ -10,47 +10,46 @@
#include "format.h"
#include <string.h>
#include <cctype>
#include <cerrno>
#include <climits>
#include <cmath>
#include <cstdarg>
#include <cstddef> // for std::ptrdiff_t
#include <cstring>
#include <cstring> // for std::memmove
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
# include <locale>
#include <locale>
#endif
#if FMT_USE_WINDOWS_H
# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN
# endif
# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
# include <windows.h>
# else
# define NOMINMAX
# include <windows.h>
# undef NOMINMAX
# endif
#if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
#define WIN32_LEAN_AND_MEAN
#endif
#if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
#include <windows.h>
#else
#define NOMINMAX
#include <windows.h>
#undef NOMINMAX
#endif
#endif
#if FMT_EXCEPTIONS
# define FMT_TRY try
# define FMT_CATCH(x) catch (x)
#define FMT_TRY try
#define FMT_CATCH(x) catch (x)
#else
# define FMT_TRY if (true)
# define FMT_CATCH(x) if (false)
#define FMT_TRY if (true)
#define FMT_CATCH(x) if (false)
#endif
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4702) // unreachable code
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable : 4702) // unreachable code
// Disable deprecation warning for strerror. The latter is not called but
// MSVC fails to detect it.
# pragma warning(disable: 4996)
#pragma warning(disable : 4996)
#endif
// Dummy implementations of strerror_r and strerror_s called if corresponding
@ -67,7 +66,7 @@ FMT_BEGIN_NAMESPACE
namespace {
#ifndef _MSC_VER
# define FMT_SNPRINTF snprintf
#define FMT_SNPRINTF snprintf
#else // _MSC_VER
inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
va_list args;
@ -76,14 +75,14 @@ inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
va_end(args);
return result;
}
# define FMT_SNPRINTF fmt_snprintf
#define FMT_SNPRINTF fmt_snprintf
#endif // _MSC_VER
#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
# define FMT_SWPRINTF snwprintf
#define FMT_SWPRINTF snwprintf
#else
# define FMT_SWPRINTF swprintf
#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
#define FMT_SWPRINTF swprintf
#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
typedef void (*FormatFunc)(internal::buffer &, int, string_view);
@ -96,8 +95,8 @@ typedef void (*FormatFunc)(internal::buffer &, int, string_view);
// ERANGE - buffer is not large enough to store the error message
// other - failure
// Buffer should be at least of size 1.
int safe_strerror(
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
int safe_strerror(int error_code, char *&buffer,
std::size_t buffer_size) FMT_NOEXCEPT {
FMT_ASSERT(buffer != FMT_NULL && buffer_size != 0, "invalid buffer");
class dispatcher {
@ -132,8 +131,8 @@ int safe_strerror(
// Fallback to strerror_s when strerror_r is not available.
int fallback(int result) {
// If the buffer is full then the message is probably truncated.
return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
ERANGE : result;
return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE
: result;
}
#if !FMT_MSC_VER
@ -147,11 +146,9 @@ int safe_strerror(
public:
dispatcher(int err_code, char *&buf, std::size_t buf_size)
: error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
: error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
int run() {
return handle(strerror_r(error_code_, buffer_, buffer_size_));
}
int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); }
};
return dispatcher(error_code, buffer, buffer_size).run();
}
@ -215,15 +212,15 @@ locale_ref::locale_ref(const Locale &loc) : locale_(&loc) {
template <typename Locale>
Locale locale_ref::get() const {
static_assert(std::is_same<Locale, std::locale>::value, "");
return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
return locale_ ? *static_cast<const std::locale *>(locale_) : std::locale();
}
template <typename Char>
FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
return std::use_facet<std::numpunct<Char> >(
loc.get<std::locale>()).thousands_sep();
}
return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
.thousands_sep();
}
} // namespace internal
#else
template <typename Char>
FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
@ -231,8 +228,8 @@ FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
}
#endif
FMT_FUNC void system_error::init(
int err_code, string_view format_str, format_args args) {
FMT_FUNC void system_error::init(int err_code, string_view format_str,
format_args args) {
error_code_ = err_code;
memory_buffer buffer;
format_system_error(buffer, err_code, vformat(format_str, args));
@ -242,20 +239,19 @@ FMT_FUNC void system_error::init(
namespace internal {
template <typename T>
int char_traits<char>::format_float(
char *buf, std::size_t size, const char *format, int precision, T value) {
return precision < 0 ?
FMT_SNPRINTF(buf, size, format, value) :
FMT_SNPRINTF(buf, size, format, precision, value);
int char_traits<char>::format_float(char *buf, std::size_t size,
const char *format, int precision,
T value) {
return precision < 0 ? FMT_SNPRINTF(buf, size, format, value)
: FMT_SNPRINTF(buf, size, format, precision, value);
}
template <typename T>
int char_traits<wchar_t>::format_float(
wchar_t *buf, std::size_t size, const wchar_t *format, int precision,
T value) {
return precision < 0 ?
FMT_SWPRINTF(buf, size, format, value) :
FMT_SWPRINTF(buf, size, format, precision, value);
int char_traits<wchar_t>::format_float(wchar_t *buf, std::size_t size,
const wchar_t *format, int precision,
T value) {
return precision < 0 ? FMT_SWPRINTF(buf, size, format, value)
: FMT_SWPRINTF(buf, size, format, precision, value);
}
template <typename T>
@ -266,88 +262,79 @@ const char basic_data<T>::DIGITS[] =
"6061626364656667686970717273747576777879"
"8081828384858687888990919293949596979899";
#define FMT_POWERS_OF_10(factor) \
factor * 10, \
factor * 100, \
factor * 1000, \
factor * 10000, \
factor * 100000, \
factor * 1000000, \
factor * 10000000, \
factor * 100000000, \
factor * 1000000000
#define FMT_POWERS_OF_10(factor) \
factor * 10, factor * 100, factor * 1000, factor * 10000, factor * 100000, \
factor * 1000000, factor * 10000000, factor * 100000000, \
factor * 1000000000
template <typename T>
const uint32_t basic_data<T>::POWERS_OF_10_32[] = {
1, FMT_POWERS_OF_10(1)
};
const uint32_t basic_data<T>::POWERS_OF_10_32[] = {1, FMT_POWERS_OF_10(1)};
template <typename T>
const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {
0, FMT_POWERS_OF_10(1)
};
const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {0,
FMT_POWERS_OF_10(1)};
template <typename T>
const uint64_t basic_data<T>::ZERO_OR_POWERS_OF_10_64[] = {
0,
FMT_POWERS_OF_10(1),
FMT_POWERS_OF_10(1000000000ull),
10000000000000000000ull
};
0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ull),
10000000000000000000ull};
// Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
// These are generated by support/compute-powers.py.
template <typename T>
const uint64_t basic_data<T>::POW10_SIGNIFICANDS[] = {
0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
};
// Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
// to significands above.
template <typename T>
const int16_t basic_data<T>::POW10_EXPONENTS[] = {
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
-927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
-635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
-343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
-50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066
};
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
-927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
-635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
-343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
-50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
template <typename T> const char basic_data<T>::FOREGROUND_COLOR[] = "\x1b[38;2;";
template <typename T> const char basic_data<T>::BACKGROUND_COLOR[] = "\x1b[48;2;";
template <typename T> const char basic_data<T>::RESET_COLOR[] = "\x1b[0m";
template <typename T> const wchar_t basic_data<T>::WRESET_COLOR[] = L"\x1b[0m";
template <typename T>
const char basic_data<T>::FOREGROUND_COLOR[] = "\x1b[38;2;";
template <typename T>
const char basic_data<T>::BACKGROUND_COLOR[] = "\x1b[48;2;";
template <typename T>
const char basic_data<T>::RESET_COLOR[] = "\x1b[0m";
template <typename T>
const wchar_t basic_data<T>::WRESET_COLOR[] = L"\x1b[0m";
// A handmade floating-point number f * pow(2, e).
class fp {
@ -356,23 +343,23 @@ class fp {
// All sizes are in bits.
static FMT_CONSTEXPR_DECL const int char_size =
std::numeric_limits<unsigned char>::digits;
std::numeric_limits<unsigned char>::digits;
// Subtract 1 to account for an implicit most significant bit in the
// normalized form.
static FMT_CONSTEXPR_DECL const int double_significand_size =
std::numeric_limits<double>::digits - 1;
std::numeric_limits<double>::digits - 1;
static FMT_CONSTEXPR_DECL const uint64_t implicit_bit =
1ull << double_significand_size;
1ull << double_significand_size;
public:
significand_type f;
int e;
static FMT_CONSTEXPR_DECL const int significand_size =
sizeof(significand_type) * char_size;
sizeof(significand_type) * char_size;
fp(): f(0), e(0) {}
fp(uint64_t f_val, int e_val): f(f_val), e(e_val) {}
fp() : f(0), e(0) {}
fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
// Constructs fp from an IEEE754 double. It is a template to prevent compile
// errors on platforms where double is not IEEE754.
@ -382,7 +369,7 @@ class fp {
typedef std::numeric_limits<Double> limits;
const int double_size = static_cast<int>(sizeof(Double) * char_size);
const int exponent_size =
double_size - double_significand_size - 1; // -1 for sign
double_size - double_significand_size - 1; // -1 for sign
const uint64_t significand_mask = implicit_bit - 1;
const uint64_t exponent_mask = (~0ull >> 1) & ~significand_mask;
const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1;
@ -416,8 +403,8 @@ class fp {
// (lower) or successor (upper). The upper boundary is normalized and lower
// has the same exponent but may be not normalized.
void compute_boundaries(fp &lower, fp &upper) const {
lower = f == implicit_bit ?
fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
lower =
f == implicit_bit ? fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
upper = fp((f << 1) + 1, e - 1);
upper.normalize<1>(); // 1 is to account for the exponent shift above.
lower.f <<= lower.e - upper.e;
@ -432,7 +419,8 @@ inline fp operator-(fp x, fp y) {
}
// Computes an fp number r with r.f = x.f * y.f / pow(2, 64) rounded to nearest
// with half-up tie breaking, r.e = x.e + y.e + 64. Result may not be normalized.
// with half-up tie breaking, r.e = x.e + y.e + 64. Result may not be
// normalized.
FMT_API fp operator*(fp x, fp y);
// Returns cached power (of 10) c_k = c_k.f * pow(2, c_k.e) such that its
@ -452,8 +440,8 @@ FMT_FUNC fp operator*(fp x, fp y) {
FMT_FUNC fp get_cached_power(int min_exponent, int &pow10_exponent) {
const double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10)
int index = static_cast<int>(std::ceil(
(min_exponent + fp::significand_size - 1) * one_over_log2_10));
int index = static_cast<int>(
std::ceil((min_exponent + fp::significand_size - 1) * one_over_log2_10));
// Decimal exponent of the first (smallest) cached power of 10.
const int first_dec_exp = -348;
// Difference between 2 consecutive decimal exponents in cached powers of 10.
@ -463,11 +451,12 @@ FMT_FUNC fp get_cached_power(int min_exponent, int &pow10_exponent) {
return fp(data::POW10_SIGNIFICANDS[index], data::POW10_EXPONENTS[index]);
}
FMT_FUNC bool grisu2_round(
char *buf, ptrdiff_t &size, size_t max_digits, uint64_t delta,
uint64_t remainder, uint64_t exp, uint64_t diff, int &exp10) {
while (remainder < diff && delta - remainder >= exp &&
(remainder + exp < diff || diff - remainder > remainder + exp - diff)) {
FMT_FUNC bool grisu2_round(char *buf, ptrdiff_t &size, size_t max_digits,
uint64_t delta, uint64_t remainder, uint64_t exp,
uint64_t diff, int &exp10) {
while (
remainder < diff && delta - remainder >= exp &&
(remainder + exp < diff || diff - remainder > remainder + exp - diff)) {
--buf[size - 1];
remainder += exp;
}
@ -481,27 +470,58 @@ FMT_FUNC bool grisu2_round(
}
// Generates output using Grisu2 digit-gen algorithm.
FMT_FUNC bool grisu2_gen_digits(
char *buf, ptrdiff_t &size, uint32_t hi, uint64_t lo, int &exp,
uint64_t delta, const fp &one, const fp &diff, size_t max_digits) {
FMT_FUNC bool grisu2_gen_digits(char *buf, ptrdiff_t &size, uint32_t hi,
uint64_t lo, int &exp, uint64_t delta,
const fp &one, const fp &diff,
size_t max_digits) {
// Generate digits for the most significant part (hi).
while (exp > 0) {
uint32_t digit = 0;
// This optimization by miloyip reduces the number of integer divisions by
// one per iteration.
switch (exp) {
case 10: digit = hi / 1000000000; hi %= 1000000000; break;
case 9: digit = hi / 100000000; hi %= 100000000; break;
case 8: digit = hi / 10000000; hi %= 10000000; break;
case 7: digit = hi / 1000000; hi %= 1000000; break;
case 6: digit = hi / 100000; hi %= 100000; break;
case 5: digit = hi / 10000; hi %= 10000; break;
case 4: digit = hi / 1000; hi %= 1000; break;
case 3: digit = hi / 100; hi %= 100; break;
case 2: digit = hi / 10; hi %= 10; break;
case 1: digit = hi; hi = 0; break;
default:
FMT_ASSERT(false, "invalid number of digits");
case 10:
digit = hi / 1000000000;
hi %= 1000000000;
break;
case 9:
digit = hi / 100000000;
hi %= 100000000;
break;
case 8:
digit = hi / 10000000;
hi %= 10000000;
break;
case 7:
digit = hi / 1000000;
hi %= 1000000;
break;
case 6:
digit = hi / 100000;
hi %= 100000;
break;
case 5:
digit = hi / 10000;
hi %= 10000;
break;
case 4:
digit = hi / 1000;
hi %= 1000;
break;
case 3:
digit = hi / 100;
hi %= 100;
break;
case 2:
digit = hi / 10;
hi %= 10;
break;
case 1:
digit = hi;
hi = 0;
break;
default:
FMT_ASSERT(false, "invalid number of digits");
}
if (digit != 0 || size != 0)
buf[size++] = static_cast<char>('0' + digit);
@ -509,9 +529,9 @@ FMT_FUNC bool grisu2_gen_digits(
uint64_t remainder = (static_cast<uint64_t>(hi) << -one.e) + lo;
if (remainder <= delta || size > static_cast<ptrdiff_t>(max_digits)) {
return grisu2_round(
buf, size, max_digits, delta, remainder,
static_cast<uint64_t>(data::POWERS_OF_10_32[exp]) << -one.e,
diff.f, exp);
buf, size, max_digits, delta, remainder,
static_cast<uint64_t>(data::POWERS_OF_10_32[exp]) << -one.e, diff.f,
exp);
}
}
// Generate digits for the least significant part (lo).
@ -531,11 +551,11 @@ FMT_FUNC bool grisu2_gen_digits(
}
#if FMT_CLANG_VERSION
# define FMT_FALLTHROUGH [[clang::fallthrough]];
#define FMT_FALLTHROUGH [[clang::fallthrough]];
#elif FMT_GCC_VERSION >= 700
# define FMT_FALLTHROUGH [[gnu::fallthrough]];
#define FMT_FALLTHROUGH [[gnu::fallthrough]];
#else
# define FMT_FALLTHROUGH
#define FMT_FALLTHROUGH
#endif
struct gen_digits_params {
@ -551,7 +571,7 @@ struct prettify_handler {
buffer &buf;
explicit prettify_handler(buffer &b, ptrdiff_t n)
: data(b.data()), size(n), buf(b) {}
: data(b.data()), size(n), buf(b) {}
~prettify_handler() {
assert(buf.size() >= to_unsigned(size));
buf.resize(to_unsigned(size));
@ -616,8 +636,8 @@ struct fill {
// The number is given as v = f * pow(10, exp), where f has size digits.
template <typename Handler>
FMT_FUNC void grisu2_prettify(const gen_digits_params &params,
int size, int exp, Handler &&handler) {
FMT_FUNC void grisu2_prettify(const gen_digits_params &params, int size,
int exp, Handler &&handler) {
if (!params.fixed) {
// Insert a decimal point after the first digit and add an exponent.
handler.insert(1, '.');
@ -660,7 +680,9 @@ struct char_counter {
ptrdiff_t size;
template <typename F>
void insert(ptrdiff_t, ptrdiff_t n, F) { size += n; }
void insert(ptrdiff_t, ptrdiff_t n, F) {
size += n;
}
void insert(ptrdiff_t, char) { ++size; }
void append(ptrdiff_t n, char) { size += n; }
void append(char) { ++size; }
@ -675,34 +697,35 @@ FMT_FUNC gen_digits_params process_specs(const core_format_specs &specs,
auto params = gen_digits_params();
int num_digits = specs.precision >= 0 ? specs.precision : 6;
switch (specs.type) {
case 'G':
params.upper = true;
FMT_FALLTHROUGH
case '\0': case 'g':
params.trailing_zeros = (specs.flags & HASH_FLAG) != 0;
if (-4 <= exp && exp < num_digits + 1) {
case 'G':
params.upper = true;
FMT_FALLTHROUGH
case '\0':
case 'g':
params.trailing_zeros = (specs.flags & HASH_FLAG) != 0;
if (-4 <= exp && exp < num_digits + 1) {
params.fixed = true;
if (!specs.type && params.trailing_zeros && exp >= 0)
num_digits = exp + 1;
}
break;
case 'F':
params.upper = true;
FMT_FALLTHROUGH
case 'f': {
params.fixed = true;
if (!specs.type && params.trailing_zeros && exp >= 0)
num_digits = exp + 1;
params.trailing_zeros = true;
int adjusted_min_digits = num_digits + exp;
if (adjusted_min_digits > 0)
num_digits = adjusted_min_digits;
break;
}
break;
case 'F':
params.upper = true;
FMT_FALLTHROUGH
case 'f': {
params.fixed = true;
params.trailing_zeros = true;
int adjusted_min_digits = num_digits + exp;
if (adjusted_min_digits > 0)
num_digits = adjusted_min_digits;
break;
}
case 'E':
params.upper = true;
FMT_FALLTHROUGH
case 'e':
++num_digits;
break;
case 'E':
params.upper = true;
FMT_FALLTHROUGH
case 'e':
++num_digits;
break;
}
params.num_digits = to_unsigned(num_digits);
char_counter counter{num_digits};
@ -713,7 +736,7 @@ FMT_FUNC gen_digits_params process_specs(const core_format_specs &specs,
template <typename Double>
FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
grisu2_format(Double value, buffer &buf, core_format_specs specs) {
grisu2_format(Double value, buffer &buf, core_format_specs specs) {
FMT_ASSERT(value >= 0, "value is negative");
if (value == 0) {
gen_digits_params params = process_specs(specs, 1, buf);
@ -728,13 +751,13 @@ FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
fp_value.compute_boundaries(lower, upper);
// Find a cached power of 10 close to 1 / upper and use it to scale upper.
const int min_exp = -60; // alpha in Grisu.
int cached_exp = 0; // K in Grisu.
const int min_exp = -60; // alpha in Grisu.
int cached_exp = 0; // K in Grisu.
auto cached_pow = get_cached_power( // \tilde{c}_{-k} in Grisu.
min_exp - (upper.e + fp::significand_size), cached_exp);
cached_exp = -cached_exp;
upper = upper * cached_pow; // \tilde{M}^+ in Grisu.
--upper.f; // \tilde{M}^+ - 1 ulp -> M^+_{\downarrow}.
--upper.f; // \tilde{M}^+ - 1 ulp -> M^+_{\downarrow}.
fp one(1ull << -upper.e, upper.e);
// hi (p1 in Grisu) contains the most significant digits of scaled_upper.
// hi = floor(upper / one).
@ -744,9 +767,9 @@ FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
fp_value.normalize();
fp scaled_value = fp_value * cached_pow;
lower = lower * cached_pow; // \tilde{M}^- in Grisu.
++lower.f; // \tilde{M}^- + 1 ulp -> M^-_{\uparrow}.
++lower.f; // \tilde{M}^- + 1 ulp -> M^-_{\uparrow}.
uint64_t delta = upper.f - lower.f;
fp diff = upper - scaled_value; // wp_w in Grisu.
fp diff = upper - scaled_value; // wp_w in Grisu.
// lo (p2 in Grisu) contains the least significants digits of scaled_upper.
// lo = supper % one.
uint64_t lo = upper.f & (one.f - 1);
@ -767,7 +790,7 @@ void sprintf_format(Double value, internal::buffer &buf,
FMT_ASSERT(buf.capacity() != 0, "empty buffer");
// Build format string.
enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg
enum { MAX_FORMAT_SIZE = 10 }; // longest format: %#-*.*Lg
char format[MAX_FORMAT_SIZE];
char *format_ptr = format;
*format_ptr++ = '%';
@ -819,13 +842,13 @@ FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) {
return;
}
int length = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0);
int length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(),
s_size, FMT_NULL, 0);
if (length == 0)
FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
buffer_.resize(length + 1);
length = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size,
&buffer_[0], length);
if (length == 0)
FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
buffer_[length] = 0;
@ -834,7 +857,7 @@ FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) {
FMT_FUNC internal::utf16_to_utf8::utf16_to_utf8(wstring_view s) {
if (int error_code = convert(s)) {
FMT_THROW(windows_error(error_code,
"cannot convert string from UTF-16 to UTF-8"));
"cannot convert string from UTF-16 to UTF-8"));
}
}
@ -849,21 +872,21 @@ FMT_FUNC int internal::utf16_to_utf8::convert(wstring_view s) {
return 0;
}
int length = WideCharToMultiByte(
CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL);
int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0,
FMT_NULL, FMT_NULL);
if (length == 0)
return GetLastError();
buffer_.resize(length + 1);
length = WideCharToMultiByte(
CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL);
length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0],
length, FMT_NULL, FMT_NULL);
if (length == 0)
return GetLastError();
buffer_[length] = 0;
return 0;
}
FMT_FUNC void windows_error::init(
int err_code, string_view format_str, format_args args) {
FMT_FUNC void windows_error::init(int err_code, string_view format_str,
format_args args) {
error_code_ = err_code;
memory_buffer buffer;
internal::format_windows_error(buffer, err_code, vformat(format_str, args));
@ -871,17 +894,18 @@ FMT_FUNC void windows_error::init(
base = std::runtime_error(to_string(buffer));
}
FMT_FUNC void internal::format_windows_error(
internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
FMT_FUNC void internal::format_windows_error(internal::buffer &out,
int error_code,
string_view message) FMT_NOEXCEPT {
FMT_TRY {
wmemory_buffer buf;
buf.resize(inline_buffer_size);
for (;;) {
wchar_t *system_message = &buf[0];
int result = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
system_message, static_cast<uint32_t>(buf.size()), FMT_NULL);
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, FMT_NULL,
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), system_message,
static_cast<uint32_t>(buf.size()), FMT_NULL);
if (result != 0) {
utf16_to_utf8 utf8_message;
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
@ -897,14 +921,15 @@ FMT_FUNC void internal::format_windows_error(
break; // Can't get error message, report error code instead.
buf.resize(buf.size() * 2);
}
} FMT_CATCH(...) {}
}
FMT_CATCH(...) {}
format_error_code(out, error_code, message);
}
#endif // FMT_USE_WINDOWS_H
FMT_FUNC void format_system_error(
internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
FMT_FUNC void format_system_error(internal::buffer &out, int error_code,
string_view message) FMT_NOEXCEPT {
FMT_TRY {
memory_buffer buf;
buf.resize(inline_buffer_size);
@ -922,7 +947,8 @@ FMT_FUNC void format_system_error(
break; // Can't get error message, report error code instead.
buf.resize(buf.size() * 2);
}
} FMT_CATCH(...) {}
}
FMT_CATCH(...) {}
format_error_code(out, error_code, message);
}
@ -930,14 +956,14 @@ FMT_FUNC void internal::error_handler::on_error(const char *message) {
FMT_THROW(format_error(message));
}
FMT_FUNC void report_system_error(
int error_code, fmt::string_view message) FMT_NOEXCEPT {
FMT_FUNC void report_system_error(int error_code,
fmt::string_view message) FMT_NOEXCEPT {
report_error(format_system_error, error_code, message);
}
#if FMT_USE_WINDOWS_H
FMT_FUNC void report_windows_error(
int error_code, fmt::string_view message) FMT_NOEXCEPT {
FMT_FUNC void report_windows_error(int error_code,
fmt::string_view message) FMT_NOEXCEPT {
report_error(internal::format_windows_error, error_code, message);
}
#endif
@ -966,7 +992,7 @@ FMT_FUNC void vprint(wstring_view format_str, wformat_args args) {
FMT_END_NAMESPACE
#ifdef _MSC_VER
# pragma warning(pop)
#pragma warning(pop)
#endif
#endif // FMT_FORMAT_INL_H_

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@
#define FMT_LOCALE_H_
#include "format.h"
#include <locale>
FMT_BEGIN_NAMESPACE
@ -19,9 +20,9 @@ typename buffer_context<Char>::type::iterator vformat_to(
const std::locale &loc, basic_buffer<Char> &buf,
basic_string_view<Char> format_str,
basic_format_args<typename buffer_context<Char>::type> args) {
typedef back_insert_range<basic_buffer<Char> > range;
return vformat_to<arg_formatter<range>>(
buf, to_string_view(format_str), args, internal::locale_ref(loc));
typedef back_insert_range<basic_buffer<Char>> range;
return vformat_to<arg_formatter<range>>(buf, to_string_view(format_str), args,
internal::locale_ref(loc));
}
template <typename Char>
@ -32,7 +33,7 @@ std::basic_string<Char> vformat(
internal::vformat_to(loc, buffer, format_str, args);
return fmt::to_string(buffer);
}
}
} // namespace internal
template <typename S, typename Char = FMT_CHAR(S)>
inline std::basic_string<Char> vformat(
@ -42,27 +43,29 @@ inline std::basic_string<Char> vformat(
}
template <typename S, typename... Args>
inline std::basic_string<FMT_CHAR(S)> format(
const std::locale &loc, const S &format_str, const Args &... args) {
inline std::basic_string<FMT_CHAR(S)> format(const std::locale &loc,
const S &format_str,
const Args &... args) {
return internal::vformat(
loc, to_string_view(format_str),
*internal::checked_args<S, Args...>(format_str, args...));
loc, to_string_view(format_str),
*internal::checked_args<S, Args...>(format_str, args...));
}
template <typename String, typename OutputIt, typename... Args>
inline typename std::enable_if<internal::is_output_iterator<OutputIt>::value,
OutputIt>::type
vformat_to(OutputIt out, const std::locale &loc, const String &format_str,
typename format_args_t<OutputIt, FMT_CHAR(String)>::type args) {
vformat_to(OutputIt out, const std::locale &loc, const String &format_str,
typename format_args_t<OutputIt, FMT_CHAR(String)>::type args) {
typedef output_range<OutputIt, FMT_CHAR(String)> range;
return vformat_to<arg_formatter<range>>(
range(out), to_string_view(format_str), args, internal::locale_ref(loc));
range(out), to_string_view(format_str), args, internal::locale_ref(loc));
}
template <typename OutputIt, typename S, typename... Args>
inline typename std::enable_if<
internal::is_string<S>::value &&
internal::is_output_iterator<OutputIt>::value, OutputIt>::type
inline
typename std::enable_if<internal::is_string<S>::value &&
internal::is_output_iterator<OutputIt>::value,
OutputIt>::type
format_to(OutputIt out, const std::locale &loc, const S &format_str,
const Args &... args) {
internal::check_format_string<Args...>(format_str);

View File

@ -9,6 +9,7 @@
#define FMT_OSTREAM_H_
#include "format.h"
#include <ostream>
FMT_BEGIN_NAMESPACE
@ -53,14 +54,16 @@ struct test_stream : std::basic_ostream<Char> {
void operator<<(null);
};
// Checks if T has a user-defined operator<< (e.g. not a member of std::ostream).
// Checks if T has a user-defined operator<< (e.g. not a member of
// std::ostream).
template <typename T, typename Char>
class is_streamable {
private:
template <typename U>
static decltype(
internal::declval<test_stream<Char>&>()
<< internal::declval<U>(), std::true_type()) test(int);
internal::declval<test_stream<Char> &>() << internal::declval<U>(),
std::true_type())
test(int);
template <typename>
static std::false_type test(...);
@ -101,20 +104,19 @@ void format_value(basic_buffer<Char> &buffer, const T &value) {
// function (not a member of std::ostream).
template <typename T, typename Char>
struct convert_to_int<T, Char, void> {
static const bool value =
convert_to_int<T, Char, int>::value &&
!internal::is_streamable<T, Char>::value;
static const bool value = convert_to_int<T, Char, int>::value &&
!internal::is_streamable<T, Char>::value;
};
// Formats an object of type T that has an overloaded ostream operator<<.
template <typename T, typename Char>
struct formatter<T, Char,
struct formatter<
T,
Char,
typename std::enable_if<
internal::is_streamable<T, Char>::value &&
!internal::format_type<
typename buffer_context<Char>::type, T>::value>::type>
: formatter<basic_string_view<Char>, Char> {
internal::is_streamable<T, Char>::value &&
!internal::format_type<typename buffer_context<Char>::type, T>::value>::
type> : formatter<basic_string_view<Char>, Char> {
template <typename Context>
auto format(const T &value, Context &ctx) -> decltype(ctx.out()) {
basic_memory_buffer<Char> buffer;
@ -125,9 +127,10 @@ struct formatter<T, Char,
};
template <typename Char>
inline void vprint(std::basic_ostream<Char> &os,
basic_string_view<Char> format_str,
basic_format_args<typename buffer_context<Char>::type> args) {
inline void vprint(
std::basic_ostream<Char> &os,
basic_string_view<Char> format_str,
basic_format_args<typename buffer_context<Char>::type> args) {
basic_memory_buffer<Char> buffer;
internal::vformat_to(buffer, format_str, args);
internal::write(os, buffer);
@ -142,9 +145,10 @@ inline void vprint(std::basic_ostream<Char> &os,
\endrst
*/
template <typename S, typename... Args>
inline typename std::enable_if<internal::is_string<S>::value>::type
print(std::basic_ostream<FMT_CHAR(S)> &os, const S &format_str,
const Args & ... args) {
inline typename std::enable_if<internal::is_string<S>::value>::type print(
std::basic_ostream<FMT_CHAR(S)> &os,
const S &format_str,
const Args &... args) {
internal::checked_args<S, Args...> ca(format_str, args...);
vprint(os, to_string_view(format_str), *ca);
}

View File

@ -10,7 +10,7 @@
#if defined(__MINGW32__) || defined(__CYGWIN__)
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
# undef __STRICT_ANSI__
#undef __STRICT_ANSI__
#endif
#include <errno.h>
@ -22,42 +22,42 @@
#include <cstddef>
#if defined __APPLE__ || defined(__FreeBSD__)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
#include <xlocale.h> // for LC_NUMERIC_MASK on OS X
#endif
#include "format.h"
#ifndef FMT_POSIX
# if defined(_WIN32) && !defined(__MINGW32__)
#if defined(_WIN32) && !defined(__MINGW32__)
// Fix warnings about deprecated symbols.
# define FMT_POSIX(call) _##call
# else
# define FMT_POSIX(call) call
# endif
#define FMT_POSIX(call) _##call
#else
#define FMT_POSIX(call) call
#endif
#endif
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) call
# ifdef _WIN32
#define FMT_SYSTEM(call) call
#ifdef _WIN32
// Fix warnings about deprecated symbols.
# define FMT_POSIX_CALL(call) ::_##call
# else
# define FMT_POSIX_CALL(call) ::call
# endif
#define FMT_POSIX_CALL(call) ::_##call
#else
#define FMT_POSIX_CALL(call) ::call
#endif
#endif
// Retries the expression while it evaluates to error_result and errno
// equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY_VAL(result, expression, error_result) \
do { \
result = (expression); \
#define FMT_RETRY_VAL(result, expression, error_result) \
do { \
result = (expression); \
} while (result == error_result && errno == EINTR)
#else
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
#define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
#endif
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
@ -143,13 +143,12 @@ class buffered_file {
buffered_file(const buffered_file &) = delete;
void operator=(const buffered_file &) = delete;
public:
buffered_file(buffered_file &&other) FMT_NOEXCEPT : file_(other.file_) {
other.file_ = FMT_NULL;
}
buffered_file& operator=(buffered_file &&other) {
buffered_file &operator=(buffered_file &&other) {
close();
file_ = other.file_;
other.file_ = FMT_NULL;
@ -167,14 +166,14 @@ class buffered_file {
// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
FMT_API int (fileno)() const;
FMT_API int(fileno)() const;
void vprint(string_view format_str, format_args args) {
fmt::vprint(file_, format_str, args);
}
template <typename... Args>
inline void print(string_view format_str, const Args & ... args) {
inline void print(string_view format_str, const Args &... args) {
vprint(format_str, make_format_args(args...));
}
};
@ -195,9 +194,9 @@ class file {
public:
// Possible values for the oflag argument to the constructor.
enum {
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing.
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing.
};
// Constructs a file object which doesn't represent any file.
@ -211,11 +210,9 @@ class file {
void operator=(const file &) = delete;
public:
file(file &&other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1;
}
file(file &&other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; }
file& operator=(file &&other) {
file &operator=(file &&other) {
close();
fd_ = other.fd_;
other.fd_ = -1;
@ -265,17 +262,17 @@ class file {
// Returns the memory page size.
long getpagesize();
#if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && \
#if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && \
!defined(__ANDROID__) && !defined(__CYGWIN__) && !defined(__OpenBSD__) && \
!defined(__NEWLIB_H__)
# define FMT_LOCALE
#define FMT_LOCALE
#endif
#ifdef FMT_LOCALE
// A "C" numeric locale.
class Locale {
private:
# ifdef _MSC_VER
#ifdef _MSC_VER
typedef _locale_t locale_t;
enum { LC_NUMERIC_MASK = LC_NUMERIC };
@ -284,14 +281,12 @@ class Locale {
return _create_locale(category_mask, locale);
}
static void freelocale(locale_t locale) {
_free_locale(locale);
}
static void freelocale(locale_t locale) { _free_locale(locale); }
static double strtod_l(const char *nptr, char **endptr, _locale_t locale) {
return _strtod_l(nptr, endptr, locale);
}
# endif
#endif
locale_t locale_;

View File

@ -8,11 +8,11 @@
#ifndef FMT_PRINTF_H_
#define FMT_PRINTF_H_
#include "ostream.h"
#include <algorithm> // std::fill_n
#include <limits> // std::numeric_limits
#include "ostream.h"
FMT_BEGIN_NAMESPACE
namespace internal {
@ -24,18 +24,18 @@ class null_terminating_iterator {
public:
typedef std::ptrdiff_t difference_type;
typedef Char value_type;
typedef const Char* pointer;
typedef const Char& reference;
typedef const Char *pointer;
typedef const Char &reference;
typedef std::random_access_iterator_tag iterator_category;
null_terminating_iterator() : ptr_(0), end_(0) {}
FMT_CONSTEXPR null_terminating_iterator(const Char *ptr, const Char *end)
: ptr_(ptr), end_(end) {}
: ptr_(ptr), end_(end) {}
template <typename Range>
FMT_CONSTEXPR explicit null_terminating_iterator(const Range &r)
: ptr_(r.begin()), end_(r.end()) {}
: ptr_(r.begin()), end_(r.end()) {}
FMT_CONSTEXPR null_terminating_iterator &operator=(const Char *ptr) {
assert(ptr <= end_);
@ -43,9 +43,7 @@ class null_terminating_iterator {
return *this;
}
FMT_CONSTEXPR Char operator*() const {
return ptr_ != end_ ? *ptr_ : Char();
}
FMT_CONSTEXPR Char operator*() const { return ptr_ != end_ ? *ptr_ : Char(); }
FMT_CONSTEXPR null_terminating_iterator operator++() {
++ptr_;
@ -76,8 +74,8 @@ class null_terminating_iterator {
return *this;
}
FMT_CONSTEXPR difference_type operator-(
null_terminating_iterator other) const {
FMT_CONSTEXPR difference_type
operator-(null_terminating_iterator other) const {
return ptr_ - other.ptr_;
}
@ -101,7 +99,9 @@ class null_terminating_iterator {
};
template <typename T>
FMT_CONSTEXPR const T *pointer_from(const T *p) { return p; }
FMT_CONSTEXPR const T *pointer_from(const T *p) {
return p;
}
template <typename Char>
FMT_CONSTEXPR const Char *pointer_from(null_terminating_iterator<Char> it) {
@ -162,33 +162,38 @@ struct int_checker<true> {
static bool fits_in_int(int) { return true; }
};
class printf_precision_handler: public function<int> {
class printf_precision_handler : public function<int> {
public:
template <typename T>
typename std::enable_if<std::is_integral<T>::value, int>::type
operator()(T value) {
typename std::enable_if<std::is_integral<T>::value, int>::type operator()(
T value) {
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
FMT_THROW(format_error("number is too big"));
return static_cast<int>(value);
}
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, int>::type operator()(T) {
typename std::enable_if<!std::is_integral<T>::value, int>::type operator()(
T) {
FMT_THROW(format_error("precision is not integer"));
return 0;
}
};
// An argument visitor that returns true iff arg is a zero integer.
class is_zero_int: public function<bool> {
class is_zero_int : public function<bool> {
public:
template <typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
operator()(T value) { return value == 0; }
typename std::enable_if<std::is_integral<T>::value, bool>::type operator()(
T value) {
return value == 0;
}
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, bool>::type
operator()(T) { return false; }
typename std::enable_if<!std::is_integral<T>::value, bool>::type operator()(
T) {
return false;
}
};
template <typename T>
@ -200,7 +205,7 @@ struct make_unsigned_or_bool<bool> {
};
template <typename T, typename Context>
class arg_converter: public function<void> {
class arg_converter : public function<void> {
private:
typedef typename Context::char_type Char;
@ -209,7 +214,7 @@ class arg_converter: public function<void> {
public:
arg_converter(basic_format_arg<Context> &arg, Char type)
: arg_(arg), type_(type) {}
: arg_(arg), type_(type) {}
void operator()(bool value) {
if (type_ != 's')
@ -217,20 +222,20 @@ class arg_converter: public function<void> {
}
template <typename U>
typename std::enable_if<std::is_integral<U>::value>::type
operator()(U value) {
typename std::enable_if<std::is_integral<U>::value>::type operator()(
U value) {
bool is_signed = type_ == 'd' || type_ == 'i';
typedef typename std::conditional<
std::is_same<T, void>::value, U, T>::type TargetType;
typedef typename std::conditional<std::is_same<T, void>::value, U, T>::type
TargetType;
if (const_check(sizeof(TargetType) <= sizeof(int))) {
// Extra casts are used to silence warnings.
if (is_signed) {
arg_ = internal::make_arg<Context>(
static_cast<int>(static_cast<TargetType>(value)));
static_cast<int>(static_cast<TargetType>(value)));
} else {
typedef typename make_unsigned_or_bool<TargetType>::type Unsigned;
arg_ = internal::make_arg<Context>(
static_cast<unsigned>(static_cast<Unsigned>(value)));
static_cast<unsigned>(static_cast<Unsigned>(value)));
}
} else {
if (is_signed) {
@ -240,7 +245,7 @@ class arg_converter: public function<void> {
arg_ = internal::make_arg<Context>(static_cast<long long>(value));
} else {
arg_ = internal::make_arg<Context>(
static_cast<typename make_unsigned_or_bool<U>::type>(value));
static_cast<typename make_unsigned_or_bool<U>::type>(value));
}
}
}
@ -262,7 +267,7 @@ void convert_arg(basic_format_arg<Context> &arg, Char type) {
// Converts an integer argument to char for printf.
template <typename Context>
class char_converter: public function<void> {
class char_converter : public function<void> {
private:
basic_format_arg<Context> &arg_;
@ -270,8 +275,8 @@ class char_converter: public function<void> {
explicit char_converter(basic_format_arg<Context> &arg) : arg_(arg) {}
template <typename T>
typename std::enable_if<std::is_integral<T>::value>::type
operator()(T value) {
typename std::enable_if<std::is_integral<T>::value>::type operator()(
T value) {
typedef typename Context::char_type Char;
arg_ = internal::make_arg<Context>(static_cast<Char>(value));
}
@ -285,7 +290,7 @@ class char_converter: public function<void> {
// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
template <typename Char>
class printf_width_handler: public function<unsigned> {
class printf_width_handler : public function<unsigned> {
private:
typedef basic_format_specs<Char> format_specs;
@ -296,7 +301,7 @@ class printf_width_handler: public function<unsigned> {
template <typename T>
typename std::enable_if<std::is_integral<T>::value, unsigned>::type
operator()(T value) {
operator()(T value) {
typedef typename internal::int_traits<T>::main_type UnsignedType;
UnsignedType width = static_cast<UnsignedType>(value);
if (internal::is_negative(value)) {
@ -311,15 +316,17 @@ class printf_width_handler: public function<unsigned> {
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, unsigned>::type
operator()(T) {
operator()(T) {
FMT_THROW(format_error("width is not integer"));
return 0;
}
};
template <typename Char, typename Context>
void printf(basic_buffer<Char> &buf, basic_string_view<Char> format,
basic_format_args<Context> args) {
void printf(
basic_buffer<Char> &buf,
basic_string_view<Char> format,
basic_format_args<Context> args) {
Context(std::back_inserter(buf), format, args).format();
}
} // namespace internal
@ -330,9 +337,10 @@ template <typename Range>
class printf_arg_formatter;
template <
typename OutputIt, typename Char,
typename OutputIt,
typename Char,
typename ArgFormatter =
printf_arg_formatter<back_insert_range<internal::basic_buffer<Char>>>>
printf_arg_formatter<back_insert_range<internal::basic_buffer<Char>>>>
class basic_printf_context;
/**
@ -341,10 +349,10 @@ class basic_printf_context;
\endrst
*/
template <typename Range>
class printf_arg_formatter:
public internal::function<
typename internal::arg_formatter_base<Range>::iterator>,
public internal::arg_formatter_base<Range> {
class printf_arg_formatter
: public internal::function<
typename internal::arg_formatter_base<Range>::iterator>,
public internal::arg_formatter_base<Range> {
private:
typedef typename Range::value_type char_type;
typedef decltype(internal::declval<Range>().begin()) iterator;
@ -373,15 +381,19 @@ class printf_arg_formatter:
specifier information for standard argument types.
\endrst
*/
printf_arg_formatter(internal::basic_buffer<char_type> &buffer,
format_specs &spec, context_type &ctx)
: base(back_insert_range<internal::basic_buffer<char_type>>(buffer), &spec,
ctx.locale()),
context_(ctx) {}
printf_arg_formatter(
internal::basic_buffer<char_type> &buffer,
format_specs &spec,
context_type &ctx)
: base(
back_insert_range<internal::basic_buffer<char_type>>(buffer),
&spec,
ctx.locale()),
context_(ctx) {}
template <typename T>
typename std::enable_if<std::is_integral<T>::value, iterator>::type
operator()(T value) {
operator()(T value) {
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if (std::is_same<T, bool>::value) {
@ -405,7 +417,7 @@ class printf_arg_formatter:
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, iterator>::type
operator()(T value) {
operator()(T value) {
return base::operator()(value);
}
@ -435,9 +447,7 @@ class printf_arg_formatter:
return base::operator()(value);
}
iterator operator()(monostate value) {
return base::operator()(value);
}
iterator operator()(monostate value) { return base::operator()(value); }
/** Formats a pointer. */
iterator operator()(const void *value) {
@ -458,7 +468,9 @@ class printf_arg_formatter:
template <typename T>
struct printf_formatter {
template <typename ParseContext>
auto parse(ParseContext &ctx) -> decltype(ctx.begin()) { return ctx.begin(); }
auto parse(ParseContext &ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const T &value, FormatContext &ctx) -> decltype(ctx.out()) {
@ -470,16 +482,20 @@ struct printf_formatter {
/** This template formats data and writes the output to a writer. */
template <typename OutputIt, typename Char, typename ArgFormatter>
class basic_printf_context :
// Inherit publicly as a workaround for the icc bug
// https://software.intel.com/en-us/forums/intel-c-compiler/topic/783476.
public internal::context_base<
OutputIt, basic_printf_context<OutputIt, Char, ArgFormatter>, Char> {
// Inherit publicly as a workaround for the icc bug
// https://software.intel.com/en-us/forums/intel-c-compiler/topic/783476.
public internal::context_base<
OutputIt,
basic_printf_context<OutputIt, Char, ArgFormatter>,
Char> {
public:
/** The character type for the output. */
typedef Char char_type;
template <typename T>
struct formatter_type { typedef printf_formatter<T> type; };
struct formatter_type {
typedef printf_formatter<T> type;
};
private:
typedef internal::context_base<OutputIt, basic_printf_context, Char> base;
@ -492,8 +508,7 @@ class basic_printf_context :
// Returns the argument with specified index or, if arg_index is equal
// to the maximum unsigned value, the next argument.
format_arg get_arg(
iterator it,
unsigned arg_index = (std::numeric_limits<unsigned>::max)());
iterator it, unsigned arg_index = (std::numeric_limits<unsigned>::max)());
// Parses argument index, flags and width and returns the argument index.
unsigned parse_header(iterator &it, format_specs &spec);
@ -506,13 +521,15 @@ class basic_printf_context :
appropriate lifetimes.
\endrst
*/
basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
basic_format_args<basic_printf_context> args)
: base(out, format_str, args) {}
basic_printf_context(
OutputIt out,
basic_string_view<char_type> format_str,
basic_format_args<basic_printf_context> args)
: base(out, format_str, args) {}
using base::parse_context;
using base::out;
using base::advance_to;
using base::out;
using base::parse_context;
/** Formats stored arguments and writes the output to the range. */
void format();
@ -547,7 +564,7 @@ void basic_printf_context<OutputIt, Char, AF>::parse_flags(
template <typename OutputIt, typename Char, typename AF>
typename basic_printf_context<OutputIt, Char, AF>::format_arg
basic_printf_context<OutputIt, Char, AF>::get_arg(
basic_printf_context<OutputIt, Char, AF>::get_arg(
iterator it, unsigned arg_index) {
(void)it;
if (arg_index == std::numeric_limits<unsigned>::max())
@ -557,7 +574,7 @@ typename basic_printf_context<OutputIt, Char, AF>::format_arg
template <typename OutputIt, typename Char, typename AF>
unsigned basic_printf_context<OutputIt, Char, AF>::parse_header(
iterator &it, format_specs &spec) {
iterator &it, format_specs &spec) {
unsigned arg_index = std::numeric_limits<unsigned>::max();
char_type c = *it;
if (c >= '0' && c <= '9') {
@ -587,7 +604,7 @@ unsigned basic_printf_context<OutputIt, Char, AF>::parse_header(
} else if (*it == '*') {
++it;
spec.width_ = visit_format_arg(
internal::printf_width_handler<char_type>(spec), get_arg(it));
internal::printf_width_handler<char_type>(spec), get_arg(it));
}
return arg_index;
}
@ -600,7 +617,8 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
using internal::pointer_from;
while (*it) {
char_type c = *it++;
if (c != '%') continue;
if (c != '%')
continue;
if (*it == c) {
buffer.append(pointer_from(start), pointer_from(it));
start = ++it;
@ -642,34 +660,34 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
// Parse length and convert the argument to the required type.
using internal::convert_arg;
switch (*it++) {
case 'h':
if (*it == 'h')
convert_arg<signed char>(arg, *++it);
else
convert_arg<short>(arg, *it);
break;
case 'l':
if (*it == 'l')
convert_arg<long long>(arg, *++it);
else
convert_arg<long>(arg, *it);
break;
case 'j':
convert_arg<intmax_t>(arg, *it);
break;
case 'z':
convert_arg<std::size_t>(arg, *it);
break;
case 't':
convert_arg<std::ptrdiff_t>(arg, *it);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--it;
convert_arg<void>(arg, *it);
case 'h':
if (*it == 'h')
convert_arg<signed char>(arg, *++it);
else
convert_arg<short>(arg, *it);
break;
case 'l':
if (*it == 'l')
convert_arg<long long>(arg, *++it);
else
convert_arg<long>(arg, *it);
break;
case 'j':
convert_arg<intmax_t>(arg, *it);
break;
case 'z':
convert_arg<std::size_t>(arg, *it);
break;
case 't':
convert_arg<std::ptrdiff_t>(arg, *it);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--it;
convert_arg<void>(arg, *it);
}
// Parse type.
@ -679,14 +697,15 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
if (arg.is_integral()) {
// Normalize type.
switch (spec.type) {
case 'i': case 'u':
spec.type = 'd';
break;
case 'c':
// TODO: handle wchar_t better?
visit_format_arg(
case 'i':
case 'u':
spec.type = 'd';
break;
case 'c':
// TODO: handle wchar_t better?
visit_format_arg(
internal::char_converter<basic_printf_context>(arg), arg);
break;
break;
}
}
@ -701,7 +720,9 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
template <typename Buffer>
struct basic_printf_context_t {
typedef basic_printf_context<
std::back_insert_iterator<Buffer>, typename Buffer::value_type> type;
std::back_insert_iterator<Buffer>,
typename Buffer::value_type>
type;
};
typedef basic_printf_context_t<internal::buffer>::type printf_context;
@ -713,28 +734,33 @@ typedef basic_format_args<wprintf_context> wprintf_args;
/**
\rst
Constructs an `~fmt::format_arg_store` object that contains references to
arguments and can be implicitly converted to `~fmt::printf_args`.
arguments and can be implicitly converted to `~fmt::printf_args`.
\endrst
*/
template<typename... Args>
inline format_arg_store<printf_context, Args...>
make_printf_args(const Args &... args) { return {args...}; }
template <typename... Args>
inline format_arg_store<printf_context, Args...> make_printf_args(
const Args &... args) {
return {args...};
}
/**
\rst
Constructs an `~fmt::format_arg_store` object that contains references to
arguments and can be implicitly converted to `~fmt::wprintf_args`.
arguments and can be implicitly converted to `~fmt::wprintf_args`.
\endrst
*/
template<typename... Args>
inline format_arg_store<wprintf_context, Args...>
make_wprintf_args(const Args &... args) { return {args...}; }
template <typename... Args>
inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
const Args &... args) {
return {args...};
}
template <typename S, typename Char = FMT_CHAR(S)>
inline std::basic_string<Char>
vsprintf(const S &format,
basic_format_args<typename basic_printf_context_t<
internal::basic_buffer<Char>>::type> args) {
inline std::basic_string<Char> vsprintf(
const S &format,
basic_format_args<
typename basic_printf_context_t<internal::basic_buffer<Char>>::type>
args) {
basic_memory_buffer<Char> buffer;
printf(buffer, to_string_view(format), args);
return to_string(buffer);
@ -752,24 +778,27 @@ vsprintf(const S &format,
template <typename S, typename... Args>
inline FMT_ENABLE_IF_T(
internal::is_string<S>::value, std::basic_string<FMT_CHAR(S)>)
sprintf(const S &format, const Args & ... args) {
sprintf(const S &format, const Args &... args) {
internal::check_format_string<Args...>(format);
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
typedef typename basic_printf_context_t<buffer>::type context;
format_arg_store<context, Args...> as{ args... };
return vsprintf(to_string_view(format),
basic_format_args<context>(as));
format_arg_store<context, Args...> as{args...};
return vsprintf(to_string_view(format), basic_format_args<context>(as));
}
template <typename S, typename Char = FMT_CHAR(S)>
inline int vfprintf(std::FILE *f, const S &format,
basic_format_args<typename basic_printf_context_t<
internal::basic_buffer<Char>>::type> args) {
inline int vfprintf(
std::FILE *f,
const S &format,
basic_format_args<
typename basic_printf_context_t<internal::basic_buffer<Char>>::type>
args) {
basic_memory_buffer<Char> buffer;
printf(buffer, to_string_view(format), args);
std::size_t size = buffer.size();
return std::fwrite(
buffer.data(), sizeof(Char), size, f) < size ? -1 : static_cast<int>(size);
return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
? -1
: static_cast<int>(size);
}
/**
@ -783,19 +812,20 @@ inline int vfprintf(std::FILE *f, const S &format,
*/
template <typename S, typename... Args>
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, int)
fprintf(std::FILE *f, const S &format, const Args & ... args) {
fprintf(std::FILE *f, const S &format, const Args &... args) {
internal::check_format_string<Args...>(format);
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
typedef typename basic_printf_context_t<buffer>::type context;
format_arg_store<context, Args...> as{ args... };
return vfprintf(f, to_string_view(format),
basic_format_args<context>(as));
format_arg_store<context, Args...> as{args...};
return vfprintf(f, to_string_view(format), basic_format_args<context>(as));
}
template <typename S, typename Char = FMT_CHAR(S)>
inline int vprintf(const S &format,
basic_format_args<typename basic_printf_context_t<
internal::basic_buffer<Char>>::type> args) {
inline int vprintf(
const S &format,
basic_format_args<
typename basic_printf_context_t<internal::basic_buffer<Char>>::type>
args) {
return vfprintf(stdout, to_string_view(format), args);
}
@ -810,20 +840,21 @@ inline int vprintf(const S &format,
*/
template <typename S, typename... Args>
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, int)
printf(const S &format_str, const Args & ... args) {
printf(const S &format_str, const Args &... args) {
internal::check_format_string<Args...>(format_str);
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
typedef typename basic_printf_context_t<buffer>::type context;
format_arg_store<context, Args...> as{ args... };
return vprintf(to_string_view(format_str),
basic_format_args<context>(as));
format_arg_store<context, Args...> as{args...};
return vprintf(to_string_view(format_str), basic_format_args<context>(as));
}
template <typename S, typename Char = FMT_CHAR(S)>
inline int vfprintf(std::basic_ostream<Char> &os,
const S &format,
basic_format_args<typename basic_printf_context_t<
internal::basic_buffer<Char>>::type> args) {
inline int vfprintf(
std::basic_ostream<Char> &os,
const S &format,
basic_format_args<
typename basic_printf_context_t<internal::basic_buffer<Char>>::type>
args) {
basic_memory_buffer<Char> buffer;
printf(buffer, to_string_view(format), args);
internal::write(os, buffer);
@ -840,15 +871,16 @@ inline int vfprintf(std::basic_ostream<Char> &os,
\endrst
*/
template <typename S, typename... Args>
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, int)
fprintf(std::basic_ostream<FMT_CHAR(S)> &os,
const S &format_str, const Args & ... args) {
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, int) fprintf(
std::basic_ostream<FMT_CHAR(S)> &os,
const S &format_str,
const Args &... args) {
internal::check_format_string<Args...>(format_str);
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
typedef typename basic_printf_context_t<buffer>::type context;
format_arg_store<context, Args...> as{ args... };
return vfprintf(os, to_string_view(format_str),
basic_format_args<context>(as));
format_arg_store<context, Args...> as{args...};
return vfprintf(
os, to_string_view(format_str), basic_format_args<context>(as));
}
FMT_END_NAMESPACE

View File

@ -13,11 +13,12 @@
#define FMT_RANGES_H_
#include "format.h"
#include <type_traits>
// output only up to N items from the range.
#ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT
# define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
#define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
#endif
FMT_BEGIN_NAMESPACE
@ -33,7 +34,8 @@ struct formatting_base {
template <typename Char, typename Enable = void>
struct formatting_range : formatting_base<Char> {
static FMT_CONSTEXPR_DECL const std::size_t range_length_limit =
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the range.
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the
// range.
Char prefix;
Char delimiter;
Char postfix;
@ -77,14 +79,14 @@ void copy(char ch, OutputIterator out) {
template <typename T>
class is_like_std_string {
template <typename U>
static auto check(U *p) ->
decltype(p->find('a'), p->length(), p->data(), int());
static auto check(U *p)
-> decltype(p->find('a'), p->length(), p->data(), int());
template <typename>
static void check(...);
public:
static FMT_CONSTEXPR_DECL const bool value =
!std::is_void<decltype(check<T>(FMT_NULL))>::value;
!std::is_void<decltype(check<T>(FMT_NULL))>::value;
};
template <typename Char>
@ -98,26 +100,30 @@ struct is_range_ : std::false_type {};
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
template <typename T>
struct is_range_<T, typename std::conditional<
false,
conditional_helper<decltype(internal::declval<T>().begin()),
decltype(internal::declval<T>().end())>,
void>::type> : std::true_type {};
struct is_range_<
T,
typename std::conditional<
false,
conditional_helper<
decltype(internal::declval<T>().begin()),
decltype(internal::declval<T>().end())>,
void>::type> : std::true_type {};
#endif
/// tuple_size and tuple_element check.
template <typename T>
class is_tuple_like_ {
template <typename U>
static auto check(U *p) ->
decltype(std::tuple_size<U>::value,
internal::declval<typename std::tuple_element<0, U>::type>(), int());
static auto check(U *p) -> decltype(
std::tuple_size<U>::value,
internal::declval<typename std::tuple_element<0, U>::type>(),
int());
template <typename>
static void check(...);
public:
static FMT_CONSTEXPR_DECL const bool value =
!std::is_void<decltype(check<T>(FMT_NULL))>::value;
!std::is_void<decltype(check<T>(FMT_NULL))>::value;
};
// Check for integer_sequence
@ -133,9 +139,7 @@ template <typename T, T... N>
struct integer_sequence {
typedef T value_type;
static FMT_CONSTEXPR std::size_t size() {
return sizeof...(N);
}
static FMT_CONSTEXPR std::size_t size() { return sizeof...(N); }
};
template <std::size_t... N>
@ -159,8 +163,10 @@ void for_each(index_sequence<Is...>, Tuple &&tup, F &&f) FMT_NOEXCEPT {
}
template <class T>
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value>
get_indexes(T const &) { return {}; }
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value> get_indexes(
T const &) {
return {};
}
template <class Tuple, class F>
void for_each(Tuple &&tup, F &&f) {
@ -168,32 +174,39 @@ void for_each(Tuple &&tup, F &&f) {
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
}
template<typename Arg>
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&,
typename std::enable_if<
!is_like_std_string<typename std::decay<Arg>::type>::value>::type* = nullptr) {
template <typename Arg>
FMT_CONSTEXPR const char *format_str_quoted(
bool add_space,
const Arg &,
typename std::enable_if<
!is_like_std_string<typename std::decay<Arg>::type>::value>::type * =
nullptr) {
return add_space ? " {}" : "{}";
}
template<typename Arg>
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&,
typename std::enable_if<
is_like_std_string<typename std::decay<Arg>::type>::value>::type* = nullptr) {
template <typename Arg>
FMT_CONSTEXPR const char *format_str_quoted(
bool add_space,
const Arg &,
typename std::enable_if<
is_like_std_string<typename std::decay<Arg>::type>::value>::type * =
nullptr) {
return add_space ? " \"{}\"" : "\"{}\"";
}
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char*) {
FMT_CONSTEXPR const char *format_str_quoted(bool add_space, const char *) {
return add_space ? " \"{}\"" : "\"{}\"";
}
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t*) {
return add_space ? L" \"{}\"" : L"\"{}\"";
FMT_CONSTEXPR const wchar_t *format_str_quoted(
bool add_space, const wchar_t *) {
return add_space ? L" \"{}\"" : L"\"{}\"";
}
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char) {
return add_space ? " '{}'" : "'{}'";
FMT_CONSTEXPR const char *format_str_quoted(bool add_space, const char) {
return add_space ? " '{}'" : "'{}'";
}
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) {
return add_space ? L" '{}'" : L"'{}'";
FMT_CONSTEXPR const wchar_t *format_str_quoted(bool add_space, const wchar_t) {
return add_space ? L" '{}'" : L"'{}'";
}
} // namespace internal
@ -201,37 +214,41 @@ FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) {
template <typename T>
struct is_tuple_like {
static FMT_CONSTEXPR_DECL const bool value =
internal::is_tuple_like_<T>::value && !internal::is_range_<T>::value;
internal::is_tuple_like_<T>::value && !internal::is_range_<T>::value;
};
template <typename TupleT, typename Char>
struct formatter<TupleT, Char,
struct formatter<
TupleT,
Char,
typename std::enable_if<fmt::is_tuple_like<TupleT>::value>::type> {
private:
private:
// C++11 generic lambda for format()
template <typename FormatContext>
struct format_each {
template <typename T>
void operator()(const T& v) {
void operator()(const T &v) {
if (i > 0) {
if (formatting.add_prepostfix_space) {
*out++ = ' ';
}
internal::copy(formatting.delimiter, out);
}
format_to(out,
internal::format_str_quoted(
(formatting.add_delimiter_spaces && i > 0), v),
v);
format_to(
out,
internal::format_str_quoted(
(formatting.add_delimiter_spaces && i > 0), v),
v);
++i;
}
formatting_tuple<Char>& formatting;
std::size_t& i;
typename std::add_lvalue_reference<decltype(std::declval<FormatContext>().out())>::type out;
formatting_tuple<Char> &formatting;
std::size_t &i;
typename std::add_lvalue_reference<decltype(
std::declval<FormatContext>().out())>::type out;
};
public:
public:
formatting_tuple<Char> formatting;
template <typename ParseContext>
@ -258,13 +275,14 @@ public:
template <typename T>
struct is_range {
static FMT_CONSTEXPR_DECL const bool value =
internal::is_range_<T>::value && !internal::is_like_std_string<T>::value;
internal::is_range_<T>::value && !internal::is_like_std_string<T>::value;
};
template <typename RangeT, typename Char>
struct formatter<RangeT, Char,
struct formatter<
RangeT,
Char,
typename std::enable_if<fmt::is_range<RangeT>::value>::type> {
formatting_range<Char> formatting;
template <typename ParseContext>
@ -285,10 +303,11 @@ struct formatter<RangeT, Char,
}
internal::copy(formatting.delimiter, out);
}
format_to(out,
internal::format_str_quoted(
(formatting.add_delimiter_spaces && i > 0), *it),
*it);
format_to(
out,
internal::format_str_quoted(
(formatting.add_delimiter_spaces && i > 0), *it),
*it);
if (++i > formatting.range_length_limit) {
format_to(out, " ... <other elements>");
break;
@ -304,5 +323,4 @@ struct formatter<RangeT, Char,
FMT_END_NAMESPACE
#endif // FMT_RANGES_H_
#endif // FMT_RANGES_H_

View File

@ -9,6 +9,7 @@
#define FMT_TIME_H_
#include "format.h"
#include <ctime>
#include <locale>
@ -18,7 +19,7 @@ FMT_BEGIN_NAMESPACE
// Usage: f FMT_NOMACRO()
#define FMT_NOMACRO
namespace internal{
namespace internal {
inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
inline null<> localtime_s(...) { return null<>(); }
inline null<> gmtime_r(...) { return null<>(); }
@ -31,7 +32,7 @@ inline std::tm localtime(std::time_t time) {
std::time_t time_;
std::tm tm_;
dispatcher(std::time_t t): time_(t) {}
dispatcher(std::time_t t) : time_(t) {}
bool run() {
using namespace fmt::internal;
@ -51,7 +52,8 @@ inline std::tm localtime(std::time_t time) {
bool fallback(internal::null<>) {
using namespace fmt::internal;
std::tm *tm = std::localtime(&time_);
if (tm) tm_ = *tm;
if (tm)
tm_ = *tm;
return tm != FMT_NULL;
}
#endif
@ -69,7 +71,7 @@ inline std::tm gmtime(std::time_t time) {
std::time_t time_;
std::tm tm_;
dispatcher(std::time_t t): time_(t) {}
dispatcher(std::time_t t) : time_(t) {}
bool run() {
using namespace fmt::internal;
@ -88,7 +90,8 @@ inline std::tm gmtime(std::time_t time) {
#if !FMT_MSC_VER
bool fallback(internal::null<>) {
std::tm *tm = std::gmtime(&time_);
if (tm) tm_ = *tm;
if (tm)
tm_ = *tm;
return tm != FMT_NULL;
}
#endif
@ -101,16 +104,19 @@ inline std::tm gmtime(std::time_t time) {
}
namespace internal {
inline std::size_t strftime(char *str, std::size_t count, const char *format,
const std::tm *time) {
inline std::size_t strftime(
char *str, std::size_t count, const char *format, const std::tm *time) {
return std::strftime(str, count, format, time);
}
inline std::size_t strftime(wchar_t *str, std::size_t count,
const wchar_t *format, const std::tm *time) {
inline std::size_t strftime(
wchar_t *str,
std::size_t count,
const wchar_t *format,
const std::tm *time) {
return std::wcsftime(str, count, format, time);
}
}
} // namespace internal
template <typename Char>
struct formatter<std::tm, Char> {
@ -120,8 +126,7 @@ struct formatter<std::tm, Char> {
if (it != ctx.end() && *it == ':')
++it;
auto end = it;
while (end != ctx.end() && *end != '}')
++end;
while (end != ctx.end() && *end != '}') ++end;
tm_format.reserve(end - it + 1);
tm_format.append(it, end);
tm_format.push_back('\0');
@ -135,7 +140,7 @@ struct formatter<std::tm, Char> {
for (;;) {
std::size_t size = buf.capacity() - start;
std::size_t count =
internal::strftime(&buf[start], size, &tm_format[0], &tm);
internal::strftime(&buf[start], size, &tm_format[0], &tm);
if (count != 0) {
buf.resize(start + count);
break;

View File

@ -16,7 +16,8 @@ template FMT_API std::locale internal::locale_ref::get<std::locale>() const;
template FMT_API char internal::thousands_sep_impl(locale_ref);
template FMT_API void internal::basic_buffer<char>::append(const char *, const char *);
template FMT_API void internal::basic_buffer<char>::append(
const char *, const char *);
template FMT_API void internal::arg_map<format_context>::init(
const basic_format_args<format_context> &args);

View File

@ -7,43 +7,43 @@
// Disable bogus MSVC warnings.
#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)
# define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "fmt/posix.h"
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
# include <unistd.h>
#include <unistd.h>
#else
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <io.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <io.h>
#include <windows.h>
# define O_CREAT _O_CREAT
# define O_TRUNC _O_TRUNC
#define O_CREAT _O_CREAT
#define O_TRUNC _O_TRUNC
# ifndef S_IRUSR
# define S_IRUSR _S_IREAD
# endif
#ifndef S_IRUSR
#define S_IRUSR _S_IREAD
#endif
# ifndef S_IWUSR
# define S_IWUSR _S_IWRITE
# endif
#ifndef S_IWUSR
#define S_IWUSR _S_IWRITE
#endif
# ifdef __MINGW32__
# define _SH_DENYNO 0x40
# endif
#ifdef __MINGW32__
#define _SH_DENYNO 0x40
#endif
#endif // _WIN32
#ifdef fileno
# undef fileno
#undef fileno
#endif
namespace {
@ -62,7 +62,7 @@ typedef ssize_t RWResult;
inline std::size_t convert_rwcount(std::size_t count) { return count; }
#endif
}
} // namespace
FMT_BEGIN_NAMESPACE
@ -72,8 +72,8 @@ buffered_file::~buffered_file() FMT_NOEXCEPT {
}
buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
FMT_RETRY_VAL(file_,
FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), FMT_NULL);
FMT_RETRY_VAL(
file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), FMT_NULL);
if (!file_)
FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str()));
}
@ -147,7 +147,8 @@ long long file::size() const {
Stat file_stat = Stat();
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
FMT_THROW(system_error(errno, "cannot get file attributes"));
static_assert(sizeof(long long) >= sizeof(file_stat.st_size),
static_assert(
sizeof(long long) >= sizeof(file_stat.st_size),
"return type of file::size is not large enough");
return file_stat.st_size;
#endif
@ -182,8 +183,8 @@ void file::dup2(int fd) {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) {
FMT_THROW(system_error(errno,
"cannot duplicate file descriptor {} to {}", fd_, fd));
FMT_THROW(system_error(
errno, "cannot duplicate file descriptor {} to {}", fd_, fd));
}
}
@ -221,8 +222,8 @@ buffered_file file::fdopen(const char *mode) {
// Don't retry as fdopen doesn't return EINTR.
FILE *f = FMT_POSIX_CALL(fdopen(fd_, mode));
if (!f)
FMT_THROW(system_error(errno,
"cannot associate stream with file descriptor"));
FMT_THROW(
system_error(errno, "cannot associate stream with file descriptor"));
buffered_file bf(f);
fd_ = -1;
return bf;
@ -241,4 +242,3 @@ long getpagesize() {
#endif
}
FMT_END_NAMESPACE