clang-format for header files
- Google Style, Cpp 11 - Break for template and param/arguments
This commit is contained in:
parent
3e01376e08
commit
8671608b83
12
.clang-format
Normal file
12
.clang-format
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
Language: Cpp
|
||||||
|
Standard: Cpp11
|
||||||
|
|
||||||
|
ColumnLimit: 80
|
||||||
|
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
|
||||||
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
namespace internal{
|
namespace internal {
|
||||||
|
|
||||||
enum class numeric_system {
|
enum class numeric_system {
|
||||||
standard,
|
standard,
|
||||||
@ -28,12 +28,14 @@ enum class numeric_system {
|
|||||||
|
|
||||||
// Parses a put_time-like format string and invokes handler actions.
|
// Parses a put_time-like format string and invokes handler actions.
|
||||||
template <typename Char, typename Handler>
|
template <typename Char, typename Handler>
|
||||||
FMT_CONSTEXPR const Char *parse_chrono_format(
|
FMT_CONSTEXPR const Char *parse_chrono_format(const Char *begin,
|
||||||
const Char *begin, const Char *end, Handler &&handler) {
|
const Char *end,
|
||||||
|
Handler &&handler) {
|
||||||
auto ptr = begin;
|
auto ptr = begin;
|
||||||
while (ptr != end) {
|
while (ptr != end) {
|
||||||
auto c = *ptr;
|
auto c = *ptr;
|
||||||
if (c == '}') break;
|
if (c == '}')
|
||||||
|
break;
|
||||||
if (c != '%') {
|
if (c != '%') {
|
||||||
++ptr;
|
++ptr;
|
||||||
continue;
|
continue;
|
||||||
@ -213,7 +215,8 @@ struct chrono_format_checker {
|
|||||||
template <typename Int>
|
template <typename Int>
|
||||||
inline int to_int(Int value) {
|
inline int to_int(Int value) {
|
||||||
FMT_ASSERT(value >= (std::numeric_limits<int>::min)() &&
|
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);
|
return static_cast<int>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,30 +344,84 @@ struct chrono_formatter {
|
|||||||
};
|
};
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
template <typename Period> FMT_CONSTEXPR const char *get_units() {
|
template <typename Period>
|
||||||
|
FMT_CONSTEXPR const char *get_units() {
|
||||||
return FMT_NULL;
|
return FMT_NULL;
|
||||||
}
|
}
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::atto>() { return "as"; }
|
template <>
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::femto>() { return "fs"; }
|
FMT_CONSTEXPR const char *get_units<std::atto>() {
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::pico>() { return "ps"; }
|
return "as";
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::nano>() { return "ns"; }
|
}
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::micro>() { return "µs"; }
|
template <>
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::milli>() { return "ms"; }
|
FMT_CONSTEXPR const char *get_units<std::femto>() {
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::centi>() { return "cs"; }
|
return "fs";
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::deci>() { return "ds"; }
|
}
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::ratio<1>>() { return "s"; }
|
template <>
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::deca>() { return "das"; }
|
FMT_CONSTEXPR const char *get_units<std::pico>() {
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::hecto>() { return "hs"; }
|
return "ps";
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::kilo>() { return "ks"; }
|
}
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::mega>() { return "Ms"; }
|
template <>
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::giga>() { return "Gs"; }
|
FMT_CONSTEXPR const char *get_units<std::nano>() {
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::tera>() { return "Ts"; }
|
return "ns";
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::peta>() { return "Ps"; }
|
}
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::exa>() { return "Es"; }
|
template <>
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::ratio<60>>() {
|
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";
|
return "m";
|
||||||
}
|
}
|
||||||
template <> FMT_CONSTEXPR const char *get_units<std::ratio<3600>>() {
|
template <>
|
||||||
|
FMT_CONSTEXPR const char *get_units<std::ratio<3600>>() {
|
||||||
return "h";
|
return "h";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,10 +466,12 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
|||||||
FMT_CONSTEXPR auto parse(basic_parse_context<Char> &ctx)
|
FMT_CONSTEXPR auto parse(basic_parse_context<Char> &ctx)
|
||||||
-> decltype(ctx.begin()) {
|
-> decltype(ctx.begin()) {
|
||||||
auto begin = ctx.begin(), end = ctx.end();
|
auto begin = ctx.begin(), end = ctx.end();
|
||||||
if (begin == end) return begin;
|
if (begin == end)
|
||||||
|
return begin;
|
||||||
spec_handler handler{*this, ctx};
|
spec_handler handler{*this, ctx};
|
||||||
begin = internal::parse_align(begin, end, handler);
|
begin = internal::parse_align(begin, end, handler);
|
||||||
if (begin == end) return begin;
|
if (begin == end)
|
||||||
|
return begin;
|
||||||
begin = internal::parse_width(begin, end, handler);
|
begin = internal::parse_width(begin, end, handler);
|
||||||
end = parse_chrono_format(begin, end, internal::chrono_format_checker());
|
end = parse_chrono_format(begin, end, internal::chrono_format_checker());
|
||||||
format_str = basic_string_view<Char>(&*begin, end - begin);
|
format_str = basic_string_view<Char>(&*begin, end - begin);
|
||||||
@ -420,8 +479,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(const duration &d, FormatContext &ctx)
|
auto format(const duration &d, FormatContext &ctx) -> decltype(ctx.out()) {
|
||||||
-> decltype(ctx.out()) {
|
|
||||||
auto begin = format_str.begin(), end = format_str.end();
|
auto begin = format_str.begin(), end = format_str.end();
|
||||||
if (begin == end || *begin == '}') {
|
if (begin == end || *begin == '}') {
|
||||||
memory_buffer buf;
|
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);
|
format_to(buf, "{}[{}/{}]s", d.count(), Period::num, Period::den);
|
||||||
typedef output_range<decltype(ctx.out()), Char> range;
|
typedef output_range<decltype(ctx.out()), Char> range;
|
||||||
basic_writer<range> w(range(ctx.out()));
|
basic_writer<range> w(range(ctx.out()));
|
||||||
internal::handle_dynamic_spec<internal::width_checker>(
|
internal::handle_dynamic_spec<internal::width_checker>(spec.width_,
|
||||||
spec.width_, width_ref, ctx);
|
width_ref, ctx);
|
||||||
w.write(buf.data(), buf.size(), spec);
|
w.write(buf.data(), buf.size(), spec);
|
||||||
return w.out();
|
return w.out();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
FMT_API void vprint_colored(color c, wstring_view format, wformat_args args);
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
inline void print_colored(color c, string_view format_str,
|
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...));
|
vprint_colored(c, format_str, make_format_args(args...));
|
||||||
}
|
}
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
inline void print_colored(color c, wstring_view format_str,
|
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...));
|
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
|
#else
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
enum class color : uint32_t {
|
enum class color : uint32_t {
|
||||||
alice_blue = 0xF0F8FF, // rgb(240,248,255)
|
alice_blue = 0xF0F8FF, // rgb(240,248,255)
|
||||||
antique_white = 0xFAEBD7, // rgb(250,235,215)
|
antique_white = 0xFAEBD7, // rgb(250,235,215)
|
||||||
@ -191,6 +193,8 @@ enum class color : uint32_t {
|
|||||||
yellow_green = 0x9ACD32 // rgb(154,205,50)
|
yellow_green = 0x9ACD32 // rgb(154,205,50)
|
||||||
}; // enum class color
|
}; // enum class color
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
enum class terminal_color : uint8_t {
|
enum class terminal_color : uint8_t {
|
||||||
black = 30,
|
black = 30,
|
||||||
red,
|
red,
|
||||||
@ -225,9 +229,10 @@ struct rgb {
|
|||||||
FMT_CONSTEXPR_DECL rgb(uint8_t r_, uint8_t g_, uint8_t b_)
|
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)
|
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)
|
FMT_CONSTEXPR_DECL rgb(color hex)
|
||||||
: r((uint32_t(hex) >> 16) & 0xFF), g((uint32_t(hex) >> 8) & 0xFF),
|
: r((uint32_t(hex) >> 16) & 0xFF),
|
||||||
|
g((uint32_t(hex) >> 8) & 0xFF),
|
||||||
b(uint32_t(hex) & 0xFF) {}
|
b(uint32_t(hex) & 0xFF) {}
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
uint8_t g;
|
uint8_t g;
|
||||||
@ -238,18 +243,16 @@ namespace internal {
|
|||||||
|
|
||||||
// color is a struct of either a rgb color or a terminal color.
|
// color is a struct of either a rgb color or a terminal color.
|
||||||
struct color_type {
|
struct color_type {
|
||||||
FMT_CONSTEXPR color_type() FMT_NOEXCEPT
|
FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {}
|
||||||
: is_rgb(), value{} {}
|
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true),
|
||||||
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT
|
value{} {
|
||||||
: is_rgb(true), value{} {
|
|
||||||
value.rgb_color = static_cast<uint32_t>(rgb_color);
|
value.rgb_color = static_cast<uint32_t>(rgb_color);
|
||||||
}
|
}
|
||||||
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT
|
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} {
|
||||||
: is_rgb(true), value{} {
|
|
||||||
value.rgb_color = (rgb_color.r << 16) + (rgb_color.g << 8) + rgb_color.b;
|
value.rgb_color = (rgb_color.r << 16) + (rgb_color.g << 8) + rgb_color.b;
|
||||||
}
|
}
|
||||||
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT
|
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(),
|
||||||
: is_rgb(), value{} {
|
value{} {
|
||||||
value.term_color = static_cast<uint8_t>(term_color);
|
value.term_color = static_cast<uint8_t>(term_color);
|
||||||
}
|
}
|
||||||
bool is_rgb;
|
bool is_rgb;
|
||||||
@ -264,7 +267,9 @@ struct color_type {
|
|||||||
class text_style {
|
class text_style {
|
||||||
public:
|
public:
|
||||||
FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT
|
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) {
|
FMT_CONSTEXPR text_style &operator|=(const text_style &rhs) {
|
||||||
if (!set_foreground_color) {
|
if (!set_foreground_color) {
|
||||||
@ -290,8 +295,8 @@ class text_style {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend FMT_CONSTEXPR
|
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
|
||||||
text_style operator|(text_style lhs, const text_style &rhs) {
|
const text_style &rhs) {
|
||||||
return lhs |= rhs;
|
return lhs |= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,8 +324,8 @@ class text_style {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend FMT_CONSTEXPR
|
friend FMT_CONSTEXPR text_style operator&(text_style lhs,
|
||||||
text_style operator&(text_style lhs, const text_style &rhs) {
|
const text_style &rhs) {
|
||||||
return lhs &= rhs;
|
return lhs &= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +351,7 @@ class text_style {
|
|||||||
return ems;
|
return ems;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FMT_CONSTEXPR text_style(bool is_foreground,
|
FMT_CONSTEXPR text_style(bool is_foreground,
|
||||||
internal::color_type text_color) FMT_NOEXCEPT
|
internal::color_type text_color) FMT_NOEXCEPT
|
||||||
: set_foreground_color(),
|
: set_foreground_color(),
|
||||||
@ -390,7 +395,7 @@ namespace internal {
|
|||||||
template <typename Char>
|
template <typename Char>
|
||||||
struct ansi_color_escape {
|
struct ansi_color_escape {
|
||||||
FMT_CONSTEXPR ansi_color_escape(internal::color_type text_color,
|
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
|
// If we have a terminal color, we need to output another escape code
|
||||||
// sequence.
|
// sequence.
|
||||||
if (!text_color.is_rgb) {
|
if (!text_color.is_rgb) {
|
||||||
@ -451,7 +456,7 @@ struct ansi_color_escape {
|
|||||||
}
|
}
|
||||||
FMT_CONSTEXPR operator const Char *() const FMT_NOEXCEPT { return buffer; }
|
FMT_CONSTEXPR operator const Char *() const FMT_NOEXCEPT { return buffer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Char buffer[7 + 3 * 4 + 1];
|
Char buffer[7 + 3 * 4 + 1];
|
||||||
|
|
||||||
static FMT_CONSTEXPR void to_esc(uint8_t c, Char *out,
|
static FMT_CONSTEXPR void to_esc(uint8_t c, Char *out,
|
||||||
@ -464,20 +469,19 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR ansi_color_escape<Char>
|
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
|
||||||
make_foreground_color(internal::color_type foreground) FMT_NOEXCEPT {
|
internal::color_type foreground) FMT_NOEXCEPT {
|
||||||
return ansi_color_escape<Char>(foreground, internal::data::FOREGROUND_COLOR);
|
return ansi_color_escape<Char>(foreground, internal::data::FOREGROUND_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR ansi_color_escape<Char>
|
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
|
||||||
make_background_color(internal::color_type background) FMT_NOEXCEPT {
|
internal::color_type background) FMT_NOEXCEPT {
|
||||||
return ansi_color_escape<Char>(background, internal::data::BACKGROUND_COLOR);
|
return ansi_color_escape<Char>(background, internal::data::BACKGROUND_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR ansi_color_escape<Char>
|
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) FMT_NOEXCEPT {
|
||||||
make_emphasis(emphasis em) FMT_NOEXCEPT {
|
|
||||||
return ansi_color_escape<Char>(em);
|
return ansi_color_escape<Char>(em);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,15 +515,13 @@ template <>
|
|||||||
struct is_string<const std::FILE *> : std::false_type {};
|
struct is_string<const std::FILE *> : std::false_type {};
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
template <
|
template <typename S, typename Char = typename internal::char_t<S>::type>
|
||||||
typename S, typename Char = typename internal::char_t<S>::type>
|
|
||||||
void vprint(std::FILE *f, const text_style &ts, const S &format,
|
void vprint(std::FILE *f, const text_style &ts, const S &format,
|
||||||
basic_format_args<typename buffer_context<Char>::type> args) {
|
basic_format_args<typename buffer_context<Char>::type> args) {
|
||||||
bool has_style = false;
|
bool has_style = false;
|
||||||
if (ts.has_emphasis()) {
|
if (ts.has_emphasis()) {
|
||||||
has_style = true;
|
has_style = true;
|
||||||
internal::fputs<Char>(
|
internal::fputs<Char>(internal::make_emphasis<Char>(ts.get_emphasis()), f);
|
||||||
internal::make_emphasis<Char>(ts.get_emphasis()), f);
|
|
||||||
}
|
}
|
||||||
if (ts.has_foreground()) {
|
if (ts.has_foreground()) {
|
||||||
has_style = true;
|
has_style = true;
|
||||||
@ -564,8 +566,7 @@ typename std::enable_if<internal::is_string<String>::value>::type print(
|
|||||||
*/
|
*/
|
||||||
template <typename String, typename... Args>
|
template <typename String, typename... Args>
|
||||||
typename std::enable_if<internal::is_string<String>::value>::type print(
|
typename std::enable_if<internal::is_string<String>::value>::type print(
|
||||||
const text_style &ts, const String &format_str,
|
const text_style &ts, const String &format_str, const Args &... args) {
|
||||||
const Args &... args) {
|
|
||||||
return print(stdout, ts, format_str, args...);
|
return print(stdout, ts, format_str, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,171 +19,178 @@
|
|||||||
#define FMT_VERSION 50202
|
#define FMT_VERSION 50202
|
||||||
|
|
||||||
#ifdef __has_feature
|
#ifdef __has_feature
|
||||||
# define FMT_HAS_FEATURE(x) __has_feature(x)
|
#define FMT_HAS_FEATURE(x) __has_feature(x)
|
||||||
#else
|
#else
|
||||||
# define FMT_HAS_FEATURE(x) 0
|
#define FMT_HAS_FEATURE(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__has_include) && !defined(__INTELLISENSE__) && \
|
#if defined(__has_include) && !defined(__INTELLISENSE__) && \
|
||||||
!(defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1600)
|
!(defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1600)
|
||||||
# define FMT_HAS_INCLUDE(x) __has_include(x)
|
#define FMT_HAS_INCLUDE(x) __has_include(x)
|
||||||
#else
|
#else
|
||||||
# define FMT_HAS_INCLUDE(x) 0
|
#define FMT_HAS_INCLUDE(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __has_cpp_attribute
|
#ifdef __has_cpp_attribute
|
||||||
# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
#define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
||||||
#else
|
#else
|
||||||
# define FMT_HAS_CPP_ATTRIBUTE(x) 0
|
#define FMT_HAS_CPP_ATTRIBUTE(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
#define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||||
#else
|
#else
|
||||||
# define FMT_GCC_VERSION 0
|
#define FMT_GCC_VERSION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
# define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION
|
#define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION
|
||||||
#else
|
#else
|
||||||
# define FMT_HAS_GXX_CXX11 0
|
#define FMT_HAS_GXX_CXX11 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define FMT_MSC_VER _MSC_VER
|
#define FMT_MSC_VER _MSC_VER
|
||||||
#else
|
#else
|
||||||
# define FMT_MSC_VER 0
|
#define FMT_MSC_VER 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check if relaxed C++14 constexpr is supported.
|
// Check if relaxed C++14 constexpr is supported.
|
||||||
// GCC doesn't allow throw in constexpr until version 6 (bug 67371).
|
// GCC doesn't allow throw in constexpr until version 6 (bug 67371).
|
||||||
#ifndef FMT_USE_CONSTEXPR
|
#ifndef FMT_USE_CONSTEXPR
|
||||||
# define FMT_USE_CONSTEXPR \
|
#define FMT_USE_CONSTEXPR \
|
||||||
(FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \
|
(FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \
|
||||||
(FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L))
|
(FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L))
|
||||||
#endif
|
#endif
|
||||||
#if FMT_USE_CONSTEXPR
|
#if FMT_USE_CONSTEXPR
|
||||||
# define FMT_CONSTEXPR constexpr
|
#define FMT_CONSTEXPR constexpr
|
||||||
# define FMT_CONSTEXPR_DECL constexpr
|
#define FMT_CONSTEXPR_DECL constexpr
|
||||||
#else
|
#else
|
||||||
# define FMT_CONSTEXPR inline
|
#define FMT_CONSTEXPR inline
|
||||||
# define FMT_CONSTEXPR_DECL
|
#define FMT_CONSTEXPR_DECL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_USE_CONSTEXPR11
|
#ifndef FMT_USE_CONSTEXPR11
|
||||||
# define FMT_USE_CONSTEXPR11 \
|
#define FMT_USE_CONSTEXPR11 \
|
||||||
(FMT_USE_CONSTEXPR || FMT_GCC_VERSION >= 406 || FMT_MSC_VER >= 1900)
|
(FMT_USE_CONSTEXPR || FMT_GCC_VERSION >= 406 || FMT_MSC_VER >= 1900)
|
||||||
#endif
|
#endif
|
||||||
#if FMT_USE_CONSTEXPR11
|
#if FMT_USE_CONSTEXPR11
|
||||||
# define FMT_CONSTEXPR11 constexpr
|
#define FMT_CONSTEXPR11 constexpr
|
||||||
#else
|
#else
|
||||||
# define FMT_CONSTEXPR11
|
#define FMT_CONSTEXPR11
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_OVERRIDE
|
#ifndef FMT_OVERRIDE
|
||||||
# if FMT_HAS_FEATURE(cxx_override) || \
|
#if FMT_HAS_FEATURE(cxx_override) || \
|
||||||
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
|
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
|
||||||
# define FMT_OVERRIDE override
|
#define FMT_OVERRIDE override
|
||||||
# else
|
#else
|
||||||
# define FMT_OVERRIDE
|
#define FMT_OVERRIDE
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_HAS_FEATURE(cxx_explicit_conversions) || \
|
#if FMT_HAS_FEATURE(cxx_explicit_conversions) || FMT_GCC_VERSION >= 405 || \
|
||||||
FMT_GCC_VERSION >= 405 || FMT_MSC_VER >= 1800
|
FMT_MSC_VER >= 1800
|
||||||
# define FMT_USE_EXPLICIT 1
|
#define FMT_USE_EXPLICIT 1
|
||||||
# define FMT_EXPLICIT explicit
|
#define FMT_EXPLICIT explicit
|
||||||
#else
|
#else
|
||||||
# define FMT_USE_EXPLICIT 0
|
#define FMT_USE_EXPLICIT 0
|
||||||
# define FMT_EXPLICIT
|
#define FMT_EXPLICIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_NULL
|
#ifndef FMT_NULL
|
||||||
# if FMT_HAS_FEATURE(cxx_nullptr) || \
|
#if FMT_HAS_FEATURE(cxx_nullptr) || \
|
||||||
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600
|
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600
|
||||||
# define FMT_NULL nullptr
|
#define FMT_NULL nullptr
|
||||||
# define FMT_USE_NULLPTR 1
|
#define FMT_USE_NULLPTR 1
|
||||||
# else
|
#else
|
||||||
# define FMT_NULL NULL
|
#define FMT_NULL NULL
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef FMT_USE_NULLPTR
|
#ifndef FMT_USE_NULLPTR
|
||||||
# define FMT_USE_NULLPTR 0
|
#define FMT_USE_NULLPTR 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check if exceptions are disabled.
|
// Check if exceptions are disabled.
|
||||||
#ifndef FMT_EXCEPTIONS
|
#ifndef FMT_EXCEPTIONS
|
||||||
# if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
|
#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
|
||||||
FMT_MSC_VER && !_HAS_EXCEPTIONS
|
FMT_MSC_VER && !_HAS_EXCEPTIONS
|
||||||
# define FMT_EXCEPTIONS 0
|
#define FMT_EXCEPTIONS 0
|
||||||
# else
|
#else
|
||||||
# define FMT_EXCEPTIONS 1
|
#define FMT_EXCEPTIONS 1
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
|
// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
|
||||||
#ifndef FMT_USE_NOEXCEPT
|
#ifndef FMT_USE_NOEXCEPT
|
||||||
# define FMT_USE_NOEXCEPT 0
|
#define FMT_USE_NOEXCEPT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
|
#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
|
||||||
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
|
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
|
||||||
# define FMT_DETECTED_NOEXCEPT noexcept
|
#define FMT_DETECTED_NOEXCEPT noexcept
|
||||||
# define FMT_HAS_CXX11_NOEXCEPT 1
|
#define FMT_HAS_CXX11_NOEXCEPT 1
|
||||||
#else
|
#else
|
||||||
# define FMT_DETECTED_NOEXCEPT throw()
|
#define FMT_DETECTED_NOEXCEPT throw()
|
||||||
# define FMT_HAS_CXX11_NOEXCEPT 0
|
#define FMT_HAS_CXX11_NOEXCEPT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_NOEXCEPT
|
#ifndef FMT_NOEXCEPT
|
||||||
# if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT
|
#if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT
|
||||||
# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
|
#define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
|
||||||
# else
|
#else
|
||||||
# define FMT_NOEXCEPT
|
#define FMT_NOEXCEPT
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_BEGIN_NAMESPACE
|
#ifndef FMT_BEGIN_NAMESPACE
|
||||||
# if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \
|
#if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \
|
||||||
FMT_MSC_VER >= 1900
|
FMT_MSC_VER >= 1900
|
||||||
# define FMT_INLINE_NAMESPACE inline namespace
|
#define FMT_INLINE_NAMESPACE inline namespace
|
||||||
# define FMT_END_NAMESPACE }}
|
#define FMT_END_NAMESPACE \
|
||||||
# else
|
} \
|
||||||
# define FMT_INLINE_NAMESPACE namespace
|
}
|
||||||
# define FMT_END_NAMESPACE } using namespace v5; }
|
#else
|
||||||
# endif
|
#define FMT_INLINE_NAMESPACE namespace
|
||||||
# define FMT_BEGIN_NAMESPACE namespace fmt { FMT_INLINE_NAMESPACE v5 {
|
#define FMT_END_NAMESPACE \
|
||||||
|
} \
|
||||||
|
using namespace v5; \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#define FMT_BEGIN_NAMESPACE \
|
||||||
|
namespace fmt { \
|
||||||
|
FMT_INLINE_NAMESPACE v5 {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
|
#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
|
||||||
# ifdef FMT_EXPORT
|
#ifdef FMT_EXPORT
|
||||||
# define FMT_API __declspec(dllexport)
|
#define FMT_API __declspec(dllexport)
|
||||||
# elif defined(FMT_SHARED)
|
#elif defined(FMT_SHARED)
|
||||||
# define FMT_API __declspec(dllimport)
|
#define FMT_API __declspec(dllimport)
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef FMT_API
|
#ifndef FMT_API
|
||||||
# define FMT_API
|
#define FMT_API
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_ASSERT
|
#ifndef FMT_ASSERT
|
||||||
# define FMT_ASSERT(condition, message) assert((condition) && message)
|
#define FMT_ASSERT(condition, message) assert((condition) && message)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// libc++ supports string_view in pre-c++17.
|
// libc++ supports string_view in pre-c++17.
|
||||||
#if (FMT_HAS_INCLUDE(<string_view>) && \
|
#if (FMT_HAS_INCLUDE(<string_view>) && \
|
||||||
(__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \
|
(__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \
|
||||||
(defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
|
(defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
|
||||||
# include <string_view>
|
#include <string_view>
|
||||||
# define FMT_STRING_VIEW std::basic_string_view
|
#define FMT_STRING_VIEW std::basic_string_view
|
||||||
#elif FMT_HAS_INCLUDE(<experimental/string_view>) && __cplusplus >= 201402L
|
#elif FMT_HAS_INCLUDE(<experimental / string_view>) && __cplusplus >= 201402L
|
||||||
# include <experimental/string_view>
|
#include <experimental/string_view>
|
||||||
# define FMT_STRING_VIEW std::experimental::basic_string_view
|
#define FMT_STRING_VIEW std::experimental::basic_string_view
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// std::result_of is defined in <functional> in gcc 4.4.
|
// std::result_of is defined in <functional> in gcc 4.4.
|
||||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 404
|
#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 404
|
||||||
# include <functional>
|
#include <functional>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
@ -199,8 +206,8 @@ struct result_of;
|
|||||||
template <typename F, typename... Args>
|
template <typename F, typename... Args>
|
||||||
struct result_of<F(Args...)> {
|
struct result_of<F(Args...)> {
|
||||||
// A workaround for gcc 4.4 that doesn't allow F to be a reference.
|
// A workaround for gcc 4.4 that doesn't allow F to be a reference.
|
||||||
typedef typename std::result_of<
|
typedef typename std::result_of<typename std::remove_reference<F>::type(
|
||||||
typename std::remove_reference<F>::type(Args...)>::type type;
|
Args...)>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Casts nonnegative integer to unsigned.
|
// Casts nonnegative integer to unsigned.
|
||||||
@ -223,10 +230,12 @@ class basic_buffer {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Don't initialize ptr_ since it is not accessed to save a few cycles.
|
// Don't initialize ptr_ since it is not accessed to save a few cycles.
|
||||||
basic_buffer(std::size_t sz) FMT_NOEXCEPT: size_(sz), capacity_(sz) {}
|
basic_buffer(std::size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {}
|
||||||
|
|
||||||
basic_buffer(T *p = FMT_NULL, std::size_t sz = 0, std::size_t cap = 0)
|
basic_buffer(T *p = FMT_NULL, std::size_t sz = 0,
|
||||||
FMT_NOEXCEPT: ptr_(p), size_(sz), capacity_(cap) {}
|
std::size_t cap = 0) FMT_NOEXCEPT : ptr_(p),
|
||||||
|
size_(sz),
|
||||||
|
capacity_(cap) {}
|
||||||
|
|
||||||
/** Sets the buffer data and capacity. */
|
/** Sets the buffer data and capacity. */
|
||||||
void set(T *buf_data, std::size_t buf_capacity) FMT_NOEXCEPT {
|
void set(T *buf_data, std::size_t buf_capacity) FMT_NOEXCEPT {
|
||||||
@ -312,7 +321,7 @@ class container_buffer : public basic_buffer<typename Container::value_type> {
|
|||||||
template <typename Container>
|
template <typename Container>
|
||||||
inline Container &get_container(std::back_insert_iterator<Container> it) {
|
inline Container &get_container(std::back_insert_iterator<Container> it) {
|
||||||
typedef std::back_insert_iterator<Container> bi_iterator;
|
typedef std::back_insert_iterator<Container> bi_iterator;
|
||||||
struct accessor: bi_iterator {
|
struct accessor : bi_iterator {
|
||||||
accessor(bi_iterator iter) : bi_iterator(iter) {}
|
accessor(bi_iterator iter) : bi_iterator(iter) {}
|
||||||
using bi_iterator::container;
|
using bi_iterator::container;
|
||||||
};
|
};
|
||||||
@ -333,7 +342,7 @@ struct no_formatter_error : std::false_type {};
|
|||||||
|
|
||||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 405
|
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 405
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
struct is_constructible: std::false_type {};
|
struct is_constructible : std::false_type {};
|
||||||
#else
|
#else
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
struct is_constructible : std::is_constructible<T...> {};
|
struct is_constructible : std::is_constructible<T...> {};
|
||||||
@ -360,7 +369,8 @@ class basic_string_view {
|
|||||||
|
|
||||||
/** Constructs a string reference object from a C string and a size. */
|
/** Constructs a string reference object from a C string and a size. */
|
||||||
FMT_CONSTEXPR basic_string_view(const Char *s, size_t count) FMT_NOEXCEPT
|
FMT_CONSTEXPR basic_string_view(const Char *s, size_t count) FMT_NOEXCEPT
|
||||||
: data_(s), size_(count) {}
|
: data_(s),
|
||||||
|
size_(count) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
@ -373,13 +383,14 @@ class basic_string_view {
|
|||||||
|
|
||||||
/** Constructs a string reference from a ``std::basic_string`` object. */
|
/** Constructs a string reference from a ``std::basic_string`` object. */
|
||||||
template <typename Alloc>
|
template <typename Alloc>
|
||||||
FMT_CONSTEXPR basic_string_view(
|
FMT_CONSTEXPR basic_string_view(const std::basic_string<Char, Alloc> &s)
|
||||||
const std::basic_string<Char, Alloc> &s) FMT_NOEXCEPT
|
FMT_NOEXCEPT : data_(s.data()),
|
||||||
: data_(s.data()), size_(s.size()) {}
|
size_(s.size()) {}
|
||||||
|
|
||||||
#ifdef FMT_STRING_VIEW
|
#ifdef FMT_STRING_VIEW
|
||||||
FMT_CONSTEXPR basic_string_view(FMT_STRING_VIEW<Char> s) FMT_NOEXCEPT
|
FMT_CONSTEXPR basic_string_view(FMT_STRING_VIEW<Char> s) FMT_NOEXCEPT
|
||||||
: data_(s.data()), size_(s.size()) {}
|
: data_(s.data()),
|
||||||
|
size_(s.size()) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Returns a pointer to the string data. */
|
/** Returns a pointer to the string data. */
|
||||||
@ -451,20 +462,26 @@ typedef basic_string_view<wchar_t> wstring_view;
|
|||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline basic_string_view<Char>
|
inline basic_string_view<Char> to_string_view(basic_string_view<Char> s) {
|
||||||
to_string_view(basic_string_view<Char> s) { return s; }
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline basic_string_view<Char>
|
inline basic_string_view<Char> to_string_view(
|
||||||
to_string_view(const std::basic_string<Char> &s) { return s; }
|
const std::basic_string<Char> &s) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline basic_string_view<Char> to_string_view(const Char *s) { return s; }
|
inline basic_string_view<Char> to_string_view(const Char *s) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef FMT_STRING_VIEW
|
#ifdef FMT_STRING_VIEW
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline basic_string_view<Char>
|
inline basic_string_view<Char> to_string_view(FMT_STRING_VIEW<Char> s) {
|
||||||
to_string_view(FMT_STRING_VIEW<Char> s) { return s; }
|
return s;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// A base class for compile-time strings. It is defined in the fmt namespace to
|
// A base class for compile-time strings. It is defined in the fmt namespace to
|
||||||
@ -474,11 +491,12 @@ struct compile_string {};
|
|||||||
template <typename S>
|
template <typename S>
|
||||||
struct is_compile_string : std::is_base_of<compile_string, S> {};
|
struct is_compile_string : std::is_base_of<compile_string, S> {};
|
||||||
|
|
||||||
template <
|
template <typename S, typename Enable = typename std::enable_if<
|
||||||
typename S,
|
is_compile_string<S>::value>::type>
|
||||||
typename Enable = typename std::enable_if<is_compile_string<S>::value>::type>
|
FMT_CONSTEXPR basic_string_view<typename S::char_type> to_string_view(
|
||||||
FMT_CONSTEXPR basic_string_view<typename S::char_type>
|
const S &s) {
|
||||||
to_string_view(const S &s) { return s; }
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
class basic_format_arg;
|
class basic_format_arg;
|
||||||
@ -489,7 +507,8 @@ class basic_format_args;
|
|||||||
// A formatter for objects of type T.
|
// A formatter for objects of type T.
|
||||||
template <typename T, typename Char = char, typename Enable = void>
|
template <typename T, typename Char = char, typename Enable = void>
|
||||||
struct formatter {
|
struct formatter {
|
||||||
static_assert(internal::no_formatter_error<T>::value,
|
static_assert(
|
||||||
|
internal::no_formatter_error<T>::value,
|
||||||
"don't know how to format the type, include fmt/ostream.h if it provides "
|
"don't know how to format the type, include fmt/ostream.h if it provides "
|
||||||
"an operator<< that should be used");
|
"an operator<< that should be used");
|
||||||
|
|
||||||
@ -501,19 +520,25 @@ struct formatter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Char, typename Enable = void>
|
template <typename T, typename Char, typename Enable = void>
|
||||||
struct convert_to_int: std::integral_constant<
|
struct convert_to_int
|
||||||
bool, !std::is_arithmetic<T>::value && std::is_convertible<T, int>::value> {};
|
: std::integral_constant<bool, !std::is_arithmetic<T>::value &&
|
||||||
|
std::is_convertible<T, int>::value> {};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
struct dummy_string_view { typedef void char_type; };
|
struct dummy_string_view {
|
||||||
|
typedef void char_type;
|
||||||
|
};
|
||||||
dummy_string_view to_string_view(...);
|
dummy_string_view to_string_view(...);
|
||||||
using fmt::v5::to_string_view;
|
using fmt::v5::to_string_view;
|
||||||
|
|
||||||
// Specifies whether S is a string type convertible to fmt::basic_string_view.
|
// Specifies whether S is a string type convertible to fmt::basic_string_view.
|
||||||
template <typename S>
|
template <typename S>
|
||||||
struct is_string : std::integral_constant<bool, !std::is_same<
|
struct is_string
|
||||||
dummy_string_view, decltype(to_string_view(declval<S>()))>::value> {};
|
: std::integral_constant<
|
||||||
|
bool, !std::is_same<dummy_string_view,
|
||||||
|
decltype(to_string_view(declval<S>()))>::value> {
|
||||||
|
};
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
struct char_t {
|
struct char_t {
|
||||||
@ -528,13 +553,24 @@ template <typename T, typename Char>
|
|||||||
struct named_arg;
|
struct named_arg;
|
||||||
|
|
||||||
enum type {
|
enum type {
|
||||||
none_type, named_arg_type,
|
none_type,
|
||||||
|
named_arg_type,
|
||||||
// Integer types should go first,
|
// Integer types should go first,
|
||||||
int_type, uint_type, long_long_type, ulong_long_type, bool_type, char_type,
|
int_type,
|
||||||
|
uint_type,
|
||||||
|
long_long_type,
|
||||||
|
ulong_long_type,
|
||||||
|
bool_type,
|
||||||
|
char_type,
|
||||||
last_integer_type = char_type,
|
last_integer_type = char_type,
|
||||||
// followed by floating-point types.
|
// followed by floating-point types.
|
||||||
double_type, long_double_type, last_numeric_type = long_double_type,
|
double_type,
|
||||||
cstring_type, string_type, pointer_type, custom_type
|
long_double_type,
|
||||||
|
last_numeric_type = long_double_type,
|
||||||
|
cstring_type,
|
||||||
|
string_type,
|
||||||
|
pointer_type,
|
||||||
|
custom_type
|
||||||
};
|
};
|
||||||
|
|
||||||
FMT_CONSTEXPR bool is_integral(type t) {
|
FMT_CONSTEXPR bool is_integral(type t) {
|
||||||
@ -609,7 +645,7 @@ class value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const named_arg_base<char_type> &as_named_arg() {
|
const named_arg_base<char_type> &as_named_arg() {
|
||||||
return *static_cast<const named_arg_base<char_type>*>(pointer);
|
return *static_cast<const named_arg_base<char_type> *>(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -622,7 +658,7 @@ class value {
|
|||||||
typename Context::template formatter_type<T>::type f;
|
typename Context::template formatter_type<T>::type f;
|
||||||
auto &&parse_ctx = ctx.parse_context();
|
auto &&parse_ctx = ctx.parse_context();
|
||||||
parse_ctx.advance_to(f.parse(parse_ctx));
|
parse_ctx.advance_to(f.parse(parse_ctx));
|
||||||
ctx.advance_to(f.format(*static_cast<const T*>(arg), ctx));
|
ctx.advance_to(f.format(*static_cast<const T *>(arg), ctx));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -647,7 +683,9 @@ FMT_CONSTEXPR basic_format_arg<Context> make_arg(const T &value);
|
|||||||
|
|
||||||
#define FMT_MAKE_VALUE_SAME(TAG, Type) \
|
#define FMT_MAKE_VALUE_SAME(TAG, Type) \
|
||||||
template <typename C> \
|
template <typename C> \
|
||||||
FMT_CONSTEXPR init<C, Type, TAG> make_value(Type val) { return val; }
|
FMT_CONSTEXPR init<C, Type, TAG> make_value(Type val) { \
|
||||||
|
return val; \
|
||||||
|
}
|
||||||
|
|
||||||
FMT_MAKE_VALUE(bool_type, bool, int)
|
FMT_MAKE_VALUE(bool_type, bool, int)
|
||||||
FMT_MAKE_VALUE(int_type, short, int)
|
FMT_MAKE_VALUE(int_type, short, int)
|
||||||
@ -659,12 +697,12 @@ FMT_MAKE_VALUE_SAME(uint_type, unsigned)
|
|||||||
// either to int or to long long depending on its size.
|
// either to int or to long long depending on its size.
|
||||||
typedef std::conditional<sizeof(long) == sizeof(int), int, long long>::type
|
typedef std::conditional<sizeof(long) == sizeof(int), int, long long>::type
|
||||||
long_type;
|
long_type;
|
||||||
FMT_MAKE_VALUE(
|
FMT_MAKE_VALUE((sizeof(long) == sizeof(int) ? int_type : long_long_type), long,
|
||||||
(sizeof(long) == sizeof(int) ? int_type : long_long_type), long, long_type)
|
long_type)
|
||||||
typedef std::conditional<sizeof(unsigned long) == sizeof(unsigned),
|
typedef std::conditional<sizeof(unsigned long) == sizeof(unsigned), unsigned,
|
||||||
unsigned, unsigned long long>::type ulong_type;
|
unsigned long long>::type ulong_type;
|
||||||
FMT_MAKE_VALUE(
|
FMT_MAKE_VALUE((sizeof(unsigned long) == sizeof(unsigned) ? uint_type
|
||||||
(sizeof(unsigned long) == sizeof(unsigned) ? uint_type : ulong_long_type),
|
: ulong_long_type),
|
||||||
unsigned long, ulong_type)
|
unsigned long, ulong_type)
|
||||||
|
|
||||||
FMT_MAKE_VALUE_SAME(long_long_type, long long)
|
FMT_MAKE_VALUE_SAME(long_long_type, long long)
|
||||||
@ -674,14 +712,20 @@ FMT_MAKE_VALUE(uint_type, unsigned char, unsigned)
|
|||||||
|
|
||||||
// This doesn't use FMT_MAKE_VALUE because of ambiguity in gcc 4.4.
|
// This doesn't use FMT_MAKE_VALUE because of ambiguity in gcc 4.4.
|
||||||
template <typename C, typename Char>
|
template <typename C, typename Char>
|
||||||
FMT_CONSTEXPR typename std::enable_if<
|
FMT_CONSTEXPR
|
||||||
std::is_same<typename C::char_type, Char>::value,
|
typename std::enable_if<std::is_same<typename C::char_type, Char>::value,
|
||||||
init<C, int, char_type>>::type make_value(Char val) { return val; }
|
init<C, int, char_type>>::type
|
||||||
|
make_value(Char val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
FMT_CONSTEXPR typename std::enable_if<
|
FMT_CONSTEXPR
|
||||||
!std::is_same<typename C::char_type, char>::value,
|
typename std::enable_if<!std::is_same<typename C::char_type, char>::value,
|
||||||
init<C, int, char_type>>::type make_value(char val) { return val; }
|
init<C, int, char_type>>::type
|
||||||
|
make_value(char val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
FMT_MAKE_VALUE(double_type, float, double)
|
FMT_MAKE_VALUE(double_type, float, double)
|
||||||
FMT_MAKE_VALUE_SAME(double_type, double)
|
FMT_MAKE_VALUE_SAME(double_type, double)
|
||||||
@ -689,26 +733,26 @@ FMT_MAKE_VALUE_SAME(long_double_type, long double)
|
|||||||
|
|
||||||
// Formatting of wide strings into a narrow buffer and multibyte strings
|
// Formatting of wide strings into a narrow buffer and multibyte strings
|
||||||
// into a wide buffer is disallowed (https://github.com/fmtlib/fmt/pull/606).
|
// into a wide buffer is disallowed (https://github.com/fmtlib/fmt/pull/606).
|
||||||
FMT_MAKE_VALUE(cstring_type, typename C::char_type*,
|
FMT_MAKE_VALUE(cstring_type, typename C::char_type *,
|
||||||
const typename C::char_type*)
|
const typename C::char_type *)
|
||||||
FMT_MAKE_VALUE(cstring_type, const typename C::char_type*,
|
FMT_MAKE_VALUE(cstring_type, const typename C::char_type *,
|
||||||
const typename C::char_type*)
|
const typename C::char_type *)
|
||||||
|
|
||||||
FMT_MAKE_VALUE(cstring_type, signed char*, const signed char*)
|
FMT_MAKE_VALUE(cstring_type, signed char *, const signed char *)
|
||||||
FMT_MAKE_VALUE_SAME(cstring_type, const signed char*)
|
FMT_MAKE_VALUE_SAME(cstring_type, const signed char *)
|
||||||
FMT_MAKE_VALUE(cstring_type, unsigned char*, const unsigned char*)
|
FMT_MAKE_VALUE(cstring_type, unsigned char *, const unsigned char *)
|
||||||
FMT_MAKE_VALUE_SAME(cstring_type, const unsigned char*)
|
FMT_MAKE_VALUE_SAME(cstring_type, const unsigned char *)
|
||||||
FMT_MAKE_VALUE_SAME(string_type, basic_string_view<typename C::char_type>)
|
FMT_MAKE_VALUE_SAME(string_type, basic_string_view<typename C::char_type>)
|
||||||
FMT_MAKE_VALUE(string_type,
|
FMT_MAKE_VALUE(string_type,
|
||||||
typename basic_string_view<typename C::char_type>::type,
|
typename basic_string_view<typename C::char_type>::type,
|
||||||
basic_string_view<typename C::char_type>)
|
basic_string_view<typename C::char_type>)
|
||||||
FMT_MAKE_VALUE(string_type, const std::basic_string<typename C::char_type>&,
|
FMT_MAKE_VALUE(string_type, const std::basic_string<typename C::char_type> &,
|
||||||
basic_string_view<typename C::char_type>)
|
basic_string_view<typename C::char_type>)
|
||||||
FMT_MAKE_VALUE(pointer_type, void*, const void*)
|
FMT_MAKE_VALUE(pointer_type, void *, const void *)
|
||||||
FMT_MAKE_VALUE_SAME(pointer_type, const void*)
|
FMT_MAKE_VALUE_SAME(pointer_type, const void *)
|
||||||
|
|
||||||
#if FMT_USE_NULLPTR
|
#if FMT_USE_NULLPTR
|
||||||
FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void*)
|
FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void *)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Formatting of arbitrary pointers is disallowed. If you want to output a
|
// Formatting of arbitrary pointers is disallowed. If you want to output a
|
||||||
@ -717,22 +761,27 @@ FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void*)
|
|||||||
// iostreams.
|
// iostreams.
|
||||||
template <typename C, typename T>
|
template <typename C, typename T>
|
||||||
typename std::enable_if<!std::is_same<T, typename C::char_type>::value>::type
|
typename std::enable_if<!std::is_same<T, typename C::char_type>::value>::type
|
||||||
make_value(const T *) {
|
make_value(const T *) {
|
||||||
static_assert(!sizeof(T), "formatting of non-void pointers is disallowed");
|
static_assert(!sizeof(T), "formatting of non-void pointers is disallowed");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C, typename T>
|
template <typename C, typename T>
|
||||||
inline typename std::enable_if<
|
inline
|
||||||
std::is_enum<T>::value && convert_to_int<T, typename C::char_type>::value,
|
typename std::enable_if<std::is_enum<T>::value &&
|
||||||
|
convert_to_int<T, typename C::char_type>::value,
|
||||||
init<C, int, int_type>>::type
|
init<C, int, int_type>>::type
|
||||||
make_value(const T &val) { return static_cast<int>(val); }
|
make_value(const T &val) {
|
||||||
|
return static_cast<int>(val);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename C, typename T, typename Char = typename C::char_type>
|
template <typename C, typename T, typename Char = typename C::char_type>
|
||||||
inline typename std::enable_if<
|
inline typename std::enable_if<
|
||||||
is_constructible<basic_string_view<Char>, T>::value &&
|
is_constructible<basic_string_view<Char>, T>::value &&
|
||||||
!internal::is_string<T>::value,
|
!internal::is_string<T>::value,
|
||||||
init<C, basic_string_view<Char>, string_type>>::type
|
init<C, basic_string_view<Char>, string_type>>::type
|
||||||
make_value(const T &val) { return basic_string_view<Char>(val); }
|
make_value(const T &val) {
|
||||||
|
return basic_string_view<Char>(val);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename C, typename T, typename Char = typename C::char_type>
|
template <typename C, typename T, typename Char = typename C::char_type>
|
||||||
inline typename std::enable_if<
|
inline typename std::enable_if<
|
||||||
@ -743,24 +792,26 @@ inline typename std::enable_if<
|
|||||||
// Implicit conversion to std::string is not handled here because it's
|
// Implicit conversion to std::string is not handled here because it's
|
||||||
// unsafe: https://github.com/fmtlib/fmt/issues/729
|
// unsafe: https://github.com/fmtlib/fmt/issues/729
|
||||||
init<C, const T &, custom_type>>::type
|
init<C, const T &, custom_type>>::type
|
||||||
make_value(const T &val) { return val; }
|
make_value(const T &val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename C, typename T>
|
template <typename C, typename T>
|
||||||
init<C, const void*, named_arg_type>
|
init<C, const void *, named_arg_type> make_value(
|
||||||
make_value(const named_arg<T, typename C::char_type> &val) {
|
const named_arg<T, typename C::char_type> &val) {
|
||||||
basic_format_arg<C> arg = make_arg<C>(val.value);
|
basic_format_arg<C> arg = make_arg<C>(val.value);
|
||||||
std::memcpy(val.data, &arg, sizeof(arg));
|
std::memcpy(val.data, &arg, sizeof(arg));
|
||||||
return static_cast<const void*>(&val);
|
return static_cast<const void *>(&val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C, typename S>
|
template <typename C, typename S>
|
||||||
FMT_CONSTEXPR11 typename std::enable_if<
|
FMT_CONSTEXPR11 typename std::enable_if<
|
||||||
internal::is_string<S>::value,
|
internal::is_string<S>::value,
|
||||||
init<C, basic_string_view<typename C::char_type>, string_type>>::type
|
init<C, basic_string_view<typename C::char_type>, string_type>>::type
|
||||||
make_value(const S &val) {
|
make_value(const S &val) {
|
||||||
// Handle adapted strings.
|
// Handle adapted strings.
|
||||||
static_assert(std::is_same<
|
static_assert(std::is_same<typename C::char_type,
|
||||||
typename C::char_type, typename internal::char_t<S>::type>::value,
|
typename internal::char_t<S>::type>::value,
|
||||||
"mismatch between char-types of context and argument");
|
"mismatch between char-types of context and argument");
|
||||||
return to_string_view(val);
|
return to_string_view(val);
|
||||||
}
|
}
|
||||||
@ -782,8 +833,8 @@ class basic_format_arg {
|
|||||||
internal::type type_;
|
internal::type type_;
|
||||||
|
|
||||||
template <typename ContextType, typename T>
|
template <typename ContextType, typename T>
|
||||||
friend FMT_CONSTEXPR basic_format_arg<ContextType>
|
friend FMT_CONSTEXPR basic_format_arg<ContextType> internal::make_arg(
|
||||||
internal::make_arg(const T &value);
|
const T &value);
|
||||||
|
|
||||||
template <typename Visitor, typename Ctx>
|
template <typename Visitor, typename Ctx>
|
||||||
friend FMT_CONSTEXPR typename internal::result_of<Visitor(int)>::type
|
friend FMT_CONSTEXPR typename internal::result_of<Visitor(int)>::type
|
||||||
@ -797,7 +848,7 @@ class basic_format_arg {
|
|||||||
public:
|
public:
|
||||||
class handle {
|
class handle {
|
||||||
public:
|
public:
|
||||||
explicit handle(internal::custom_value<Context> custom): custom_(custom) {}
|
explicit handle(internal::custom_value<Context> custom) : custom_(custom) {}
|
||||||
|
|
||||||
void format(Context &ctx) const { custom_.format(custom_.value, ctx); }
|
void format(Context &ctx) const { custom_.format(custom_.value, ctx); }
|
||||||
|
|
||||||
@ -827,8 +878,8 @@ struct monostate {};
|
|||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename Visitor, typename Context>
|
template <typename Visitor, typename Context>
|
||||||
FMT_CONSTEXPR typename internal::result_of<Visitor(int)>::type
|
FMT_CONSTEXPR typename internal::result_of<Visitor(int)>::type visit_format_arg(
|
||||||
visit_format_arg(Visitor &&vis, const basic_format_arg<Context> &arg) {
|
Visitor &&vis, const basic_format_arg<Context> &arg) {
|
||||||
typedef typename Context::char_type char_type;
|
typedef typename Context::char_type char_type;
|
||||||
switch (arg.type_) {
|
switch (arg.type_) {
|
||||||
case internal::none_type:
|
case internal::none_type:
|
||||||
@ -855,8 +906,8 @@ FMT_CONSTEXPR typename internal::result_of<Visitor(int)>::type
|
|||||||
case internal::cstring_type:
|
case internal::cstring_type:
|
||||||
return vis(arg.value_.string.value);
|
return vis(arg.value_.string.value);
|
||||||
case internal::string_type:
|
case internal::string_type:
|
||||||
return vis(basic_string_view<char_type>(
|
return vis(basic_string_view<char_type>(arg.value_.string.value,
|
||||||
arg.value_.string.value, arg.value_.string.size));
|
arg.value_.string.size));
|
||||||
case internal::pointer_type:
|
case internal::pointer_type:
|
||||||
return vis(arg.value_.pointer);
|
return vis(arg.value_.pointer);
|
||||||
case internal::custom_type:
|
case internal::custom_type:
|
||||||
@ -866,8 +917,8 @@ FMT_CONSTEXPR typename internal::result_of<Visitor(int)>::type
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor, typename Context>
|
template <typename Visitor, typename Context>
|
||||||
FMT_CONSTEXPR typename internal::result_of<Visitor(int)>::type
|
FMT_CONSTEXPR typename internal::result_of<Visitor(int)>::type visit(
|
||||||
visit(Visitor &&vis, const basic_format_arg<Context> &arg) {
|
Visitor &&vis, const basic_format_arg<Context> &arg) {
|
||||||
return visit_format_arg(std::forward<Visitor>(vis), arg);
|
return visit_format_arg(std::forward<Visitor>(vis), arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -883,8 +934,8 @@ class basic_parse_context : private ErrorHandler {
|
|||||||
typedef Char char_type;
|
typedef Char char_type;
|
||||||
typedef typename basic_string_view<Char>::iterator iterator;
|
typedef typename basic_string_view<Char>::iterator iterator;
|
||||||
|
|
||||||
explicit FMT_CONSTEXPR basic_parse_context(
|
explicit FMT_CONSTEXPR basic_parse_context(basic_string_view<Char> format_str,
|
||||||
basic_string_view<Char> format_str, ErrorHandler eh = ErrorHandler())
|
ErrorHandler eh = ErrorHandler())
|
||||||
: ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {}
|
: ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {}
|
||||||
|
|
||||||
// Returns an iterator to the beginning of the format string range being
|
// Returns an iterator to the beginning of the format string range being
|
||||||
@ -955,7 +1006,7 @@ class arg_map {
|
|||||||
public:
|
public:
|
||||||
arg_map() : map_(FMT_NULL), size_(0) {}
|
arg_map() : map_(FMT_NULL), size_(0) {}
|
||||||
void init(const basic_format_args<Context> &args);
|
void init(const basic_format_args<Context> &args);
|
||||||
~arg_map() { delete [] map_; }
|
~arg_map() { delete[] map_; }
|
||||||
|
|
||||||
basic_format_arg<Context> find(basic_string_view<char_type> name) const {
|
basic_format_arg<Context> find(basic_string_view<char_type> name) const {
|
||||||
// The list is unsorted, so just return the first matching name.
|
// The list is unsorted, so just return the first matching name.
|
||||||
@ -1014,8 +1065,8 @@ class context_base {
|
|||||||
// Checks if manual indexing is used and returns the argument with
|
// Checks if manual indexing is used and returns the argument with
|
||||||
// specified index.
|
// specified index.
|
||||||
format_arg get_arg(unsigned arg_id) {
|
format_arg get_arg(unsigned arg_id) {
|
||||||
return this->parse_context().check_arg_id(arg_id) ?
|
return this->parse_context().check_arg_id(arg_id) ? this->do_get_arg(arg_id)
|
||||||
this->do_get_arg(arg_id) : format_arg();
|
: format_arg();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1042,12 +1093,14 @@ class context_base {
|
|||||||
template <typename Context, typename T>
|
template <typename Context, typename T>
|
||||||
struct get_type {
|
struct get_type {
|
||||||
typedef decltype(make_value<Context>(
|
typedef decltype(make_value<Context>(
|
||||||
declval<typename std::decay<T>::type&>())) value_type;
|
declval<typename std::decay<T>::type &>())) value_type;
|
||||||
static const type value = value_type::type_tag;
|
static const type value = value_type::type_tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
FMT_CONSTEXPR11 unsigned long long get_types() { return 0; }
|
FMT_CONSTEXPR11 unsigned long long get_types() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Context, typename Arg, typename... Args>
|
template <typename Context, typename Arg, typename... Args>
|
||||||
FMT_CONSTEXPR11 unsigned long long get_types() {
|
FMT_CONSTEXPR11 unsigned long long get_types() {
|
||||||
@ -1063,22 +1116,22 @@ FMT_CONSTEXPR basic_format_arg<Context> make_arg(const T &value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <bool IS_PACKED, typename Context, typename T>
|
template <bool IS_PACKED, typename Context, typename T>
|
||||||
inline typename std::enable_if<IS_PACKED, value<Context>>::type
|
inline typename std::enable_if<IS_PACKED, value<Context>>::type make_arg(
|
||||||
make_arg(const T &value) {
|
const T &value) {
|
||||||
return make_value<Context>(value);
|
return make_value<Context>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool IS_PACKED, typename Context, typename T>
|
template <bool IS_PACKED, typename Context, typename T>
|
||||||
inline typename std::enable_if<!IS_PACKED, basic_format_arg<Context>>::type
|
inline typename std::enable_if<!IS_PACKED, basic_format_arg<Context>>::type
|
||||||
make_arg(const T &value) {
|
make_arg(const T &value) {
|
||||||
return make_arg<Context>(value);
|
return make_arg<Context>(value);
|
||||||
}
|
}
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
// Formatting context.
|
// Formatting context.
|
||||||
template <typename OutputIt, typename Char>
|
template <typename OutputIt, typename Char>
|
||||||
class basic_format_context :
|
class basic_format_context
|
||||||
public internal::context_base<
|
: public internal::context_base<
|
||||||
OutputIt, basic_format_context<OutputIt, Char>, Char> {
|
OutputIt, basic_format_context<OutputIt, Char>, Char> {
|
||||||
public:
|
public:
|
||||||
/** The character type for the output. */
|
/** The character type for the output. */
|
||||||
@ -1086,7 +1139,9 @@ class basic_format_context :
|
|||||||
|
|
||||||
// using formatter_type = formatter<T, char_type>;
|
// using formatter_type = formatter<T, char_type>;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct formatter_type { typedef formatter<T, char_type> type; };
|
struct formatter_type {
|
||||||
|
typedef formatter<T, char_type> type;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
internal::arg_map<basic_format_context> map_;
|
internal::arg_map<basic_format_context> map_;
|
||||||
@ -1123,7 +1178,8 @@ class basic_format_context :
|
|||||||
template <typename Char>
|
template <typename Char>
|
||||||
struct buffer_context {
|
struct buffer_context {
|
||||||
typedef basic_format_context<
|
typedef basic_format_context<
|
||||||
std::back_insert_iterator<internal::basic_buffer<Char>>, Char> type;
|
std::back_insert_iterator<internal::basic_buffer<Char>>, Char>
|
||||||
|
type;
|
||||||
};
|
};
|
||||||
typedef buffer_context<char>::type format_context;
|
typedef buffer_context<char>::type format_context;
|
||||||
typedef buffer_context<wchar_t>::type wformat_context;
|
typedef buffer_context<wchar_t>::type wformat_context;
|
||||||
@ -1135,7 +1191,7 @@ typedef buffer_context<wchar_t>::type wformat_context;
|
|||||||
such as `~fmt::vformat`.
|
such as `~fmt::vformat`.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename Context, typename ...Args>
|
template <typename Context, typename... Args>
|
||||||
class format_arg_store {
|
class format_arg_store {
|
||||||
private:
|
private:
|
||||||
static const size_t NUM_ARGS = sizeof...(Args);
|
static const size_t NUM_ARGS = sizeof...(Args);
|
||||||
@ -1143,8 +1199,8 @@ class format_arg_store {
|
|||||||
// Packed is a macro on MinGW so use IS_PACKED instead.
|
// Packed is a macro on MinGW so use IS_PACKED instead.
|
||||||
static const bool IS_PACKED = NUM_ARGS < internal::max_packed_args;
|
static const bool IS_PACKED = NUM_ARGS < internal::max_packed_args;
|
||||||
|
|
||||||
typedef typename std::conditional<IS_PACKED,
|
typedef typename std::conditional<IS_PACKED, internal::value<Context>,
|
||||||
internal::value<Context>, basic_format_arg<Context>>::type value_type;
|
basic_format_arg<Context>>::type value_type;
|
||||||
|
|
||||||
// If the arguments are not packed, add one more element to mark the end.
|
// If the arguments are not packed, add one more element to mark the end.
|
||||||
static const size_t DATA_SIZE =
|
static const size_t DATA_SIZE =
|
||||||
@ -1154,9 +1210,8 @@ class format_arg_store {
|
|||||||
friend class basic_format_args<Context>;
|
friend class basic_format_args<Context>;
|
||||||
|
|
||||||
static FMT_CONSTEXPR11 unsigned long long get_types() {
|
static FMT_CONSTEXPR11 unsigned long long get_types() {
|
||||||
return IS_PACKED ?
|
return IS_PACKED ? internal::get_types<Context, Args...>()
|
||||||
internal::get_types<Context, Args...>() :
|
: internal::is_unpacked_bit | NUM_ARGS;
|
||||||
internal::is_unpacked_bit | NUM_ARGS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1170,8 +1225,8 @@ class format_arg_store {
|
|||||||
(FMT_MSC_VER && FMT_MSC_VER <= 1800)
|
(FMT_MSC_VER && FMT_MSC_VER <= 1800)
|
||||||
// Workaround array initialization issues in gcc <= 4.5 and MSVC <= 2013.
|
// Workaround array initialization issues in gcc <= 4.5 and MSVC <= 2013.
|
||||||
format_arg_store(const Args &... args) {
|
format_arg_store(const Args &... args) {
|
||||||
value_type init[DATA_SIZE] =
|
value_type init[DATA_SIZE] = {
|
||||||
{internal::make_arg<IS_PACKED, Context>(args)...};
|
internal::make_arg<IS_PACKED, Context>(args)...};
|
||||||
std::memcpy(data_, init, sizeof(init));
|
std::memcpy(data_, init, sizeof(init));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -1181,7 +1236,7 @@ class format_arg_store {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if !FMT_USE_CONSTEXPR11
|
#if !FMT_USE_CONSTEXPR11
|
||||||
template <typename Context, typename ...Args>
|
template <typename Context, typename... Args>
|
||||||
const unsigned long long format_arg_store<Context, Args...>::TYPES =
|
const unsigned long long format_arg_store<Context, Args...>::TYPES =
|
||||||
get_types();
|
get_types();
|
||||||
#endif
|
#endif
|
||||||
@ -1193,9 +1248,11 @@ const unsigned long long format_arg_store<Context, Args...>::TYPES =
|
|||||||
can be omitted in which case it defaults to `~fmt::context`.
|
can be omitted in which case it defaults to `~fmt::context`.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename Context = format_context, typename ...Args>
|
template <typename Context = format_context, typename... Args>
|
||||||
inline format_arg_store<Context, Args...>
|
inline format_arg_store<Context, Args...> make_format_args(
|
||||||
make_format_args(const Args &... args) { return {args...}; }
|
const Args &... args) {
|
||||||
|
return {args...};
|
||||||
|
}
|
||||||
|
|
||||||
/** Formatting arguments. */
|
/** Formatting arguments. */
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
@ -1222,8 +1279,8 @@ class basic_format_args {
|
|||||||
|
|
||||||
typename internal::type type(unsigned index) const {
|
typename internal::type type(unsigned index) const {
|
||||||
unsigned shift = index * 4;
|
unsigned shift = index * 4;
|
||||||
return static_cast<typename internal::type>(
|
return static_cast<typename internal::type>((types_ & (0xfull << shift)) >>
|
||||||
(types_ & (0xfull << shift)) >> shift);
|
shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class internal::arg_map<Context>;
|
friend class internal::arg_map<Context>;
|
||||||
@ -1291,12 +1348,12 @@ class basic_format_args {
|
|||||||
/** An alias to ``basic_format_args<context>``. */
|
/** An alias to ``basic_format_args<context>``. */
|
||||||
// It is a separate type rather than a typedef to make symbols readable.
|
// It is a separate type rather than a typedef to make symbols readable.
|
||||||
struct format_args : basic_format_args<format_context> {
|
struct format_args : basic_format_args<format_context> {
|
||||||
template <typename ...Args>
|
template <typename... Args>
|
||||||
format_args(Args &&... arg)
|
format_args(Args &&... arg)
|
||||||
: basic_format_args<format_context>(std::forward<Args>(arg)...) {}
|
: basic_format_args<format_context>(std::forward<Args>(arg)...) {}
|
||||||
};
|
};
|
||||||
struct wformat_args : basic_format_args<wformat_context> {
|
struct wformat_args : basic_format_args<wformat_context> {
|
||||||
template <typename ...Args>
|
template <typename... Args>
|
||||||
wformat_args(Args &&... arg)
|
wformat_args(Args &&... arg)
|
||||||
: basic_format_args<wformat_context>(std::forward<Args>(arg)...) {}
|
: basic_format_args<wformat_context>(std::forward<Args>(arg)...) {}
|
||||||
};
|
};
|
||||||
@ -1304,18 +1361,18 @@ struct wformat_args : basic_format_args<wformat_context> {
|
|||||||
#define FMT_ENABLE_IF_T(B, T) typename std::enable_if<B, T>::type
|
#define FMT_ENABLE_IF_T(B, T) typename std::enable_if<B, T>::type
|
||||||
|
|
||||||
#ifndef FMT_USE_ALIAS_TEMPLATES
|
#ifndef FMT_USE_ALIAS_TEMPLATES
|
||||||
# define FMT_USE_ALIAS_TEMPLATES FMT_HAS_FEATURE(cxx_alias_templates)
|
#define FMT_USE_ALIAS_TEMPLATES FMT_HAS_FEATURE(cxx_alias_templates)
|
||||||
#endif
|
#endif
|
||||||
#if FMT_USE_ALIAS_TEMPLATES
|
#if FMT_USE_ALIAS_TEMPLATES
|
||||||
/** String's character type. */
|
/** String's character type. */
|
||||||
template <typename S>
|
template <typename S>
|
||||||
using char_t = FMT_ENABLE_IF_T(
|
using char_t = FMT_ENABLE_IF_T(internal::is_string<S>::value,
|
||||||
internal::is_string<S>::value, typename internal::char_t<S>::type);
|
typename internal::char_t<S>::type);
|
||||||
#define FMT_CHAR(S) fmt::char_t<S>
|
#define FMT_CHAR(S) fmt::char_t<S>
|
||||||
#else
|
#else
|
||||||
template <typename S>
|
template <typename S>
|
||||||
struct char_t : std::enable_if<
|
struct char_t : std::enable_if<internal::is_string<S>::value,
|
||||||
internal::is_string<S>::value, typename internal::char_t<S>::type> {};
|
typename internal::char_t<S>::type> {};
|
||||||
#define FMT_CHAR(S) typename char_t<S>::type
|
#define FMT_CHAR(S) typename char_t<S>::type
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1325,8 +1382,8 @@ struct named_arg_base {
|
|||||||
basic_string_view<Char> name;
|
basic_string_view<Char> name;
|
||||||
|
|
||||||
// Serialized value<context>.
|
// Serialized value<context>.
|
||||||
mutable char data[
|
mutable char
|
||||||
sizeof(basic_format_arg<typename buffer_context<Char>::type>)];
|
data[sizeof(basic_format_arg<typename buffer_context<Char>::type>)];
|
||||||
|
|
||||||
named_arg_base(basic_string_view<Char> nm) : name(nm) {}
|
named_arg_base(basic_string_view<Char> nm) : name(nm) {}
|
||||||
|
|
||||||
@ -1348,18 +1405,18 @@ struct named_arg : named_arg_base<Char> {
|
|||||||
|
|
||||||
template <typename... Args, typename S>
|
template <typename... Args, typename S>
|
||||||
inline typename std::enable_if<!is_compile_string<S>::value>::type
|
inline typename std::enable_if<!is_compile_string<S>::value>::type
|
||||||
check_format_string(const S &) {}
|
check_format_string(const S &) {}
|
||||||
template <typename... Args, typename S>
|
template <typename... Args, typename S>
|
||||||
typename std::enable_if<is_compile_string<S>::value>::type
|
typename std::enable_if<is_compile_string<S>::value>::type check_format_string(
|
||||||
check_format_string(S);
|
S);
|
||||||
|
|
||||||
template <typename S, typename... Args>
|
template <typename S, typename... Args>
|
||||||
struct checked_args : format_arg_store<
|
struct checked_args
|
||||||
typename buffer_context<FMT_CHAR(S)>::type, Args...> {
|
: format_arg_store<typename buffer_context<FMT_CHAR(S)>::type, Args...> {
|
||||||
typedef typename buffer_context<FMT_CHAR(S)>::type context;
|
typedef typename buffer_context<FMT_CHAR(S)>::type context;
|
||||||
|
|
||||||
checked_args(const S &format_str, const Args &... args):
|
checked_args(const S &format_str, const Args &... args)
|
||||||
format_arg_store<context, Args...>(args...) {
|
: format_arg_store<context, Args...>(args...) {
|
||||||
internal::check_format_string<Args...>(format_str);
|
internal::check_format_string<Args...>(format_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1375,7 +1432,7 @@ template <typename Char>
|
|||||||
typename buffer_context<Char>::type::iterator vformat_to(
|
typename buffer_context<Char>::type::iterator vformat_to(
|
||||||
internal::basic_buffer<Char> &buf, basic_string_view<Char> format_str,
|
internal::basic_buffer<Char> &buf, basic_string_view<Char> format_str,
|
||||||
basic_format_args<typename buffer_context<Char>::type> args);
|
basic_format_args<typename buffer_context<Char>::type> args);
|
||||||
}
|
} // namespace internal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
@ -1401,21 +1458,19 @@ template <typename S, typename T, typename Char>
|
|||||||
void arg(S, internal::named_arg<T, Char>) = delete;
|
void arg(S, internal::named_arg<T, Char>) = delete;
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
struct is_contiguous: std::false_type {};
|
struct is_contiguous : std::false_type {};
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
struct is_contiguous<std::basic_string<Char> >: std::true_type {};
|
struct is_contiguous<std::basic_string<Char>> : std::true_type {};
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
struct is_contiguous<internal::basic_buffer<Char> >: std::true_type {};
|
struct is_contiguous<internal::basic_buffer<Char>> : std::true_type {};
|
||||||
|
|
||||||
/** Formats a string and writes the output to ``out``. */
|
/** Formats a string and writes the output to ``out``. */
|
||||||
template <typename Container, typename S>
|
template <typename Container, typename S>
|
||||||
typename std::enable_if<
|
typename std::enable_if<is_contiguous<Container>::value,
|
||||||
is_contiguous<Container>::value, std::back_insert_iterator<Container>>::type
|
std::back_insert_iterator<Container>>::type
|
||||||
vformat_to(
|
vformat_to(std::back_insert_iterator<Container> out, const S &format_str,
|
||||||
std::back_insert_iterator<Container> out,
|
|
||||||
const S &format_str,
|
|
||||||
basic_format_args<typename buffer_context<FMT_CHAR(S)>::type> args) {
|
basic_format_args<typename buffer_context<FMT_CHAR(S)>::type> args) {
|
||||||
internal::container_buffer<Container> buf(internal::get_container(out));
|
internal::container_buffer<Container> buf(internal::get_container(out));
|
||||||
internal::vformat_to(buf, to_string_view(format_str), args);
|
internal::vformat_to(buf, to_string_view(format_str), args);
|
||||||
@ -1423,10 +1478,10 @@ typename std::enable_if<
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container, typename S, typename... Args>
|
template <typename Container, typename S, typename... Args>
|
||||||
inline typename std::enable_if<
|
inline typename std::enable_if<is_contiguous<Container>::value &&
|
||||||
is_contiguous<Container>::value && internal::is_string<S>::value,
|
internal::is_string<S>::value,
|
||||||
std::back_insert_iterator<Container>>::type
|
std::back_insert_iterator<Container>>::type
|
||||||
format_to(std::back_insert_iterator<Container> out, const S &format_str,
|
format_to(std::back_insert_iterator<Container> out, const S &format_str,
|
||||||
const Args &... args) {
|
const Args &... args) {
|
||||||
internal::checked_args<S, Args...> ca(format_str, args...);
|
internal::checked_args<S, Args...> ca(format_str, args...);
|
||||||
return vformat_to(out, to_string_view(format_str), *ca);
|
return vformat_to(out, to_string_view(format_str), *ca);
|
||||||
@ -1450,8 +1505,8 @@ inline std::basic_string<Char> vformat(
|
|||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename S, typename... Args>
|
template <typename S, typename... Args>
|
||||||
inline std::basic_string<FMT_CHAR(S)> format(
|
inline std::basic_string<FMT_CHAR(S)> format(const S &format_str,
|
||||||
const S &format_str, const Args &... args) {
|
const Args &... args) {
|
||||||
return internal::vformat(
|
return internal::vformat(
|
||||||
to_string_view(format_str),
|
to_string_view(format_str),
|
||||||
*internal::checked_args<S, Args...>(format_str, args...));
|
*internal::checked_args<S, Args...>(format_str, args...));
|
||||||
|
|||||||
@ -10,47 +10,46 @@
|
|||||||
|
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstddef> // for std::ptrdiff_t
|
#include <cstddef> // for std::ptrdiff_t
|
||||||
|
#include <cstring>
|
||||||
#include <cstring> // for std::memmove
|
#include <cstring> // for std::memmove
|
||||||
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
||||||
# include <locale>
|
#include <locale>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_USE_WINDOWS_H
|
#if FMT_USE_WINDOWS_H
|
||||||
# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
|
#if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
|
||||||
# define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
# endif
|
#endif
|
||||||
# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
|
#if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
|
||||||
# include <windows.h>
|
#include <windows.h>
|
||||||
# else
|
#else
|
||||||
# define NOMINMAX
|
#define NOMINMAX
|
||||||
# include <windows.h>
|
#include <windows.h>
|
||||||
# undef NOMINMAX
|
#undef NOMINMAX
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_EXCEPTIONS
|
#if FMT_EXCEPTIONS
|
||||||
# define FMT_TRY try
|
#define FMT_TRY try
|
||||||
# define FMT_CATCH(x) catch (x)
|
#define FMT_CATCH(x) catch (x)
|
||||||
#else
|
#else
|
||||||
# define FMT_TRY if (true)
|
#define FMT_TRY if (true)
|
||||||
# define FMT_CATCH(x) if (false)
|
#define FMT_CATCH(x) if (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(push)
|
#pragma warning(push)
|
||||||
# pragma warning(disable: 4127) // conditional expression is constant
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
# pragma warning(disable: 4702) // unreachable code
|
#pragma warning(disable : 4702) // unreachable code
|
||||||
// Disable deprecation warning for strerror. The latter is not called but
|
// Disable deprecation warning for strerror. The latter is not called but
|
||||||
// MSVC fails to detect it.
|
// MSVC fails to detect it.
|
||||||
# pragma warning(disable: 4996)
|
#pragma warning(disable : 4996)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Dummy implementations of strerror_r and strerror_s called if corresponding
|
// Dummy implementations of strerror_r and strerror_s called if corresponding
|
||||||
@ -67,7 +66,7 @@ FMT_BEGIN_NAMESPACE
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
# define FMT_SNPRINTF snprintf
|
#define FMT_SNPRINTF snprintf
|
||||||
#else // _MSC_VER
|
#else // _MSC_VER
|
||||||
inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
|
inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
@ -76,13 +75,13 @@ inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
# define FMT_SNPRINTF fmt_snprintf
|
#define FMT_SNPRINTF fmt_snprintf
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
|
#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
|
||||||
# define FMT_SWPRINTF snwprintf
|
#define FMT_SWPRINTF snwprintf
|
||||||
#else
|
#else
|
||||||
# define FMT_SWPRINTF swprintf
|
#define FMT_SWPRINTF swprintf
|
||||||
#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
|
#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
|
||||||
|
|
||||||
typedef void (*FormatFunc)(internal::buffer &, int, string_view);
|
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
|
// ERANGE - buffer is not large enough to store the error message
|
||||||
// other - failure
|
// other - failure
|
||||||
// Buffer should be at least of size 1.
|
// Buffer should be at least of size 1.
|
||||||
int safe_strerror(
|
int safe_strerror(int error_code, char *&buffer,
|
||||||
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
|
std::size_t buffer_size) FMT_NOEXCEPT {
|
||||||
FMT_ASSERT(buffer != FMT_NULL && buffer_size != 0, "invalid buffer");
|
FMT_ASSERT(buffer != FMT_NULL && buffer_size != 0, "invalid buffer");
|
||||||
|
|
||||||
class dispatcher {
|
class dispatcher {
|
||||||
@ -132,8 +131,8 @@ int safe_strerror(
|
|||||||
// Fallback to strerror_s when strerror_r is not available.
|
// Fallback to strerror_s when strerror_r is not available.
|
||||||
int fallback(int result) {
|
int fallback(int result) {
|
||||||
// If the buffer is full then the message is probably truncated.
|
// If the buffer is full then the message is probably truncated.
|
||||||
return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
|
return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE
|
||||||
ERANGE : result;
|
: result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !FMT_MSC_VER
|
#if !FMT_MSC_VER
|
||||||
@ -149,9 +148,7 @@ int safe_strerror(
|
|||||||
dispatcher(int err_code, char *&buf, std::size_t buf_size)
|
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() {
|
int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); }
|
||||||
return handle(strerror_r(error_code_, buffer_, buffer_size_));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
return dispatcher(error_code, buffer, buffer_size).run();
|
return dispatcher(error_code, buffer, buffer_size).run();
|
||||||
}
|
}
|
||||||
@ -215,15 +212,15 @@ locale_ref::locale_ref(const Locale &loc) : locale_(&loc) {
|
|||||||
template <typename Locale>
|
template <typename Locale>
|
||||||
Locale locale_ref::get() const {
|
Locale locale_ref::get() const {
|
||||||
static_assert(std::is_same<Locale, std::locale>::value, "");
|
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>
|
template <typename Char>
|
||||||
FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
|
FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
|
||||||
return std::use_facet<std::numpunct<Char> >(
|
return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
|
||||||
loc.get<std::locale>()).thousands_sep();
|
.thousands_sep();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace internal
|
||||||
#else
|
#else
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
|
FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
|
||||||
@ -231,8 +228,8 @@ FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_FUNC void system_error::init(
|
FMT_FUNC void system_error::init(int err_code, string_view format_str,
|
||||||
int err_code, string_view format_str, format_args args) {
|
format_args args) {
|
||||||
error_code_ = err_code;
|
error_code_ = err_code;
|
||||||
memory_buffer buffer;
|
memory_buffer buffer;
|
||||||
format_system_error(buffer, err_code, vformat(format_str, args));
|
format_system_error(buffer, err_code, vformat(format_str, args));
|
||||||
@ -242,20 +239,19 @@ FMT_FUNC void system_error::init(
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
int char_traits<char>::format_float(
|
int char_traits<char>::format_float(char *buf, std::size_t size,
|
||||||
char *buf, std::size_t size, const char *format, int precision, T value) {
|
const char *format, int precision,
|
||||||
return precision < 0 ?
|
T value) {
|
||||||
FMT_SNPRINTF(buf, size, format, value) :
|
return precision < 0 ? FMT_SNPRINTF(buf, size, format, value)
|
||||||
FMT_SNPRINTF(buf, size, format, precision, value);
|
: FMT_SNPRINTF(buf, size, format, precision, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
int char_traits<wchar_t>::format_float(
|
int char_traits<wchar_t>::format_float(wchar_t *buf, std::size_t size,
|
||||||
wchar_t *buf, std::size_t size, const wchar_t *format, int precision,
|
const wchar_t *format, int precision,
|
||||||
T value) {
|
T value) {
|
||||||
return precision < 0 ?
|
return precision < 0 ? FMT_SWPRINTF(buf, size, format, value)
|
||||||
FMT_SWPRINTF(buf, size, format, value) :
|
: FMT_SWPRINTF(buf, size, format, precision, value);
|
||||||
FMT_SWPRINTF(buf, size, format, precision, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -267,33 +263,21 @@ const char basic_data<T>::DIGITS[] =
|
|||||||
"8081828384858687888990919293949596979899";
|
"8081828384858687888990919293949596979899";
|
||||||
|
|
||||||
#define FMT_POWERS_OF_10(factor) \
|
#define FMT_POWERS_OF_10(factor) \
|
||||||
factor * 10, \
|
factor * 10, factor * 100, factor * 1000, factor * 10000, factor * 100000, \
|
||||||
factor * 100, \
|
factor * 1000000, factor * 10000000, factor * 100000000, \
|
||||||
factor * 1000, \
|
|
||||||
factor * 10000, \
|
|
||||||
factor * 100000, \
|
|
||||||
factor * 1000000, \
|
|
||||||
factor * 10000000, \
|
|
||||||
factor * 100000000, \
|
|
||||||
factor * 1000000000
|
factor * 1000000000
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const uint32_t basic_data<T>::POWERS_OF_10_32[] = {
|
const uint32_t basic_data<T>::POWERS_OF_10_32[] = {1, FMT_POWERS_OF_10(1)};
|
||||||
1, FMT_POWERS_OF_10(1)
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {
|
const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {0,
|
||||||
0, FMT_POWERS_OF_10(1)
|
FMT_POWERS_OF_10(1)};
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const uint64_t basic_data<T>::ZERO_OR_POWERS_OF_10_64[] = {
|
const uint64_t basic_data<T>::ZERO_OR_POWERS_OF_10_64[] = {
|
||||||
0,
|
0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ull),
|
||||||
FMT_POWERS_OF_10(1),
|
10000000000000000000ull};
|
||||||
FMT_POWERS_OF_10(1000000000ull),
|
|
||||||
10000000000000000000ull
|
|
||||||
};
|
|
||||||
|
|
||||||
// Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
|
// Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
|
||||||
// These are generated by support/compute-powers.py.
|
// These are generated by support/compute-powers.py.
|
||||||
@ -341,13 +325,16 @@ const int16_t basic_data<T>::POW10_EXPONENTS[] = {
|
|||||||
-50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
|
-50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
|
||||||
242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
|
242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
|
||||||
534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
|
534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
|
||||||
827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066
|
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>
|
||||||
template <typename T> const char basic_data<T>::BACKGROUND_COLOR[] = "\x1b[48;2;";
|
const char basic_data<T>::FOREGROUND_COLOR[] = "\x1b[38;2;";
|
||||||
template <typename T> const char basic_data<T>::RESET_COLOR[] = "\x1b[0m";
|
template <typename T>
|
||||||
template <typename T> const wchar_t basic_data<T>::WRESET_COLOR[] = L"\x1b[0m";
|
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).
|
// A handmade floating-point number f * pow(2, e).
|
||||||
class fp {
|
class fp {
|
||||||
@ -371,8 +358,8 @@ class fp {
|
|||||||
static FMT_CONSTEXPR_DECL const int significand_size =
|
static FMT_CONSTEXPR_DECL const int significand_size =
|
||||||
sizeof(significand_type) * char_size;
|
sizeof(significand_type) * char_size;
|
||||||
|
|
||||||
fp(): f(0), e(0) {}
|
fp() : f(0), e(0) {}
|
||||||
fp(uint64_t f_val, int e_val): f(f_val), e(e_val) {}
|
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
|
// Constructs fp from an IEEE754 double. It is a template to prevent compile
|
||||||
// errors on platforms where double is not IEEE754.
|
// errors on platforms where double is not IEEE754.
|
||||||
@ -416,8 +403,8 @@ class fp {
|
|||||||
// (lower) or successor (upper). The upper boundary is normalized and lower
|
// (lower) or successor (upper). The upper boundary is normalized and lower
|
||||||
// has the same exponent but may be not normalized.
|
// has the same exponent but may be not normalized.
|
||||||
void compute_boundaries(fp &lower, fp &upper) const {
|
void compute_boundaries(fp &lower, fp &upper) const {
|
||||||
lower = f == implicit_bit ?
|
lower =
|
||||||
fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
|
f == implicit_bit ? fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1);
|
||||||
upper = 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.
|
upper.normalize<1>(); // 1 is to account for the exponent shift above.
|
||||||
lower.f <<= lower.e - upper.e;
|
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
|
// 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);
|
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
|
// 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) {
|
FMT_FUNC fp get_cached_power(int min_exponent, int &pow10_exponent) {
|
||||||
const double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10)
|
const double one_over_log2_10 = 0.30102999566398114; // 1 / log2(10)
|
||||||
int index = static_cast<int>(std::ceil(
|
int index = static_cast<int>(
|
||||||
(min_exponent + fp::significand_size - 1) * one_over_log2_10));
|
std::ceil((min_exponent + fp::significand_size - 1) * one_over_log2_10));
|
||||||
// Decimal exponent of the first (smallest) cached power of 10.
|
// Decimal exponent of the first (smallest) cached power of 10.
|
||||||
const int first_dec_exp = -348;
|
const int first_dec_exp = -348;
|
||||||
// Difference between 2 consecutive decimal exponents in cached powers of 10.
|
// Difference between 2 consecutive decimal exponents in cached powers of 10.
|
||||||
@ -463,10 +451,11 @@ FMT_FUNC fp get_cached_power(int min_exponent, int &pow10_exponent) {
|
|||||||
return fp(data::POW10_SIGNIFICANDS[index], data::POW10_EXPONENTS[index]);
|
return fp(data::POW10_SIGNIFICANDS[index], data::POW10_EXPONENTS[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC bool grisu2_round(
|
FMT_FUNC bool grisu2_round(char *buf, ptrdiff_t &size, size_t max_digits,
|
||||||
char *buf, ptrdiff_t &size, size_t max_digits, uint64_t delta,
|
uint64_t delta, uint64_t remainder, uint64_t exp,
|
||||||
uint64_t remainder, uint64_t exp, uint64_t diff, int &exp10) {
|
uint64_t diff, int &exp10) {
|
||||||
while (remainder < diff && delta - remainder >= exp &&
|
while (
|
||||||
|
remainder < diff && delta - remainder >= exp &&
|
||||||
(remainder + exp < diff || diff - remainder > remainder + exp - diff)) {
|
(remainder + exp < diff || diff - remainder > remainder + exp - diff)) {
|
||||||
--buf[size - 1];
|
--buf[size - 1];
|
||||||
remainder += exp;
|
remainder += exp;
|
||||||
@ -481,25 +470,56 @@ FMT_FUNC bool grisu2_round(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generates output using Grisu2 digit-gen algorithm.
|
// Generates output using Grisu2 digit-gen algorithm.
|
||||||
FMT_FUNC bool grisu2_gen_digits(
|
FMT_FUNC bool grisu2_gen_digits(char *buf, ptrdiff_t &size, uint32_t hi,
|
||||||
char *buf, ptrdiff_t &size, uint32_t hi, uint64_t lo, int &exp,
|
uint64_t lo, int &exp, uint64_t delta,
|
||||||
uint64_t delta, const fp &one, const fp &diff, size_t max_digits) {
|
const fp &one, const fp &diff,
|
||||||
|
size_t max_digits) {
|
||||||
// Generate digits for the most significant part (hi).
|
// Generate digits for the most significant part (hi).
|
||||||
while (exp > 0) {
|
while (exp > 0) {
|
||||||
uint32_t digit = 0;
|
uint32_t digit = 0;
|
||||||
// This optimization by miloyip reduces the number of integer divisions by
|
// This optimization by miloyip reduces the number of integer divisions by
|
||||||
// one per iteration.
|
// one per iteration.
|
||||||
switch (exp) {
|
switch (exp) {
|
||||||
case 10: digit = hi / 1000000000; hi %= 1000000000; break;
|
case 10:
|
||||||
case 9: digit = hi / 100000000; hi %= 100000000; break;
|
digit = hi / 1000000000;
|
||||||
case 8: digit = hi / 10000000; hi %= 10000000; break;
|
hi %= 1000000000;
|
||||||
case 7: digit = hi / 1000000; hi %= 1000000; break;
|
break;
|
||||||
case 6: digit = hi / 100000; hi %= 100000; break;
|
case 9:
|
||||||
case 5: digit = hi / 10000; hi %= 10000; break;
|
digit = hi / 100000000;
|
||||||
case 4: digit = hi / 1000; hi %= 1000; break;
|
hi %= 100000000;
|
||||||
case 3: digit = hi / 100; hi %= 100; break;
|
break;
|
||||||
case 2: digit = hi / 10; hi %= 10; break;
|
case 8:
|
||||||
case 1: digit = hi; hi = 0; break;
|
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:
|
default:
|
||||||
FMT_ASSERT(false, "invalid number of digits");
|
FMT_ASSERT(false, "invalid number of digits");
|
||||||
}
|
}
|
||||||
@ -510,8 +530,8 @@ FMT_FUNC bool grisu2_gen_digits(
|
|||||||
if (remainder <= delta || size > static_cast<ptrdiff_t>(max_digits)) {
|
if (remainder <= delta || size > static_cast<ptrdiff_t>(max_digits)) {
|
||||||
return grisu2_round(
|
return grisu2_round(
|
||||||
buf, size, max_digits, delta, remainder,
|
buf, size, max_digits, delta, remainder,
|
||||||
static_cast<uint64_t>(data::POWERS_OF_10_32[exp]) << -one.e,
|
static_cast<uint64_t>(data::POWERS_OF_10_32[exp]) << -one.e, diff.f,
|
||||||
diff.f, exp);
|
exp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Generate digits for the least significant part (lo).
|
// Generate digits for the least significant part (lo).
|
||||||
@ -531,11 +551,11 @@ FMT_FUNC bool grisu2_gen_digits(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if FMT_CLANG_VERSION
|
#if FMT_CLANG_VERSION
|
||||||
# define FMT_FALLTHROUGH [[clang::fallthrough]];
|
#define FMT_FALLTHROUGH [[clang::fallthrough]];
|
||||||
#elif FMT_GCC_VERSION >= 700
|
#elif FMT_GCC_VERSION >= 700
|
||||||
# define FMT_FALLTHROUGH [[gnu::fallthrough]];
|
#define FMT_FALLTHROUGH [[gnu::fallthrough]];
|
||||||
#else
|
#else
|
||||||
# define FMT_FALLTHROUGH
|
#define FMT_FALLTHROUGH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct gen_digits_params {
|
struct gen_digits_params {
|
||||||
@ -616,8 +636,8 @@ struct fill {
|
|||||||
|
|
||||||
// The number is given as v = f * pow(10, exp), where f has size digits.
|
// The number is given as v = f * pow(10, exp), where f has size digits.
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
FMT_FUNC void grisu2_prettify(const gen_digits_params ¶ms,
|
FMT_FUNC void grisu2_prettify(const gen_digits_params ¶ms, int size,
|
||||||
int size, int exp, Handler &&handler) {
|
int exp, Handler &&handler) {
|
||||||
if (!params.fixed) {
|
if (!params.fixed) {
|
||||||
// Insert a decimal point after the first digit and add an exponent.
|
// Insert a decimal point after the first digit and add an exponent.
|
||||||
handler.insert(1, '.');
|
handler.insert(1, '.');
|
||||||
@ -660,7 +680,9 @@ struct char_counter {
|
|||||||
ptrdiff_t size;
|
ptrdiff_t size;
|
||||||
|
|
||||||
template <typename F>
|
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 insert(ptrdiff_t, char) { ++size; }
|
||||||
void append(ptrdiff_t n, char) { size += n; }
|
void append(ptrdiff_t n, char) { size += n; }
|
||||||
void append(char) { ++size; }
|
void append(char) { ++size; }
|
||||||
@ -678,7 +700,8 @@ FMT_FUNC gen_digits_params process_specs(const core_format_specs &specs,
|
|||||||
case 'G':
|
case 'G':
|
||||||
params.upper = true;
|
params.upper = true;
|
||||||
FMT_FALLTHROUGH
|
FMT_FALLTHROUGH
|
||||||
case '\0': case 'g':
|
case '\0':
|
||||||
|
case 'g':
|
||||||
params.trailing_zeros = (specs.flags & HASH_FLAG) != 0;
|
params.trailing_zeros = (specs.flags & HASH_FLAG) != 0;
|
||||||
if (-4 <= exp && exp < num_digits + 1) {
|
if (-4 <= exp && exp < num_digits + 1) {
|
||||||
params.fixed = true;
|
params.fixed = true;
|
||||||
@ -713,7 +736,7 @@ FMT_FUNC gen_digits_params process_specs(const core_format_specs &specs,
|
|||||||
|
|
||||||
template <typename Double>
|
template <typename Double>
|
||||||
FMT_FUNC typename std::enable_if<sizeof(Double) == sizeof(uint64_t), bool>::type
|
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");
|
FMT_ASSERT(value >= 0, "value is negative");
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
gen_digits_params params = process_specs(specs, 1, buf);
|
gen_digits_params params = process_specs(specs, 1, buf);
|
||||||
@ -767,7 +790,7 @@ void sprintf_format(Double value, internal::buffer &buf,
|
|||||||
FMT_ASSERT(buf.capacity() != 0, "empty buffer");
|
FMT_ASSERT(buf.capacity() != 0, "empty buffer");
|
||||||
|
|
||||||
// Build format string.
|
// 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[MAX_FORMAT_SIZE];
|
||||||
char *format_ptr = format;
|
char *format_ptr = format;
|
||||||
*format_ptr++ = '%';
|
*format_ptr++ = '%';
|
||||||
@ -819,13 +842,13 @@ FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = MultiByteToWideChar(
|
int length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(),
|
||||||
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0);
|
s_size, FMT_NULL, 0);
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
|
FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
|
||||||
buffer_.resize(length + 1);
|
buffer_.resize(length + 1);
|
||||||
length = MultiByteToWideChar(
|
length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size,
|
||||||
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
|
&buffer_[0], length);
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
|
FMT_THROW(windows_error(GetLastError(), ERROR_MSG));
|
||||||
buffer_[length] = 0;
|
buffer_[length] = 0;
|
||||||
@ -849,21 +872,21 @@ FMT_FUNC int internal::utf16_to_utf8::convert(wstring_view s) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = WideCharToMultiByte(
|
int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0,
|
||||||
CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL);
|
FMT_NULL, FMT_NULL);
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
buffer_.resize(length + 1);
|
buffer_.resize(length + 1);
|
||||||
length = WideCharToMultiByte(
|
length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0],
|
||||||
CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL);
|
length, FMT_NULL, FMT_NULL);
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
buffer_[length] = 0;
|
buffer_[length] = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC void windows_error::init(
|
FMT_FUNC void windows_error::init(int err_code, string_view format_str,
|
||||||
int err_code, string_view format_str, format_args args) {
|
format_args args) {
|
||||||
error_code_ = err_code;
|
error_code_ = err_code;
|
||||||
memory_buffer buffer;
|
memory_buffer buffer;
|
||||||
internal::format_windows_error(buffer, err_code, vformat(format_str, args));
|
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));
|
base = std::runtime_error(to_string(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC void internal::format_windows_error(
|
FMT_FUNC void internal::format_windows_error(internal::buffer &out,
|
||||||
internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
|
int error_code,
|
||||||
|
string_view message) FMT_NOEXCEPT {
|
||||||
FMT_TRY {
|
FMT_TRY {
|
||||||
wmemory_buffer buf;
|
wmemory_buffer buf;
|
||||||
buf.resize(inline_buffer_size);
|
buf.resize(inline_buffer_size);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
wchar_t *system_message = &buf[0];
|
wchar_t *system_message = &buf[0];
|
||||||
int result = FormatMessageW(
|
int result = FormatMessageW(
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, FMT_NULL,
|
||||||
FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), system_message,
|
||||||
system_message, static_cast<uint32_t>(buf.size()), FMT_NULL);
|
static_cast<uint32_t>(buf.size()), FMT_NULL);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
utf16_to_utf8 utf8_message;
|
utf16_to_utf8 utf8_message;
|
||||||
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
|
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.
|
break; // Can't get error message, report error code instead.
|
||||||
buf.resize(buf.size() * 2);
|
buf.resize(buf.size() * 2);
|
||||||
}
|
}
|
||||||
} FMT_CATCH(...) {}
|
}
|
||||||
|
FMT_CATCH(...) {}
|
||||||
format_error_code(out, error_code, message);
|
format_error_code(out, error_code, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FMT_USE_WINDOWS_H
|
#endif // FMT_USE_WINDOWS_H
|
||||||
|
|
||||||
FMT_FUNC void format_system_error(
|
FMT_FUNC void format_system_error(internal::buffer &out, int error_code,
|
||||||
internal::buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
|
string_view message) FMT_NOEXCEPT {
|
||||||
FMT_TRY {
|
FMT_TRY {
|
||||||
memory_buffer buf;
|
memory_buffer buf;
|
||||||
buf.resize(inline_buffer_size);
|
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.
|
break; // Can't get error message, report error code instead.
|
||||||
buf.resize(buf.size() * 2);
|
buf.resize(buf.size() * 2);
|
||||||
}
|
}
|
||||||
} FMT_CATCH(...) {}
|
}
|
||||||
|
FMT_CATCH(...) {}
|
||||||
format_error_code(out, error_code, message);
|
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_THROW(format_error(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC void report_system_error(
|
FMT_FUNC void report_system_error(int error_code,
|
||||||
int error_code, fmt::string_view message) FMT_NOEXCEPT {
|
fmt::string_view message) FMT_NOEXCEPT {
|
||||||
report_error(format_system_error, error_code, message);
|
report_error(format_system_error, error_code, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FMT_USE_WINDOWS_H
|
#if FMT_USE_WINDOWS_H
|
||||||
FMT_FUNC void report_windows_error(
|
FMT_FUNC void report_windows_error(int error_code,
|
||||||
int error_code, fmt::string_view message) FMT_NOEXCEPT {
|
fmt::string_view message) FMT_NOEXCEPT {
|
||||||
report_error(internal::format_windows_error, error_code, message);
|
report_error(internal::format_windows_error, error_code, message);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -966,7 +992,7 @@ FMT_FUNC void vprint(wstring_view format_str, wformat_args args) {
|
|||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // FMT_FORMAT_INL_H_
|
#endif // FMT_FORMAT_INL_H_
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
|||||||
#define FMT_LOCALE_H_
|
#define FMT_LOCALE_H_
|
||||||
|
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
@ -19,9 +20,9 @@ typename buffer_context<Char>::type::iterator vformat_to(
|
|||||||
const std::locale &loc, basic_buffer<Char> &buf,
|
const std::locale &loc, basic_buffer<Char> &buf,
|
||||||
basic_string_view<Char> format_str,
|
basic_string_view<Char> format_str,
|
||||||
basic_format_args<typename buffer_context<Char>::type> args) {
|
basic_format_args<typename buffer_context<Char>::type> args) {
|
||||||
typedef back_insert_range<basic_buffer<Char> > range;
|
typedef back_insert_range<basic_buffer<Char>> range;
|
||||||
return vformat_to<arg_formatter<range>>(
|
return vformat_to<arg_formatter<range>>(buf, to_string_view(format_str), args,
|
||||||
buf, to_string_view(format_str), args, internal::locale_ref(loc));
|
internal::locale_ref(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@ -32,7 +33,7 @@ std::basic_string<Char> vformat(
|
|||||||
internal::vformat_to(loc, buffer, format_str, args);
|
internal::vformat_to(loc, buffer, format_str, args);
|
||||||
return fmt::to_string(buffer);
|
return fmt::to_string(buffer);
|
||||||
}
|
}
|
||||||
}
|
} // namespace internal
|
||||||
|
|
||||||
template <typename S, typename Char = FMT_CHAR(S)>
|
template <typename S, typename Char = FMT_CHAR(S)>
|
||||||
inline std::basic_string<Char> vformat(
|
inline std::basic_string<Char> vformat(
|
||||||
@ -42,8 +43,9 @@ inline std::basic_string<Char> vformat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename S, typename... Args>
|
template <typename S, typename... Args>
|
||||||
inline std::basic_string<FMT_CHAR(S)> format(
|
inline std::basic_string<FMT_CHAR(S)> format(const std::locale &loc,
|
||||||
const std::locale &loc, const S &format_str, const Args &... args) {
|
const S &format_str,
|
||||||
|
const Args &... args) {
|
||||||
return internal::vformat(
|
return internal::vformat(
|
||||||
loc, to_string_view(format_str),
|
loc, to_string_view(format_str),
|
||||||
*internal::checked_args<S, Args...>(format_str, args...));
|
*internal::checked_args<S, Args...>(format_str, args...));
|
||||||
@ -52,7 +54,7 @@ inline std::basic_string<FMT_CHAR(S)> format(
|
|||||||
template <typename String, typename OutputIt, typename... Args>
|
template <typename String, typename OutputIt, typename... Args>
|
||||||
inline typename std::enable_if<internal::is_output_iterator<OutputIt>::value,
|
inline typename std::enable_if<internal::is_output_iterator<OutputIt>::value,
|
||||||
OutputIt>::type
|
OutputIt>::type
|
||||||
vformat_to(OutputIt out, const std::locale &loc, const String &format_str,
|
vformat_to(OutputIt out, const std::locale &loc, const String &format_str,
|
||||||
typename format_args_t<OutputIt, FMT_CHAR(String)>::type args) {
|
typename format_args_t<OutputIt, FMT_CHAR(String)>::type args) {
|
||||||
typedef output_range<OutputIt, FMT_CHAR(String)> range;
|
typedef output_range<OutputIt, FMT_CHAR(String)> range;
|
||||||
return vformat_to<arg_formatter<range>>(
|
return vformat_to<arg_formatter<range>>(
|
||||||
@ -60,9 +62,10 @@ inline typename std::enable_if<internal::is_output_iterator<OutputIt>::value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIt, typename S, typename... Args>
|
template <typename OutputIt, typename S, typename... Args>
|
||||||
inline typename std::enable_if<
|
inline
|
||||||
internal::is_string<S>::value &&
|
typename std::enable_if<internal::is_string<S>::value &&
|
||||||
internal::is_output_iterator<OutputIt>::value, OutputIt>::type
|
internal::is_output_iterator<OutputIt>::value,
|
||||||
|
OutputIt>::type
|
||||||
format_to(OutputIt out, const std::locale &loc, const S &format_str,
|
format_to(OutputIt out, const std::locale &loc, const S &format_str,
|
||||||
const Args &... args) {
|
const Args &... args) {
|
||||||
internal::check_format_string<Args...>(format_str);
|
internal::check_format_string<Args...>(format_str);
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#define FMT_OSTREAM_H_
|
#define FMT_OSTREAM_H_
|
||||||
|
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
@ -53,14 +54,16 @@ struct test_stream : std::basic_ostream<Char> {
|
|||||||
void operator<<(null);
|
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>
|
template <typename T, typename Char>
|
||||||
class is_streamable {
|
class is_streamable {
|
||||||
private:
|
private:
|
||||||
template <typename U>
|
template <typename U>
|
||||||
static decltype(
|
static decltype(
|
||||||
internal::declval<test_stream<Char>&>()
|
internal::declval<test_stream<Char> &>() << internal::declval<U>(),
|
||||||
<< internal::declval<U>(), std::true_type()) test(int);
|
std::true_type())
|
||||||
|
test(int);
|
||||||
|
|
||||||
template <typename>
|
template <typename>
|
||||||
static std::false_type test(...);
|
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).
|
// function (not a member of std::ostream).
|
||||||
template <typename T, typename Char>
|
template <typename T, typename Char>
|
||||||
struct convert_to_int<T, Char, void> {
|
struct convert_to_int<T, Char, void> {
|
||||||
static const bool value =
|
static const bool value = convert_to_int<T, Char, int>::value &&
|
||||||
convert_to_int<T, Char, int>::value &&
|
|
||||||
!internal::is_streamable<T, Char>::value;
|
!internal::is_streamable<T, Char>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Formats an object of type T that has an overloaded ostream operator<<.
|
// Formats an object of type T that has an overloaded ostream operator<<.
|
||||||
template <typename T, typename Char>
|
template <typename T, typename Char>
|
||||||
struct formatter<T, Char,
|
struct formatter<
|
||||||
|
T,
|
||||||
|
Char,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
internal::is_streamable<T, Char>::value &&
|
internal::is_streamable<T, Char>::value &&
|
||||||
!internal::format_type<
|
!internal::format_type<typename buffer_context<Char>::type, T>::value>::
|
||||||
typename buffer_context<Char>::type, T>::value>::type>
|
type> : formatter<basic_string_view<Char>, Char> {
|
||||||
: formatter<basic_string_view<Char>, Char> {
|
|
||||||
|
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
auto format(const T &value, Context &ctx) -> decltype(ctx.out()) {
|
auto format(const T &value, Context &ctx) -> decltype(ctx.out()) {
|
||||||
basic_memory_buffer<Char> buffer;
|
basic_memory_buffer<Char> buffer;
|
||||||
@ -125,7 +127,8 @@ struct formatter<T, Char,
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline void vprint(std::basic_ostream<Char> &os,
|
inline void vprint(
|
||||||
|
std::basic_ostream<Char> &os,
|
||||||
basic_string_view<Char> format_str,
|
basic_string_view<Char> format_str,
|
||||||
basic_format_args<typename buffer_context<Char>::type> args) {
|
basic_format_args<typename buffer_context<Char>::type> args) {
|
||||||
basic_memory_buffer<Char> buffer;
|
basic_memory_buffer<Char> buffer;
|
||||||
@ -142,9 +145,10 @@ inline void vprint(std::basic_ostream<Char> &os,
|
|||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename S, typename... Args>
|
template <typename S, typename... Args>
|
||||||
inline typename std::enable_if<internal::is_string<S>::value>::type
|
inline typename std::enable_if<internal::is_string<S>::value>::type print(
|
||||||
print(std::basic_ostream<FMT_CHAR(S)> &os, const S &format_str,
|
std::basic_ostream<FMT_CHAR(S)> &os,
|
||||||
const Args & ... args) {
|
const S &format_str,
|
||||||
|
const Args &... args) {
|
||||||
internal::checked_args<S, Args...> ca(format_str, args...);
|
internal::checked_args<S, Args...> ca(format_str, args...);
|
||||||
vprint(os, to_string_view(format_str), *ca);
|
vprint(os, to_string_view(format_str), *ca);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
||||||
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
|
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
|
||||||
# undef __STRICT_ANSI__
|
#undef __STRICT_ANSI__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -22,42 +22,42 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#if defined __APPLE__ || defined(__FreeBSD__)
|
#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
|
#endif
|
||||||
|
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
#ifndef FMT_POSIX
|
#ifndef FMT_POSIX
|
||||||
# if defined(_WIN32) && !defined(__MINGW32__)
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||||
// Fix warnings about deprecated symbols.
|
// Fix warnings about deprecated symbols.
|
||||||
# define FMT_POSIX(call) _##call
|
#define FMT_POSIX(call) _##call
|
||||||
# else
|
#else
|
||||||
# define FMT_POSIX(call) call
|
#define FMT_POSIX(call) call
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
|
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
|
||||||
#ifdef FMT_SYSTEM
|
#ifdef FMT_SYSTEM
|
||||||
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
#define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
||||||
#else
|
#else
|
||||||
# define FMT_SYSTEM(call) call
|
#define FMT_SYSTEM(call) call
|
||||||
# ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Fix warnings about deprecated symbols.
|
// Fix warnings about deprecated symbols.
|
||||||
# define FMT_POSIX_CALL(call) ::_##call
|
#define FMT_POSIX_CALL(call) ::_##call
|
||||||
# else
|
#else
|
||||||
# define FMT_POSIX_CALL(call) ::call
|
#define FMT_POSIX_CALL(call) ::call
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Retries the expression while it evaluates to error_result and errno
|
// Retries the expression while it evaluates to error_result and errno
|
||||||
// equals to EINTR.
|
// equals to EINTR.
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# define FMT_RETRY_VAL(result, expression, error_result) \
|
#define FMT_RETRY_VAL(result, expression, error_result) \
|
||||||
do { \
|
do { \
|
||||||
result = (expression); \
|
result = (expression); \
|
||||||
} while (result == error_result && errno == EINTR)
|
} while (result == error_result && errno == EINTR)
|
||||||
#else
|
#else
|
||||||
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
|
#define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
||||||
@ -143,13 +143,12 @@ class buffered_file {
|
|||||||
buffered_file(const buffered_file &) = delete;
|
buffered_file(const buffered_file &) = delete;
|
||||||
void operator=(const buffered_file &) = delete;
|
void operator=(const buffered_file &) = delete;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
buffered_file(buffered_file &&other) FMT_NOEXCEPT : file_(other.file_) {
|
buffered_file(buffered_file &&other) FMT_NOEXCEPT : file_(other.file_) {
|
||||||
other.file_ = FMT_NULL;
|
other.file_ = FMT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffered_file& operator=(buffered_file &&other) {
|
buffered_file &operator=(buffered_file &&other) {
|
||||||
close();
|
close();
|
||||||
file_ = other.file_;
|
file_ = other.file_;
|
||||||
other.file_ = FMT_NULL;
|
other.file_ = FMT_NULL;
|
||||||
@ -167,14 +166,14 @@ class buffered_file {
|
|||||||
|
|
||||||
// We place parentheses around fileno to workaround a bug in some versions
|
// We place parentheses around fileno to workaround a bug in some versions
|
||||||
// of MinGW that define fileno as a macro.
|
// 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) {
|
void vprint(string_view format_str, format_args args) {
|
||||||
fmt::vprint(file_, format_str, args);
|
fmt::vprint(file_, format_str, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... 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...));
|
vprint(format_str, make_format_args(args...));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -211,11 +210,9 @@ class file {
|
|||||||
void operator=(const file &) = delete;
|
void operator=(const file &) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
file(file &&other) FMT_NOEXCEPT : fd_(other.fd_) {
|
file(file &&other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; }
|
||||||
other.fd_ = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
file& operator=(file &&other) {
|
file &operator=(file &&other) {
|
||||||
close();
|
close();
|
||||||
fd_ = other.fd_;
|
fd_ = other.fd_;
|
||||||
other.fd_ = -1;
|
other.fd_ = -1;
|
||||||
@ -268,14 +265,14 @@ 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(__ANDROID__) && !defined(__CYGWIN__) && !defined(__OpenBSD__) && \
|
||||||
!defined(__NEWLIB_H__)
|
!defined(__NEWLIB_H__)
|
||||||
# define FMT_LOCALE
|
#define FMT_LOCALE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FMT_LOCALE
|
#ifdef FMT_LOCALE
|
||||||
// A "C" numeric locale.
|
// A "C" numeric locale.
|
||||||
class Locale {
|
class Locale {
|
||||||
private:
|
private:
|
||||||
# ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
typedef _locale_t locale_t;
|
typedef _locale_t locale_t;
|
||||||
|
|
||||||
enum { LC_NUMERIC_MASK = LC_NUMERIC };
|
enum { LC_NUMERIC_MASK = LC_NUMERIC };
|
||||||
@ -284,14 +281,12 @@ class Locale {
|
|||||||
return _create_locale(category_mask, locale);
|
return _create_locale(category_mask, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freelocale(locale_t locale) {
|
static void freelocale(locale_t locale) { _free_locale(locale); }
|
||||||
_free_locale(locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double strtod_l(const char *nptr, char **endptr, _locale_t locale) {
|
static double strtod_l(const char *nptr, char **endptr, _locale_t locale) {
|
||||||
return _strtod_l(nptr, endptr, locale);
|
return _strtod_l(nptr, endptr, locale);
|
||||||
}
|
}
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
locale_t locale_;
|
locale_t locale_;
|
||||||
|
|
||||||
|
|||||||
@ -8,11 +8,11 @@
|
|||||||
#ifndef FMT_PRINTF_H_
|
#ifndef FMT_PRINTF_H_
|
||||||
#define FMT_PRINTF_H_
|
#define FMT_PRINTF_H_
|
||||||
|
|
||||||
|
#include "ostream.h"
|
||||||
|
|
||||||
#include <algorithm> // std::fill_n
|
#include <algorithm> // std::fill_n
|
||||||
#include <limits> // std::numeric_limits
|
#include <limits> // std::numeric_limits
|
||||||
|
|
||||||
#include "ostream.h"
|
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@ -24,8 +24,8 @@ class null_terminating_iterator {
|
|||||||
public:
|
public:
|
||||||
typedef std::ptrdiff_t difference_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
typedef Char value_type;
|
typedef Char value_type;
|
||||||
typedef const Char* pointer;
|
typedef const Char *pointer;
|
||||||
typedef const Char& reference;
|
typedef const Char &reference;
|
||||||
typedef std::random_access_iterator_tag iterator_category;
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
|
||||||
null_terminating_iterator() : ptr_(0), end_(0) {}
|
null_terminating_iterator() : ptr_(0), end_(0) {}
|
||||||
@ -43,9 +43,7 @@ class null_terminating_iterator {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR Char operator*() const {
|
FMT_CONSTEXPR Char operator*() const { return ptr_ != end_ ? *ptr_ : Char(); }
|
||||||
return ptr_ != end_ ? *ptr_ : Char();
|
|
||||||
}
|
|
||||||
|
|
||||||
FMT_CONSTEXPR null_terminating_iterator operator++() {
|
FMT_CONSTEXPR null_terminating_iterator operator++() {
|
||||||
++ptr_;
|
++ptr_;
|
||||||
@ -76,8 +74,8 @@ class null_terminating_iterator {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR difference_type operator-(
|
FMT_CONSTEXPR difference_type
|
||||||
null_terminating_iterator other) const {
|
operator-(null_terminating_iterator other) const {
|
||||||
return ptr_ - other.ptr_;
|
return ptr_ - other.ptr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +99,9 @@ class null_terminating_iterator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
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>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR const Char *pointer_from(null_terminating_iterator<Char> it) {
|
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; }
|
static bool fits_in_int(int) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class printf_precision_handler: public function<int> {
|
class printf_precision_handler : public function<int> {
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_integral<T>::value, int>::type
|
typename std::enable_if<std::is_integral<T>::value, int>::type operator()(
|
||||||
operator()(T value) {
|
T value) {
|
||||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||||
FMT_THROW(format_error("number is too big"));
|
FMT_THROW(format_error("number is too big"));
|
||||||
return static_cast<int>(value);
|
return static_cast<int>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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"));
|
FMT_THROW(format_error("precision is not integer"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// An argument visitor that returns true iff arg is a zero integer.
|
// 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:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_integral<T>::value, bool>::type
|
typename std::enable_if<std::is_integral<T>::value, bool>::type operator()(
|
||||||
operator()(T value) { return value == 0; }
|
T value) {
|
||||||
|
return value == 0;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<!std::is_integral<T>::value, bool>::type
|
typename std::enable_if<!std::is_integral<T>::value, bool>::type operator()(
|
||||||
operator()(T) { return false; }
|
T) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -200,7 +205,7 @@ struct make_unsigned_or_bool<bool> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Context>
|
template <typename T, typename Context>
|
||||||
class arg_converter: public function<void> {
|
class arg_converter : public function<void> {
|
||||||
private:
|
private:
|
||||||
typedef typename Context::char_type Char;
|
typedef typename Context::char_type Char;
|
||||||
|
|
||||||
@ -217,11 +222,11 @@ class arg_converter: public function<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
typename std::enable_if<std::is_integral<U>::value>::type
|
typename std::enable_if<std::is_integral<U>::value>::type operator()(
|
||||||
operator()(U value) {
|
U value) {
|
||||||
bool is_signed = type_ == 'd' || type_ == 'i';
|
bool is_signed = type_ == 'd' || type_ == 'i';
|
||||||
typedef typename std::conditional<
|
typedef typename std::conditional<std::is_same<T, void>::value, U, T>::type
|
||||||
std::is_same<T, void>::value, U, T>::type TargetType;
|
TargetType;
|
||||||
if (const_check(sizeof(TargetType) <= sizeof(int))) {
|
if (const_check(sizeof(TargetType) <= sizeof(int))) {
|
||||||
// Extra casts are used to silence warnings.
|
// Extra casts are used to silence warnings.
|
||||||
if (is_signed) {
|
if (is_signed) {
|
||||||
@ -262,7 +267,7 @@ void convert_arg(basic_format_arg<Context> &arg, Char type) {
|
|||||||
|
|
||||||
// Converts an integer argument to char for printf.
|
// Converts an integer argument to char for printf.
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
class char_converter: public function<void> {
|
class char_converter : public function<void> {
|
||||||
private:
|
private:
|
||||||
basic_format_arg<Context> &arg_;
|
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) {}
|
explicit char_converter(basic_format_arg<Context> &arg) : arg_(arg) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_integral<T>::value>::type
|
typename std::enable_if<std::is_integral<T>::value>::type operator()(
|
||||||
operator()(T value) {
|
T value) {
|
||||||
typedef typename Context::char_type Char;
|
typedef typename Context::char_type Char;
|
||||||
arg_ = internal::make_arg<Context>(static_cast<Char>(value));
|
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
|
// Checks if an argument is a valid printf width specifier and sets
|
||||||
// left alignment if it is negative.
|
// left alignment if it is negative.
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class printf_width_handler: public function<unsigned> {
|
class printf_width_handler : public function<unsigned> {
|
||||||
private:
|
private:
|
||||||
typedef basic_format_specs<Char> format_specs;
|
typedef basic_format_specs<Char> format_specs;
|
||||||
|
|
||||||
@ -318,7 +323,9 @@ class printf_width_handler: public function<unsigned> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char, typename Context>
|
template <typename Char, typename Context>
|
||||||
void printf(basic_buffer<Char> &buf, basic_string_view<Char> format,
|
void printf(
|
||||||
|
basic_buffer<Char> &buf,
|
||||||
|
basic_string_view<Char> format,
|
||||||
basic_format_args<Context> args) {
|
basic_format_args<Context> args) {
|
||||||
Context(std::back_inserter(buf), format, args).format();
|
Context(std::back_inserter(buf), format, args).format();
|
||||||
}
|
}
|
||||||
@ -330,7 +337,8 @@ template <typename Range>
|
|||||||
class printf_arg_formatter;
|
class printf_arg_formatter;
|
||||||
|
|
||||||
template <
|
template <
|
||||||
typename OutputIt, typename Char,
|
typename OutputIt,
|
||||||
|
typename Char,
|
||||||
typename ArgFormatter =
|
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;
|
class basic_printf_context;
|
||||||
@ -341,8 +349,8 @@ class basic_printf_context;
|
|||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename Range>
|
template <typename Range>
|
||||||
class printf_arg_formatter:
|
class printf_arg_formatter
|
||||||
public internal::function<
|
: public internal::function<
|
||||||
typename internal::arg_formatter_base<Range>::iterator>,
|
typename internal::arg_formatter_base<Range>::iterator>,
|
||||||
public internal::arg_formatter_base<Range> {
|
public internal::arg_formatter_base<Range> {
|
||||||
private:
|
private:
|
||||||
@ -373,9 +381,13 @@ class printf_arg_formatter:
|
|||||||
specifier information for standard argument types.
|
specifier information for standard argument types.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
printf_arg_formatter(internal::basic_buffer<char_type> &buffer,
|
printf_arg_formatter(
|
||||||
format_specs &spec, context_type &ctx)
|
internal::basic_buffer<char_type> &buffer,
|
||||||
: base(back_insert_range<internal::basic_buffer<char_type>>(buffer), &spec,
|
format_specs &spec,
|
||||||
|
context_type &ctx)
|
||||||
|
: base(
|
||||||
|
back_insert_range<internal::basic_buffer<char_type>>(buffer),
|
||||||
|
&spec,
|
||||||
ctx.locale()),
|
ctx.locale()),
|
||||||
context_(ctx) {}
|
context_(ctx) {}
|
||||||
|
|
||||||
@ -435,9 +447,7 @@ class printf_arg_formatter:
|
|||||||
return base::operator()(value);
|
return base::operator()(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator operator()(monostate value) {
|
iterator operator()(monostate value) { return base::operator()(value); }
|
||||||
return base::operator()(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Formats a pointer. */
|
/** Formats a pointer. */
|
||||||
iterator operator()(const void *value) {
|
iterator operator()(const void *value) {
|
||||||
@ -458,7 +468,9 @@ class printf_arg_formatter:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct printf_formatter {
|
struct printf_formatter {
|
||||||
template <typename ParseContext>
|
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>
|
template <typename FormatContext>
|
||||||
auto format(const T &value, FormatContext &ctx) -> decltype(ctx.out()) {
|
auto format(const T &value, FormatContext &ctx) -> decltype(ctx.out()) {
|
||||||
@ -473,13 +485,17 @@ class basic_printf_context :
|
|||||||
// Inherit publicly as a workaround for the icc bug
|
// Inherit publicly as a workaround for the icc bug
|
||||||
// https://software.intel.com/en-us/forums/intel-c-compiler/topic/783476.
|
// https://software.intel.com/en-us/forums/intel-c-compiler/topic/783476.
|
||||||
public internal::context_base<
|
public internal::context_base<
|
||||||
OutputIt, basic_printf_context<OutputIt, Char, ArgFormatter>, Char> {
|
OutputIt,
|
||||||
|
basic_printf_context<OutputIt, Char, ArgFormatter>,
|
||||||
|
Char> {
|
||||||
public:
|
public:
|
||||||
/** The character type for the output. */
|
/** The character type for the output. */
|
||||||
typedef Char char_type;
|
typedef Char char_type;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct formatter_type { typedef printf_formatter<T> type; };
|
struct formatter_type {
|
||||||
|
typedef printf_formatter<T> type;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef internal::context_base<OutputIt, basic_printf_context, Char> base;
|
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
|
// Returns the argument with specified index or, if arg_index is equal
|
||||||
// to the maximum unsigned value, the next argument.
|
// to the maximum unsigned value, the next argument.
|
||||||
format_arg get_arg(
|
format_arg get_arg(
|
||||||
iterator it,
|
iterator it, unsigned arg_index = (std::numeric_limits<unsigned>::max)());
|
||||||
unsigned arg_index = (std::numeric_limits<unsigned>::max)());
|
|
||||||
|
|
||||||
// Parses argument index, flags and width and returns the argument index.
|
// Parses argument index, flags and width and returns the argument index.
|
||||||
unsigned parse_header(iterator &it, format_specs &spec);
|
unsigned parse_header(iterator &it, format_specs &spec);
|
||||||
@ -506,13 +521,15 @@ class basic_printf_context :
|
|||||||
appropriate lifetimes.
|
appropriate lifetimes.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
|
basic_printf_context(
|
||||||
|
OutputIt out,
|
||||||
|
basic_string_view<char_type> format_str,
|
||||||
basic_format_args<basic_printf_context> args)
|
basic_format_args<basic_printf_context> args)
|
||||||
: base(out, format_str, args) {}
|
: base(out, format_str, args) {}
|
||||||
|
|
||||||
using base::parse_context;
|
|
||||||
using base::out;
|
|
||||||
using base::advance_to;
|
using base::advance_to;
|
||||||
|
using base::out;
|
||||||
|
using base::parse_context;
|
||||||
|
|
||||||
/** Formats stored arguments and writes the output to the range. */
|
/** Formats stored arguments and writes the output to the range. */
|
||||||
void format();
|
void format();
|
||||||
@ -547,7 +564,7 @@ void basic_printf_context<OutputIt, Char, AF>::parse_flags(
|
|||||||
|
|
||||||
template <typename OutputIt, typename Char, typename AF>
|
template <typename OutputIt, typename Char, typename AF>
|
||||||
typename basic_printf_context<OutputIt, Char, AF>::format_arg
|
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) {
|
iterator it, unsigned arg_index) {
|
||||||
(void)it;
|
(void)it;
|
||||||
if (arg_index == std::numeric_limits<unsigned>::max())
|
if (arg_index == std::numeric_limits<unsigned>::max())
|
||||||
@ -600,7 +617,8 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
|
|||||||
using internal::pointer_from;
|
using internal::pointer_from;
|
||||||
while (*it) {
|
while (*it) {
|
||||||
char_type c = *it++;
|
char_type c = *it++;
|
||||||
if (c != '%') continue;
|
if (c != '%')
|
||||||
|
continue;
|
||||||
if (*it == c) {
|
if (*it == c) {
|
||||||
buffer.append(pointer_from(start), pointer_from(it));
|
buffer.append(pointer_from(start), pointer_from(it));
|
||||||
start = ++it;
|
start = ++it;
|
||||||
@ -679,7 +697,8 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
|
|||||||
if (arg.is_integral()) {
|
if (arg.is_integral()) {
|
||||||
// Normalize type.
|
// Normalize type.
|
||||||
switch (spec.type) {
|
switch (spec.type) {
|
||||||
case 'i': case 'u':
|
case 'i':
|
||||||
|
case 'u':
|
||||||
spec.type = 'd';
|
spec.type = 'd';
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
@ -701,7 +720,9 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
|
|||||||
template <typename Buffer>
|
template <typename Buffer>
|
||||||
struct basic_printf_context_t {
|
struct basic_printf_context_t {
|
||||||
typedef basic_printf_context<
|
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;
|
typedef basic_printf_context_t<internal::buffer>::type printf_context;
|
||||||
@ -716,9 +737,11 @@ typedef basic_format_args<wprintf_context> wprintf_args;
|
|||||||
arguments and can be implicitly converted to `~fmt::printf_args`.
|
arguments and can be implicitly converted to `~fmt::printf_args`.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template<typename... Args>
|
template <typename... Args>
|
||||||
inline format_arg_store<printf_context, Args...>
|
inline format_arg_store<printf_context, Args...> make_printf_args(
|
||||||
make_printf_args(const Args &... args) { return {args...}; }
|
const Args &... args) {
|
||||||
|
return {args...};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
@ -726,15 +749,18 @@ inline format_arg_store<printf_context, Args...>
|
|||||||
arguments and can be implicitly converted to `~fmt::wprintf_args`.
|
arguments and can be implicitly converted to `~fmt::wprintf_args`.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template<typename... Args>
|
template <typename... Args>
|
||||||
inline format_arg_store<wprintf_context, Args...>
|
inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
|
||||||
make_wprintf_args(const Args &... args) { return {args...}; }
|
const Args &... args) {
|
||||||
|
return {args...};
|
||||||
|
}
|
||||||
|
|
||||||
template <typename S, typename Char = FMT_CHAR(S)>
|
template <typename S, typename Char = FMT_CHAR(S)>
|
||||||
inline std::basic_string<Char>
|
inline std::basic_string<Char> vsprintf(
|
||||||
vsprintf(const S &format,
|
const S &format,
|
||||||
basic_format_args<typename basic_printf_context_t<
|
basic_format_args<
|
||||||
internal::basic_buffer<Char>>::type> args) {
|
typename basic_printf_context_t<internal::basic_buffer<Char>>::type>
|
||||||
|
args) {
|
||||||
basic_memory_buffer<Char> buffer;
|
basic_memory_buffer<Char> buffer;
|
||||||
printf(buffer, to_string_view(format), args);
|
printf(buffer, to_string_view(format), args);
|
||||||
return to_string(buffer);
|
return to_string(buffer);
|
||||||
@ -752,24 +778,27 @@ vsprintf(const S &format,
|
|||||||
template <typename S, typename... Args>
|
template <typename S, typename... Args>
|
||||||
inline FMT_ENABLE_IF_T(
|
inline FMT_ENABLE_IF_T(
|
||||||
internal::is_string<S>::value, std::basic_string<FMT_CHAR(S)>)
|
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);
|
internal::check_format_string<Args...>(format);
|
||||||
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
|
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
|
||||||
typedef typename basic_printf_context_t<buffer>::type context;
|
typedef typename basic_printf_context_t<buffer>::type context;
|
||||||
format_arg_store<context, Args...> as{ args... };
|
format_arg_store<context, Args...> as{args...};
|
||||||
return vsprintf(to_string_view(format),
|
return vsprintf(to_string_view(format), basic_format_args<context>(as));
|
||||||
basic_format_args<context>(as));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename S, typename Char = FMT_CHAR(S)>
|
template <typename S, typename Char = FMT_CHAR(S)>
|
||||||
inline int vfprintf(std::FILE *f, const S &format,
|
inline int vfprintf(
|
||||||
basic_format_args<typename basic_printf_context_t<
|
std::FILE *f,
|
||||||
internal::basic_buffer<Char>>::type> args) {
|
const S &format,
|
||||||
|
basic_format_args<
|
||||||
|
typename basic_printf_context_t<internal::basic_buffer<Char>>::type>
|
||||||
|
args) {
|
||||||
basic_memory_buffer<Char> buffer;
|
basic_memory_buffer<Char> buffer;
|
||||||
printf(buffer, to_string_view(format), args);
|
printf(buffer, to_string_view(format), args);
|
||||||
std::size_t size = buffer.size();
|
std::size_t size = buffer.size();
|
||||||
return std::fwrite(
|
return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
|
||||||
buffer.data(), sizeof(Char), size, f) < size ? -1 : static_cast<int>(size);
|
? -1
|
||||||
|
: static_cast<int>(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -783,19 +812,20 @@ inline int vfprintf(std::FILE *f, const S &format,
|
|||||||
*/
|
*/
|
||||||
template <typename S, typename... Args>
|
template <typename S, typename... Args>
|
||||||
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, int)
|
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);
|
internal::check_format_string<Args...>(format);
|
||||||
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
|
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
|
||||||
typedef typename basic_printf_context_t<buffer>::type context;
|
typedef typename basic_printf_context_t<buffer>::type context;
|
||||||
format_arg_store<context, Args...> as{ args... };
|
format_arg_store<context, Args...> as{args...};
|
||||||
return vfprintf(f, to_string_view(format),
|
return vfprintf(f, to_string_view(format), basic_format_args<context>(as));
|
||||||
basic_format_args<context>(as));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename S, typename Char = FMT_CHAR(S)>
|
template <typename S, typename Char = FMT_CHAR(S)>
|
||||||
inline int vprintf(const S &format,
|
inline int vprintf(
|
||||||
basic_format_args<typename basic_printf_context_t<
|
const S &format,
|
||||||
internal::basic_buffer<Char>>::type> args) {
|
basic_format_args<
|
||||||
|
typename basic_printf_context_t<internal::basic_buffer<Char>>::type>
|
||||||
|
args) {
|
||||||
return vfprintf(stdout, to_string_view(format), args);
|
return vfprintf(stdout, to_string_view(format), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,20 +840,21 @@ inline int vprintf(const S &format,
|
|||||||
*/
|
*/
|
||||||
template <typename S, typename... Args>
|
template <typename S, typename... Args>
|
||||||
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, int)
|
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);
|
internal::check_format_string<Args...>(format_str);
|
||||||
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
|
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
|
||||||
typedef typename basic_printf_context_t<buffer>::type context;
|
typedef typename basic_printf_context_t<buffer>::type context;
|
||||||
format_arg_store<context, Args...> as{ args... };
|
format_arg_store<context, Args...> as{args...};
|
||||||
return vprintf(to_string_view(format_str),
|
return vprintf(to_string_view(format_str), basic_format_args<context>(as));
|
||||||
basic_format_args<context>(as));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename S, typename Char = FMT_CHAR(S)>
|
template <typename S, typename Char = FMT_CHAR(S)>
|
||||||
inline int vfprintf(std::basic_ostream<Char> &os,
|
inline int vfprintf(
|
||||||
|
std::basic_ostream<Char> &os,
|
||||||
const S &format,
|
const S &format,
|
||||||
basic_format_args<typename basic_printf_context_t<
|
basic_format_args<
|
||||||
internal::basic_buffer<Char>>::type> args) {
|
typename basic_printf_context_t<internal::basic_buffer<Char>>::type>
|
||||||
|
args) {
|
||||||
basic_memory_buffer<Char> buffer;
|
basic_memory_buffer<Char> buffer;
|
||||||
printf(buffer, to_string_view(format), args);
|
printf(buffer, to_string_view(format), args);
|
||||||
internal::write(os, buffer);
|
internal::write(os, buffer);
|
||||||
@ -840,15 +871,16 @@ inline int vfprintf(std::basic_ostream<Char> &os,
|
|||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename S, typename... Args>
|
template <typename S, typename... Args>
|
||||||
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, int)
|
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, int) fprintf(
|
||||||
fprintf(std::basic_ostream<FMT_CHAR(S)> &os,
|
std::basic_ostream<FMT_CHAR(S)> &os,
|
||||||
const S &format_str, const Args & ... args) {
|
const S &format_str,
|
||||||
|
const Args &... args) {
|
||||||
internal::check_format_string<Args...>(format_str);
|
internal::check_format_string<Args...>(format_str);
|
||||||
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
|
typedef internal::basic_buffer<FMT_CHAR(S)> buffer;
|
||||||
typedef typename basic_printf_context_t<buffer>::type context;
|
typedef typename basic_printf_context_t<buffer>::type context;
|
||||||
format_arg_store<context, Args...> as{ args... };
|
format_arg_store<context, Args...> as{args...};
|
||||||
return vfprintf(os, to_string_view(format_str),
|
return vfprintf(
|
||||||
basic_format_args<context>(as));
|
os, to_string_view(format_str), basic_format_args<context>(as));
|
||||||
}
|
}
|
||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
|
|||||||
@ -13,11 +13,12 @@
|
|||||||
#define FMT_RANGES_H_
|
#define FMT_RANGES_H_
|
||||||
|
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
// output only up to N items from the range.
|
// output only up to N items from the range.
|
||||||
#ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT
|
#ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT
|
||||||
# define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
|
#define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
@ -33,7 +34,8 @@ struct formatting_base {
|
|||||||
template <typename Char, typename Enable = void>
|
template <typename Char, typename Enable = void>
|
||||||
struct formatting_range : formatting_base<Char> {
|
struct formatting_range : formatting_base<Char> {
|
||||||
static FMT_CONSTEXPR_DECL const std::size_t range_length_limit =
|
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 prefix;
|
||||||
Char delimiter;
|
Char delimiter;
|
||||||
Char postfix;
|
Char postfix;
|
||||||
@ -77,8 +79,8 @@ void copy(char ch, OutputIterator out) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class is_like_std_string {
|
class is_like_std_string {
|
||||||
template <typename U>
|
template <typename U>
|
||||||
static auto check(U *p) ->
|
static auto check(U *p)
|
||||||
decltype(p->find('a'), p->length(), p->data(), int());
|
-> decltype(p->find('a'), p->length(), p->data(), int());
|
||||||
template <typename>
|
template <typename>
|
||||||
static void check(...);
|
static void check(...);
|
||||||
|
|
||||||
@ -98,9 +100,12 @@ struct is_range_ : std::false_type {};
|
|||||||
|
|
||||||
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
|
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_range_<T, typename std::conditional<
|
struct is_range_<
|
||||||
|
T,
|
||||||
|
typename std::conditional<
|
||||||
false,
|
false,
|
||||||
conditional_helper<decltype(internal::declval<T>().begin()),
|
conditional_helper<
|
||||||
|
decltype(internal::declval<T>().begin()),
|
||||||
decltype(internal::declval<T>().end())>,
|
decltype(internal::declval<T>().end())>,
|
||||||
void>::type> : std::true_type {};
|
void>::type> : std::true_type {};
|
||||||
#endif
|
#endif
|
||||||
@ -109,9 +114,10 @@ struct is_range_<T, typename std::conditional<
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class is_tuple_like_ {
|
class is_tuple_like_ {
|
||||||
template <typename U>
|
template <typename U>
|
||||||
static auto check(U *p) ->
|
static auto check(U *p) -> decltype(
|
||||||
decltype(std::tuple_size<U>::value,
|
std::tuple_size<U>::value,
|
||||||
internal::declval<typename std::tuple_element<0, U>::type>(), int());
|
internal::declval<typename std::tuple_element<0, U>::type>(),
|
||||||
|
int());
|
||||||
template <typename>
|
template <typename>
|
||||||
static void check(...);
|
static void check(...);
|
||||||
|
|
||||||
@ -133,9 +139,7 @@ template <typename T, T... N>
|
|||||||
struct integer_sequence {
|
struct integer_sequence {
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
|
|
||||||
static FMT_CONSTEXPR std::size_t size() {
|
static FMT_CONSTEXPR std::size_t size() { return sizeof...(N); }
|
||||||
return sizeof...(N);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <std::size_t... 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>
|
template <class T>
|
||||||
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value>
|
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value> get_indexes(
|
||||||
get_indexes(T const &) { return {}; }
|
T const &) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
template <class Tuple, class F>
|
template <class Tuple, class F>
|
||||||
void for_each(Tuple &&tup, F &&f) {
|
void for_each(Tuple &&tup, F &&f) {
|
||||||
@ -168,31 +174,38 @@ void for_each(Tuple &&tup, F &&f) {
|
|||||||
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
|
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Arg>
|
template <typename Arg>
|
||||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&,
|
FMT_CONSTEXPR const char *format_str_quoted(
|
||||||
|
bool add_space,
|
||||||
|
const Arg &,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
!is_like_std_string<typename std::decay<Arg>::type>::value>::type* = nullptr) {
|
!is_like_std_string<typename std::decay<Arg>::type>::value>::type * =
|
||||||
|
nullptr) {
|
||||||
return add_space ? " {}" : "{}";
|
return add_space ? " {}" : "{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Arg>
|
template <typename Arg>
|
||||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&,
|
FMT_CONSTEXPR const char *format_str_quoted(
|
||||||
|
bool add_space,
|
||||||
|
const Arg &,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
is_like_std_string<typename std::decay<Arg>::type>::value>::type* = nullptr) {
|
is_like_std_string<typename std::decay<Arg>::type>::value>::type * =
|
||||||
|
nullptr) {
|
||||||
return add_space ? " \"{}\"" : "\"{}\"";
|
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 ? " \"{}\"" : "\"{}\"";
|
return add_space ? " \"{}\"" : "\"{}\"";
|
||||||
}
|
}
|
||||||
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t*) {
|
FMT_CONSTEXPR const wchar_t *format_str_quoted(
|
||||||
|
bool add_space, const wchar_t *) {
|
||||||
return add_space ? L" \"{}\"" : L"\"{}\"";
|
return add_space ? L" \"{}\"" : L"\"{}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ? " '{}'" : "'{}'";
|
return add_space ? " '{}'" : "'{}'";
|
||||||
}
|
}
|
||||||
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) {
|
FMT_CONSTEXPR const wchar_t *format_str_quoted(bool add_space, const wchar_t) {
|
||||||
return add_space ? L" '{}'" : L"'{}'";
|
return add_space ? L" '{}'" : L"'{}'";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,33 +218,37 @@ struct is_tuple_like {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename TupleT, typename Char>
|
template <typename TupleT, typename Char>
|
||||||
struct formatter<TupleT, Char,
|
struct formatter<
|
||||||
|
TupleT,
|
||||||
|
Char,
|
||||||
typename std::enable_if<fmt::is_tuple_like<TupleT>::value>::type> {
|
typename std::enable_if<fmt::is_tuple_like<TupleT>::value>::type> {
|
||||||
private:
|
private:
|
||||||
// C++11 generic lambda for format()
|
// C++11 generic lambda for format()
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
struct format_each {
|
struct format_each {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(const T& v) {
|
void operator()(const T &v) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (formatting.add_prepostfix_space) {
|
if (formatting.add_prepostfix_space) {
|
||||||
*out++ = ' ';
|
*out++ = ' ';
|
||||||
}
|
}
|
||||||
internal::copy(formatting.delimiter, out);
|
internal::copy(formatting.delimiter, out);
|
||||||
}
|
}
|
||||||
format_to(out,
|
format_to(
|
||||||
|
out,
|
||||||
internal::format_str_quoted(
|
internal::format_str_quoted(
|
||||||
(formatting.add_delimiter_spaces && i > 0), v),
|
(formatting.add_delimiter_spaces && i > 0), v),
|
||||||
v);
|
v);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
formatting_tuple<Char>& formatting;
|
formatting_tuple<Char> &formatting;
|
||||||
std::size_t& i;
|
std::size_t &i;
|
||||||
typename std::add_lvalue_reference<decltype(std::declval<FormatContext>().out())>::type out;
|
typename std::add_lvalue_reference<decltype(
|
||||||
|
std::declval<FormatContext>().out())>::type out;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
formatting_tuple<Char> formatting;
|
formatting_tuple<Char> formatting;
|
||||||
|
|
||||||
template <typename ParseContext>
|
template <typename ParseContext>
|
||||||
@ -262,9 +279,10 @@ struct is_range {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename RangeT, typename Char>
|
template <typename RangeT, typename Char>
|
||||||
struct formatter<RangeT, Char,
|
struct formatter<
|
||||||
|
RangeT,
|
||||||
|
Char,
|
||||||
typename std::enable_if<fmt::is_range<RangeT>::value>::type> {
|
typename std::enable_if<fmt::is_range<RangeT>::value>::type> {
|
||||||
|
|
||||||
formatting_range<Char> formatting;
|
formatting_range<Char> formatting;
|
||||||
|
|
||||||
template <typename ParseContext>
|
template <typename ParseContext>
|
||||||
@ -285,7 +303,8 @@ struct formatter<RangeT, Char,
|
|||||||
}
|
}
|
||||||
internal::copy(formatting.delimiter, out);
|
internal::copy(formatting.delimiter, out);
|
||||||
}
|
}
|
||||||
format_to(out,
|
format_to(
|
||||||
|
out,
|
||||||
internal::format_str_quoted(
|
internal::format_str_quoted(
|
||||||
(formatting.add_delimiter_spaces && i > 0), *it),
|
(formatting.add_delimiter_spaces && i > 0), *it),
|
||||||
*it);
|
*it);
|
||||||
@ -305,4 +324,3 @@ struct formatter<RangeT, Char,
|
|||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // FMT_RANGES_H_
|
#endif // FMT_RANGES_H_
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#define FMT_TIME_H_
|
#define FMT_TIME_H_
|
||||||
|
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ FMT_BEGIN_NAMESPACE
|
|||||||
// Usage: f FMT_NOMACRO()
|
// Usage: f FMT_NOMACRO()
|
||||||
#define FMT_NOMACRO
|
#define FMT_NOMACRO
|
||||||
|
|
||||||
namespace internal{
|
namespace internal {
|
||||||
inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
|
inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
|
||||||
inline null<> localtime_s(...) { return null<>(); }
|
inline null<> localtime_s(...) { return null<>(); }
|
||||||
inline null<> gmtime_r(...) { 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::time_t time_;
|
||||||
std::tm tm_;
|
std::tm tm_;
|
||||||
|
|
||||||
dispatcher(std::time_t t): time_(t) {}
|
dispatcher(std::time_t t) : time_(t) {}
|
||||||
|
|
||||||
bool run() {
|
bool run() {
|
||||||
using namespace fmt::internal;
|
using namespace fmt::internal;
|
||||||
@ -51,7 +52,8 @@ inline std::tm localtime(std::time_t time) {
|
|||||||
bool fallback(internal::null<>) {
|
bool fallback(internal::null<>) {
|
||||||
using namespace fmt::internal;
|
using namespace fmt::internal;
|
||||||
std::tm *tm = std::localtime(&time_);
|
std::tm *tm = std::localtime(&time_);
|
||||||
if (tm) tm_ = *tm;
|
if (tm)
|
||||||
|
tm_ = *tm;
|
||||||
return tm != FMT_NULL;
|
return tm != FMT_NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -69,7 +71,7 @@ inline std::tm gmtime(std::time_t time) {
|
|||||||
std::time_t time_;
|
std::time_t time_;
|
||||||
std::tm tm_;
|
std::tm tm_;
|
||||||
|
|
||||||
dispatcher(std::time_t t): time_(t) {}
|
dispatcher(std::time_t t) : time_(t) {}
|
||||||
|
|
||||||
bool run() {
|
bool run() {
|
||||||
using namespace fmt::internal;
|
using namespace fmt::internal;
|
||||||
@ -88,7 +90,8 @@ inline std::tm gmtime(std::time_t time) {
|
|||||||
#if !FMT_MSC_VER
|
#if !FMT_MSC_VER
|
||||||
bool fallback(internal::null<>) {
|
bool fallback(internal::null<>) {
|
||||||
std::tm *tm = std::gmtime(&time_);
|
std::tm *tm = std::gmtime(&time_);
|
||||||
if (tm) tm_ = *tm;
|
if (tm)
|
||||||
|
tm_ = *tm;
|
||||||
return tm != FMT_NULL;
|
return tm != FMT_NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -101,16 +104,19 @@ inline std::tm gmtime(std::time_t time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
inline std::size_t strftime(char *str, std::size_t count, const char *format,
|
inline std::size_t strftime(
|
||||||
const std::tm *time) {
|
char *str, std::size_t count, const char *format, const std::tm *time) {
|
||||||
return std::strftime(str, count, format, time);
|
return std::strftime(str, count, format, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t strftime(wchar_t *str, std::size_t count,
|
inline std::size_t strftime(
|
||||||
const wchar_t *format, const std::tm *time) {
|
wchar_t *str,
|
||||||
|
std::size_t count,
|
||||||
|
const wchar_t *format,
|
||||||
|
const std::tm *time) {
|
||||||
return std::wcsftime(str, count, format, time);
|
return std::wcsftime(str, count, format, time);
|
||||||
}
|
}
|
||||||
}
|
} // namespace internal
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
struct formatter<std::tm, Char> {
|
struct formatter<std::tm, Char> {
|
||||||
@ -120,8 +126,7 @@ struct formatter<std::tm, Char> {
|
|||||||
if (it != ctx.end() && *it == ':')
|
if (it != ctx.end() && *it == ':')
|
||||||
++it;
|
++it;
|
||||||
auto end = it;
|
auto end = it;
|
||||||
while (end != ctx.end() && *end != '}')
|
while (end != ctx.end() && *end != '}') ++end;
|
||||||
++end;
|
|
||||||
tm_format.reserve(end - it + 1);
|
tm_format.reserve(end - it + 1);
|
||||||
tm_format.append(it, end);
|
tm_format.append(it, end);
|
||||||
tm_format.push_back('\0');
|
tm_format.push_back('\0');
|
||||||
|
|||||||
@ -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 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(
|
template FMT_API void internal::arg_map<format_context>::init(
|
||||||
const basic_format_args<format_context> &args);
|
const basic_format_args<format_context> &args);
|
||||||
|
|||||||
58
src/posix.cc
58
src/posix.cc
@ -7,43 +7,43 @@
|
|||||||
|
|
||||||
// Disable bogus MSVC warnings.
|
// Disable bogus MSVC warnings.
|
||||||
#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)
|
#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)
|
||||||
# define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "fmt/posix.h"
|
#include "fmt/posix.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <unistd.h>
|
#include <unistd.h>
|
||||||
#else
|
#else
|
||||||
# ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
# define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
# endif
|
#endif
|
||||||
# include <windows.h>
|
#include <io.h>
|
||||||
# include <io.h>
|
#include <windows.h>
|
||||||
|
|
||||||
# define O_CREAT _O_CREAT
|
#define O_CREAT _O_CREAT
|
||||||
# define O_TRUNC _O_TRUNC
|
#define O_TRUNC _O_TRUNC
|
||||||
|
|
||||||
# ifndef S_IRUSR
|
#ifndef S_IRUSR
|
||||||
# define S_IRUSR _S_IREAD
|
#define S_IRUSR _S_IREAD
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
# ifndef S_IWUSR
|
#ifndef S_IWUSR
|
||||||
# define S_IWUSR _S_IWRITE
|
#define S_IWUSR _S_IWRITE
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
# ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
# define _SH_DENYNO 0x40
|
#define _SH_DENYNO 0x40
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
#ifdef fileno
|
#ifdef fileno
|
||||||
# undef fileno
|
#undef fileno
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -62,7 +62,7 @@ typedef ssize_t RWResult;
|
|||||||
|
|
||||||
inline std::size_t convert_rwcount(std::size_t count) { return count; }
|
inline std::size_t convert_rwcount(std::size_t count) { return count; }
|
||||||
#endif
|
#endif
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -72,8 +72,8 @@ buffered_file::~buffered_file() FMT_NOEXCEPT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
|
buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
|
||||||
FMT_RETRY_VAL(file_,
|
FMT_RETRY_VAL(
|
||||||
FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), FMT_NULL);
|
file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), FMT_NULL);
|
||||||
if (!file_)
|
if (!file_)
|
||||||
FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str()));
|
FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str()));
|
||||||
}
|
}
|
||||||
@ -147,7 +147,8 @@ long long file::size() const {
|
|||||||
Stat file_stat = Stat();
|
Stat file_stat = Stat();
|
||||||
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
|
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
|
||||||
FMT_THROW(system_error(errno, "cannot get file attributes"));
|
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 type of file::size is not large enough");
|
||||||
return file_stat.st_size;
|
return file_stat.st_size;
|
||||||
#endif
|
#endif
|
||||||
@ -182,8 +183,8 @@ void file::dup2(int fd) {
|
|||||||
int result = 0;
|
int result = 0;
|
||||||
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
|
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
FMT_THROW(system_error(errno,
|
FMT_THROW(system_error(
|
||||||
"cannot duplicate file descriptor {} to {}", fd_, fd));
|
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.
|
// Don't retry as fdopen doesn't return EINTR.
|
||||||
FILE *f = FMT_POSIX_CALL(fdopen(fd_, mode));
|
FILE *f = FMT_POSIX_CALL(fdopen(fd_, mode));
|
||||||
if (!f)
|
if (!f)
|
||||||
FMT_THROW(system_error(errno,
|
FMT_THROW(
|
||||||
"cannot associate stream with file descriptor"));
|
system_error(errno, "cannot associate stream with file descriptor"));
|
||||||
buffered_file bf(f);
|
buffered_file bf(f);
|
||||||
fd_ = -1;
|
fd_ = -1;
|
||||||
return bf;
|
return bf;
|
||||||
@ -241,4 +242,3 @@ long getpagesize() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user