Skip to content

Commit

Permalink
update fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
actboy168 committed Aug 30, 2023
1 parent a73df87 commit 6bddb34
Show file tree
Hide file tree
Showing 14 changed files with 834 additions and 1,139 deletions.
2 changes: 1 addition & 1 deletion 3rd/fmt/fmt/args.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Formatting library for C++ - dynamic format arguments
// Formatting library for C++ - dynamic argument lists
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
Expand Down
205 changes: 73 additions & 132 deletions 3rd/fmt/fmt/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ inline std::tm gmtime(std::time_t time) {
}
#endif
};
dispatcher gt(time);
auto gt = dispatcher(time);
// Too big time values may be unsupported.
if (!gt.run()) FMT_THROW(format_error("time_t value out of range"));
return gt.tm_;
Expand All @@ -530,50 +530,7 @@ inline std::tm gmtime(
return gmtime(std::chrono::system_clock::to_time_t(time_point));
}

FMT_BEGIN_DETAIL_NAMESPACE

// DEPRECATED!
template <typename Char>
FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
format_specs<Char>& specs) -> const Char* {
FMT_ASSERT(begin != end, "");
auto align = align::none;
auto p = begin + code_point_length(begin);
if (end - p <= 0) p = begin;
for (;;) {
switch (to_ascii(*p)) {
case '<':
align = align::left;
break;
case '>':
align = align::right;
break;
case '^':
align = align::center;
break;
}
if (align != align::none) {
if (p != begin) {
auto c = *begin;
if (c == '}') return begin;
if (c == '{') {
throw_format_error("invalid fill character '{'");
return begin;
}
specs.fill = {begin, to_unsigned(p - begin)};
begin = p + 1;
} else {
++begin;
}
break;
} else if (p == begin) {
break;
}
p = begin;
}
specs.align = align;
return begin;
}
namespace detail {

// Writes two-digit numbers a, b and c separated by sep to buf.
// The method by Pavel Novikov based on
Expand Down Expand Up @@ -1997,7 +1954,7 @@ struct chrono_formatter {
}
};

FMT_END_DETAIL_NAMESPACE
} // namespace detail

#if defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907
using weekday = std::chrono::weekday;
Expand Down Expand Up @@ -2047,102 +2004,91 @@ template <typename Char> struct formatter<weekday, Char> {
template <typename Rep, typename Period, typename Char>
struct formatter<std::chrono::duration<Rep, Period>, Char> {
private:
format_specs<Char> specs;
int precision = -1;
using arg_ref_type = detail::arg_ref<Char>;
arg_ref_type width_ref;
arg_ref_type precision_ref;
bool localized = false;
basic_string_view<Char> format_str;
using duration = std::chrono::duration<Rep, Period>;
format_specs<Char> specs_;
detail::arg_ref<Char> width_ref_;
detail::arg_ref<Char> precision_ref_;
bool localized_ = false;
basic_string_view<Char> format_str_;

using iterator = typename basic_format_parse_context<Char>::iterator;
struct parse_range {
iterator begin;
iterator end;
};

FMT_CONSTEXPR parse_range do_parse(basic_format_parse_context<Char>& ctx) {
auto begin = ctx.begin(), end = ctx.end();
if (begin == end || *begin == '}') return {begin, begin};
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
if (it == end || *it == '}') return it;

begin = detail::parse_align(begin, end, specs);
if (begin == end) return {begin, begin};
it = detail::parse_align(it, end, specs_);
if (it == end) return it;

begin = detail::parse_dynamic_spec(begin, end, specs.width, width_ref, ctx);
if (begin == end) return {begin, begin};
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
if (it == end) return it;

auto checker = detail::chrono_format_checker();
if (*begin == '.') {
if (*it == '.') {
checker.has_precision_integral = !std::is_floating_point<Rep>::value;
begin =
detail::parse_precision(begin, end, precision, precision_ref, ctx);
it = detail::parse_precision(it, end, specs_.precision, precision_ref_,
ctx);
}
if (begin != end && *begin == 'L') {
++begin;
localized = true;
if (it != end && *it == 'L') {
localized_ = true;
++it;
}
end = detail::parse_chrono_format(begin, end, checker);
return {begin, end};
}

public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
auto range = do_parse(ctx);
format_str = basic_string_view<Char>(
&*range.begin, detail::to_unsigned(range.end - range.begin));
return range.end;
end = detail::parse_chrono_format(it, end, checker);
format_str_ = {it, detail::to_unsigned(end - it)};
return end;
}

template <typename FormatContext>
auto format(const duration& d, FormatContext& ctx) const
auto format(std::chrono::duration<Rep, Period> d, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto specs_copy = specs;
auto precision_copy = precision;
auto begin = format_str.begin(), end = format_str.end();
auto specs = specs_;
auto precision = specs.precision;
specs.precision = -1;
auto begin = format_str_.begin(), end = format_str_.end();
// As a possible future optimization, we could avoid extra copying if width
// is not specified.
basic_memory_buffer<Char> buf;
auto buf = basic_memory_buffer<Char>();
auto out = std::back_inserter(buf);
detail::handle_dynamic_spec<detail::width_checker>(specs_copy.width,
width_ref, ctx);
detail::handle_dynamic_spec<detail::precision_checker>(precision_copy,
precision_ref, ctx);
detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
ctx);
detail::handle_dynamic_spec<detail::precision_checker>(precision,
precision_ref_, ctx);
if (begin == end || *begin == '}') {
out = detail::format_duration_value<Char>(out, d.count(), precision_copy);
out = detail::format_duration_value<Char>(out, d.count(), precision);
detail::format_duration_unit<Char, Period>(out);
} else {
detail::chrono_formatter<FormatContext, decltype(out), Rep, Period> f(
ctx, out, d);
f.precision = precision_copy;
f.localized = localized;
using chrono_formatter =
detail::chrono_formatter<FormatContext, decltype(out), Rep, Period>;
auto f = chrono_formatter(ctx, out, d);
f.precision = precision;
f.localized = localized_;
detail::parse_chrono_format(begin, end, f);
}
return detail::write(
ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs_copy);
ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
}
};

template <typename Char, typename Duration>
struct formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
Char> : formatter<std::tm, Char> {
FMT_CONSTEXPR formatter() {
this->format_str = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>{};
this->format_str_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>{};
}

template <typename FormatContext>
auto format(std::chrono::time_point<std::chrono::system_clock, Duration> val,
FormatContext& ctx) const -> decltype(ctx.out()) {
using period = typename Duration::period;
if (period::num != 1 || period::den != 1 ||
std::is_floating_point<typename Duration::rep>::value) {
if (detail::const_check(
period::num != 1 || period::den != 1 ||
std::is_floating_point<typename Duration::rep>::value)) {
const auto epoch = val.time_since_epoch();
auto subsecs = std::chrono::duration_cast<Duration>(
epoch - std::chrono::duration_cast<std::chrono::seconds>(epoch));

if (subsecs.count() < 0) {
auto second = std::chrono::seconds(1);
auto second =
std::chrono::duration_cast<Duration>(std::chrono::seconds(1));
if (epoch.count() < ((Duration::min)() + second).count())
FMT_THROW(format_error("duration is too small"));
subsecs += second;
Expand All @@ -2164,7 +2110,7 @@ template <typename Char, typename Duration>
struct formatter<std::chrono::local_time<Duration>, Char>
: formatter<std::tm, Char> {
FMT_CONSTEXPR formatter() {
this->format_str = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>{};
this->format_str_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>{};
}

template <typename FormatContext>
Expand Down Expand Up @@ -2207,51 +2153,46 @@ struct formatter<std::chrono::time_point<std::chrono::utc_clock, Duration>,

template <typename Char> struct formatter<std::tm, Char> {
private:
format_specs<Char> specs;
detail::arg_ref<Char> width_ref;
format_specs<Char> specs_;
detail::arg_ref<Char> width_ref_;

protected:
basic_string_view<Char> format_str;

FMT_CONSTEXPR auto do_parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
auto begin = ctx.begin(), end = ctx.end();
if (begin == end || *begin == '}') return begin;

begin = detail::parse_align(begin, end, specs);
if (begin == end) return end;

begin = detail::parse_dynamic_spec(begin, end, specs.width, width_ref, ctx);
if (begin == end) return end;

end = detail::parse_chrono_format(begin, end, detail::tm_format_checker());
// Replace default format_str only if the new spec is not empty.
if (end != begin) format_str = {begin, detail::to_unsigned(end - begin)};
return end;
}
basic_string_view<Char> format_str_;

template <typename FormatContext, typename Duration>
auto do_format(const std::tm& tm, FormatContext& ctx,
const Duration* subsecs) const -> decltype(ctx.out()) {
auto specs_copy = specs;
basic_memory_buffer<Char> buf;
auto specs = specs_;
auto buf = basic_memory_buffer<Char>();
auto out = std::back_inserter(buf);
detail::handle_dynamic_spec<detail::width_checker>(specs_copy.width,
width_ref, ctx);
detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
ctx);

const auto loc_ref = ctx.locale();
auto loc_ref = ctx.locale();
detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);
auto w =
detail::tm_writer<decltype(out), Char, Duration>(loc, out, tm, subsecs);
detail::parse_chrono_format(format_str.begin(), format_str.end(), w);
detail::parse_chrono_format(format_str_.begin(), format_str_.end(), w);
return detail::write(
ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs_copy);
ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
}

public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
return this->do_parse(ctx);
auto it = ctx.begin(), end = ctx.end();
if (it == end || *it == '}') return it;

it = detail::parse_align(it, end, specs_);
if (it == end) return it;

it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
if (it == end) return it;

end = detail::parse_chrono_format(it, end, detail::tm_format_checker());
// Replace the default format_str only if the new spec is not empty.
if (end != it) format_str_ = {it, detail::to_unsigned(end - it)};
return end;
}

template <typename FormatContext>
Expand Down
9 changes: 4 additions & 5 deletions 3rd/fmt/fmt/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ struct rgb {
uint8_t b;
};

FMT_BEGIN_DETAIL_NAMESPACE
namespace detail {

// color is a struct of either a rgb color or a terminal color.
struct color_type {
Expand All @@ -225,8 +225,7 @@ struct color_type {
uint32_t rgb_color;
} value;
};

FMT_END_DETAIL_NAMESPACE
} // namespace detail

/** A text style consisting of foreground and background colors and emphasis. */
class text_style {
Expand Down Expand Up @@ -323,7 +322,7 @@ FMT_CONSTEXPR inline text_style operator|(emphasis lhs, emphasis rhs) noexcept {
return text_style(lhs) | rhs;
}

FMT_BEGIN_DETAIL_NAMESPACE
namespace detail {

template <typename Char> struct ansi_color_escape {
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
Expand Down Expand Up @@ -457,7 +456,7 @@ void vformat_to(buffer<Char>& buf, const text_style& ts,
if (has_style) detail::reset_color<Char>(buf);
}

FMT_END_DETAIL_NAMESPACE
} // namespace detail

inline void vprint(std::FILE* f, const text_style& ts, string_view fmt,
format_args args) {
Expand Down
Loading

0 comments on commit 6bddb34

Please sign in to comment.