diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 7d8559d4..22bef59c 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -217,17 +217,17 @@ inline int to_int(Int value) { return static_cast(value); } -template +template struct chrono_formatter { FormatContext &context; - typename FormatContext::iterator out; + OutputIt out; std::chrono::seconds s; std::chrono::milliseconds ms; typedef typename FormatContext::char_type char_type; - explicit chrono_formatter(FormatContext &ctx) - : context(ctx), out(ctx.out()) {} + explicit chrono_formatter(FormatContext &ctx, OutputIt o) + : context(ctx), out(o) {} int hour() const { return to_int((s.count() / 3600) % 24); } @@ -423,27 +423,27 @@ struct formatter, Char> { auto format(const duration &d, FormatContext &ctx) -> decltype(ctx.out()) { auto begin = format_str.begin(), end = format_str.end(); + memory_buffer buf; + typedef output_range range; + basic_writer w(range(ctx.out())); if (begin == end || *begin == '}') { - memory_buffer buf; if (const char *unit = get_units()) format_to(buf, "{}{}", d.count(), unit); else if (Period::den == 1) format_to(buf, "{}[{}]s", d.count(), Period::num); else format_to(buf, "{}[{}/{}]s", d.count(), Period::num, Period::den); - typedef output_range range; - basic_writer w(range(ctx.out())); internal::handle_dynamic_spec( spec.width_, width_ref, ctx); - w.write(buf.data(), buf.size(), spec); - return w.out(); + } else { + auto out = std::back_inserter(buf); + internal::chrono_formatter f(ctx, out); + f.s = std::chrono::duration_cast(d); + f.ms = std::chrono::duration_cast(d - f.s); + parse_chrono_format(begin, end, f); } - // TODO: use fill and align - internal::chrono_formatter f(ctx); - f.s = std::chrono::duration_cast(d); - f.ms = std::chrono::duration_cast(d - f.s); - parse_chrono_format(begin, end, f); - return f.out; + w.write(buf.data(), buf.size(), spec); + return w.out(); } }; diff --git a/include/fmt/format.h b/include/fmt/format.h index a4d79090..9f1ef6f8 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -479,6 +479,9 @@ class basic_memory_buffer: private Allocator, public internal::basic_buffer { void grow(std::size_t size) FMT_OVERRIDE; public: + typedef T value_type; + typedef const T &const_reference; + explicit basic_memory_buffer(const Allocator &alloc = Allocator()) : Allocator(alloc) { this->set(store_, SIZE); diff --git a/test/chrono-test.cc b/test/chrono-test.cc index 5e35a5c1..ec6092bb 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -97,6 +97,13 @@ TEST(ChronoTest, Align) { EXPECT_EQ("42s ", fmt::format("{:{}}", s, 5)); EXPECT_EQ(" 42s", fmt::format("{:>5}", 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) {