mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-25 06:21:00 +00:00
Implement fill/align/width for strftime-like formatting
This commit is contained in:
parent
3e01376e08
commit
77a7244804
@ -217,17 +217,17 @@ inline int to_int(Int value) {
|
|||||||
return static_cast<int>(value);
|
return static_cast<int>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext>
|
template <typename FormatContext, typename OutputIt>
|
||||||
struct chrono_formatter {
|
struct chrono_formatter {
|
||||||
FormatContext &context;
|
FormatContext &context;
|
||||||
typename FormatContext::iterator out;
|
OutputIt out;
|
||||||
std::chrono::seconds s;
|
std::chrono::seconds s;
|
||||||
std::chrono::milliseconds ms;
|
std::chrono::milliseconds ms;
|
||||||
|
|
||||||
typedef typename FormatContext::char_type char_type;
|
typedef typename FormatContext::char_type char_type;
|
||||||
|
|
||||||
explicit chrono_formatter(FormatContext &ctx)
|
explicit chrono_formatter(FormatContext &ctx, OutputIt o)
|
||||||
: context(ctx), out(ctx.out()) {}
|
: context(ctx), out(o) {}
|
||||||
|
|
||||||
int hour() const { return to_int((s.count() / 3600) % 24); }
|
int hour() const { return to_int((s.count() / 3600) % 24); }
|
||||||
|
|
||||||
@ -423,27 +423,27 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
|||||||
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();
|
||||||
|
memory_buffer buf;
|
||||||
|
typedef output_range<decltype(ctx.out()), Char> range;
|
||||||
|
basic_writer<range> w(range(ctx.out()));
|
||||||
if (begin == end || *begin == '}') {
|
if (begin == end || *begin == '}') {
|
||||||
memory_buffer buf;
|
|
||||||
if (const char *unit = get_units<Period>())
|
if (const char *unit = get_units<Period>())
|
||||||
format_to(buf, "{}{}", d.count(), unit);
|
format_to(buf, "{}{}", d.count(), unit);
|
||||||
else if (Period::den == 1)
|
else if (Period::den == 1)
|
||||||
format_to(buf, "{}[{}]s", d.count(), Period::num);
|
format_to(buf, "{}[{}]s", d.count(), Period::num);
|
||||||
else
|
else
|
||||||
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;
|
|
||||||
basic_writer<range> w(range(ctx.out()));
|
|
||||||
internal::handle_dynamic_spec<internal::width_checker>(
|
internal::handle_dynamic_spec<internal::width_checker>(
|
||||||
spec.width_, width_ref, ctx);
|
spec.width_, width_ref, ctx);
|
||||||
w.write(buf.data(), buf.size(), spec);
|
} else {
|
||||||
return w.out();
|
auto out = std::back_inserter(buf);
|
||||||
|
internal::chrono_formatter<FormatContext, decltype(out)> f(ctx, out);
|
||||||
|
f.s = std::chrono::duration_cast<std::chrono::seconds>(d);
|
||||||
|
f.ms = std::chrono::duration_cast<std::chrono::milliseconds>(d - f.s);
|
||||||
|
parse_chrono_format(begin, end, f);
|
||||||
}
|
}
|
||||||
// TODO: use fill and align
|
w.write(buf.data(), buf.size(), spec);
|
||||||
internal::chrono_formatter<FormatContext> f(ctx);
|
return w.out();
|
||||||
f.s = std::chrono::duration_cast<std::chrono::seconds>(d);
|
|
||||||
f.ms = std::chrono::duration_cast<std::chrono::milliseconds>(d - f.s);
|
|
||||||
parse_chrono_format(begin, end, f);
|
|
||||||
return f.out;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -479,6 +479,9 @@ class basic_memory_buffer: private Allocator, public internal::basic_buffer<T> {
|
|||||||
void grow(std::size_t size) FMT_OVERRIDE;
|
void grow(std::size_t size) FMT_OVERRIDE;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef const T &const_reference;
|
||||||
|
|
||||||
explicit basic_memory_buffer(const Allocator &alloc = Allocator())
|
explicit basic_memory_buffer(const Allocator &alloc = Allocator())
|
||||||
: Allocator(alloc) {
|
: Allocator(alloc) {
|
||||||
this->set(store_, SIZE);
|
this->set(store_, SIZE);
|
||||||
|
@ -97,6 +97,13 @@ TEST(ChronoTest, Align) {
|
|||||||
EXPECT_EQ("42s ", fmt::format("{:{}}", s, 5));
|
EXPECT_EQ("42s ", fmt::format("{:{}}", s, 5));
|
||||||
EXPECT_EQ(" 42s", fmt::format("{:>5}", s));
|
EXPECT_EQ(" 42s", fmt::format("{:>5}", s));
|
||||||
EXPECT_EQ("**42s**", fmt::format("{:*^7}", s));
|
EXPECT_EQ("**42s**", fmt::format("{:*^7}", s));
|
||||||
|
EXPECT_EQ("03:25:45 ",
|
||||||
|
fmt::format("{:12%H:%M:%S}", std::chrono::seconds(12345)));
|
||||||
|
EXPECT_EQ(" 03:25:45",
|
||||||
|
fmt::format("{:>12%H:%M:%S}", std::chrono::seconds(12345)));
|
||||||
|
EXPECT_EQ("~~03:25:45~~",
|
||||||
|
fmt::format("{:~^12%H:%M:%S}", std::chrono::seconds(12345)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ChronoTest, FormatSpecs) {
|
TEST(ChronoTest, FormatSpecs) {
|
||||||
|
Loading…
Reference in New Issue
Block a user