30 template <
typename Char,
typename Handler>
32 const Char *
begin,
const Char *
end, Handler &&handler) {
42 handler.on_text(begin,
ptr);
49 handler.on_text(
ptr - 1,
ptr);
52 const char newline[] =
"\n";
53 handler.on_text(newline, newline + 1);
57 const char tab[] =
"\t";
58 handler.on_text(tab, tab + 1);
63 handler.on_abbr_weekday();
66 handler.on_full_weekday();
69 handler.on_dec0_weekday(numeric_system::standard);
72 handler.on_dec1_weekday(numeric_system::standard);
76 handler.on_abbr_month();
79 handler.on_full_month();
83 handler.on_24_hour(numeric_system::standard);
86 handler.on_12_hour(numeric_system::standard);
89 handler.on_minute(numeric_system::standard);
92 handler.on_second(numeric_system::standard);
96 handler.on_datetime(numeric_system::standard);
99 handler.on_loc_date(numeric_system::standard);
102 handler.on_loc_time(numeric_system::standard);
105 handler.on_us_date();
108 handler.on_iso_date();
111 handler.on_12_hour_time();
114 handler.on_24_hour_time();
117 handler.on_iso_time();
123 handler.on_utc_offset();
126 handler.on_tz_name();
135 handler.on_datetime(numeric_system::alternative);
138 handler.on_loc_date(numeric_system::alternative);
141 handler.on_loc_time(numeric_system::alternative);
154 handler.on_dec0_weekday(numeric_system::alternative);
157 handler.on_dec1_weekday(numeric_system::alternative);
160 handler.on_24_hour(numeric_system::alternative);
163 handler.on_12_hour(numeric_system::alternative);
166 handler.on_minute(numeric_system::alternative);
169 handler.on_second(numeric_system::alternative);
181 handler.on_text(begin,
ptr);
188 template <
typename Char>
213 template <
typename Int>
215 FMT_ASSERT(value >= (std::numeric_limits<int>::min)() &&
216 value <= (std::numeric_limits<int>::max)(),
"invalid value");
217 return static_cast<int>(value);
220 template <
typename FormatContext,
typename OutputIt>
224 std::chrono::seconds
s;
225 std::chrono::milliseconds
ms;
230 : context(ctx), out(o) {}
235 auto hour =
to_int((s.count() / 3600) % 12);
236 return hour > 0 ? hour : 12;
243 auto time = std::tm();
244 time.tm_hour = hour();
245 time.tm_min = minute();
246 time.tm_sec = second();
254 if (width > num_digits)
255 out = std::fill_n(out, width - num_digits,
'0');
256 out = format_decimal<char_type>(out, n, num_digits);
260 auto locale = context.locale().template get<std::locale>();
261 auto &facet = std::use_facet<std::time_put<char_type>>(locale);
262 std::basic_ostringstream<char_type> os;
264 facet.put(os, os,
' ', &time, format, format + std::strlen(format));
289 if (ns == numeric_system::standard)
290 return write(hour(), 2);
292 time.tm_hour = hour();
293 format_localized(time,
"%OH");
297 if (ns == numeric_system::standard)
298 return write(hour12(), 2);
300 time.tm_hour = hour();
301 format_localized(time,
"%OI");
305 if (ns == numeric_system::standard)
306 return write(minute(), 2);
308 time.tm_min = minute();
309 format_localized(time,
"%OM");
313 if (ns == numeric_system::standard) {
315 if (ms != std::chrono::milliseconds(0)) {
322 time.tm_sec = second();
323 format_localized(time,
"%OS");
340 void on_am_pm() { format_localized(time(),
"%p"); }
347 template <>
FMT_CONSTEXPR const char *get_units<std::atto>() {
return "as"; }
348 template <>
FMT_CONSTEXPR const char *get_units<std::femto>() {
return "fs"; }
349 template <>
FMT_CONSTEXPR const char *get_units<std::pico>() {
return "ps"; }
350 template <>
FMT_CONSTEXPR const char *get_units<std::nano>() {
return "ns"; }
351 template <>
FMT_CONSTEXPR const char *get_units<std::micro>() {
return "µs"; }
352 template <>
FMT_CONSTEXPR const char *get_units<std::milli>() {
return "ms"; }
353 template <>
FMT_CONSTEXPR const char *get_units<std::centi>() {
return "cs"; }
354 template <>
FMT_CONSTEXPR const char *get_units<std::deci>() {
return "ds"; }
355 template <>
FMT_CONSTEXPR const char *get_units<std::ratio<1>>() {
return "s"; }
356 template <>
FMT_CONSTEXPR const char *get_units<std::deca>() {
return "das"; }
357 template <>
FMT_CONSTEXPR const char *get_units<std::hecto>() {
return "hs"; }
358 template <>
FMT_CONSTEXPR const char *get_units<std::kilo>() {
return "ks"; }
359 template <>
FMT_CONSTEXPR const char *get_units<std::mega>() {
return "Ms"; }
360 template <>
FMT_CONSTEXPR const char *get_units<std::giga>() {
return "Gs"; }
361 template <>
FMT_CONSTEXPR const char *get_units<std::tera>() {
return "Ts"; }
362 template <>
FMT_CONSTEXPR const char *get_units<std::peta>() {
return "Ps"; }
363 template <>
FMT_CONSTEXPR const char *get_units<std::exa>() {
return "Es"; }
371 template <
typename Rep,
typename Period,
typename Char>
377 typedef std::chrono::duration<Rep, Period> duration;
379 struct spec_handler {
385 template <
typename Id>
388 return arg_ref_type(arg_id);
395 void on_error(
const char *msg) {
throw format_error(msg); }
396 void on_fill(Char fill) { f.spec.fill_ = fill; }
397 void on_align(
alignment align) { f.spec.align_ = align; }
398 void on_width(
unsigned width) { f.spec.width_ = width; }
400 template <
typename Id>
401 void on_dynamic_width(Id arg_id) {
402 f.width_ref = make_arg_ref(arg_id);
410 -> decltype(ctx.begin()) {
411 auto begin = ctx.begin(),
end = ctx.end();
413 spec_handler handler{*
this, ctx};
422 template <
typename FormatContext>
423 auto format(
const duration &d, FormatContext &ctx)
424 -> decltype(ctx.out()) {
430 if (
const char *unit = get_units<Period>())
432 else if (Period::den == 1)
433 format_to(buf,
"{}[{}]s", d.count(), Period::num);
435 format_to(buf,
"{}[{}/{}]s", d.count(), Period::num, Period::den);
436 internal::handle_dynamic_spec<internal::width_checker>(
437 spec.
width_, width_ref, ctx);
439 auto out = std::back_inserter(buf);
441 f.
s = std::chrono::duration_cast<std::chrono::seconds>(d);
442 f.
ms = std::chrono::duration_cast<std::chrono::milliseconds>(d - f.
s);
445 w.write(buf.
data(), buf.
size(), spec);
452 #endif // FMT_CHRONO_H_
auto begin(const C &c) -> decltype(c.begin())
void write(std::basic_ostream< Char > &os, basic_buffer< Char > &buf)
#define FMT_END_NAMESPACE
const Char * parse_width(const Char *begin, const Char *end, Handler &&handler)
bool check_arg_id(unsigned)
std::make_unsigned< Int >::type to_unsigned(Int value)
std::basic_string< typename char_t< S >::type > format(const S &format_str, const Args &...args)
const void * ptr(const T *p)
const Char * parse_chrono_format(const Char *begin, const Char *end, Handler &&handler)
void copy(const RangeT &range, OutputIterator out)
std::enable_if< is_contiguous< Container >::value &&internal::is_string< S >::value, std::back_insert_iterator< Container > >::type format_to(std::back_insert_iterator< Container > out, const S &format_str, const Args &...args)
#define FMT_ASSERT(condition, message)
const Char * parse_align(const Char *begin, const Char *end, Handler &&handler)
#define FMT_BEGIN_NAMESPACE
unsigned count_digits(T n)
auto end(const C &c) -> decltype(c.end())