summaryrefslogtreecommitdiff
path: root/matching/include/spdlog/fmt/bundled/chrono.h
diff options
context:
space:
mode:
Diffstat (limited to 'matching/include/spdlog/fmt/bundled/chrono.h')
-rw-r--r--matching/include/spdlog/fmt/bundled/chrono.h452
1 files changed, 452 insertions, 0 deletions
diff --git a/matching/include/spdlog/fmt/bundled/chrono.h b/matching/include/spdlog/fmt/bundled/chrono.h
new file mode 100644
index 0000000..209cdc2
--- /dev/null
+++ b/matching/include/spdlog/fmt/bundled/chrono.h
@@ -0,0 +1,452 @@
+// Formatting library for C++ - chrono support
+//
+// Copyright (c) 2012 - present, Victor Zverovich
+// All rights reserved.
+//
+// For the license information refer to format.h.
+
+#ifndef FMT_CHRONO_H_
+#define FMT_CHRONO_H_
+
+#include "format.h"
+#include "locale.h"
+
+#include <chrono>
+#include <ctime>
+#include <locale>
+#include <sstream>
+
+FMT_BEGIN_NAMESPACE
+
+namespace internal{
+
+enum class numeric_system {
+ standard,
+ // Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale.
+ alternative
+};
+
+// Parses a put_time-like format string and invokes handler actions.
+template <typename Char, typename Handler>
+FMT_CONSTEXPR const Char *parse_chrono_format(
+ const Char *begin, const Char *end, Handler &&handler) {
+ auto ptr = begin;
+ while (ptr != end) {
+ auto c = *ptr;
+ if (c == '}') break;
+ if (c != '%') {
+ ++ptr;
+ continue;
+ }
+ if (begin != ptr)
+ handler.on_text(begin, ptr);
+ ++ptr; // consume '%'
+ if (ptr == end)
+ throw format_error("invalid format");
+ c = *ptr++;
+ switch (c) {
+ case '%':
+ handler.on_text(ptr - 1, ptr);
+ break;
+ case 'n': {
+ const char newline[] = "\n";
+ handler.on_text(newline, newline + 1);
+ break;
+ }
+ case 't': {
+ const char tab[] = "\t";
+ handler.on_text(tab, tab + 1);
+ break;
+ }
+ // Day of the week:
+ case 'a':
+ handler.on_abbr_weekday();
+ break;
+ case 'A':
+ handler.on_full_weekday();
+ break;
+ case 'w':
+ handler.on_dec0_weekday(numeric_system::standard);
+ break;
+ case 'u':
+ handler.on_dec1_weekday(numeric_system::standard);
+ break;
+ // Month:
+ case 'b':
+ handler.on_abbr_month();
+ break;
+ case 'B':
+ handler.on_full_month();
+ break;
+ // Hour, minute, second:
+ case 'H':
+ handler.on_24_hour(numeric_system::standard);
+ break;
+ case 'I':
+ handler.on_12_hour(numeric_system::standard);
+ break;
+ case 'M':
+ handler.on_minute(numeric_system::standard);
+ break;
+ case 'S':
+ handler.on_second(numeric_system::standard);
+ break;
+ // Other:
+ case 'c':
+ handler.on_datetime(numeric_system::standard);
+ break;
+ case 'x':
+ handler.on_loc_date(numeric_system::standard);
+ break;
+ case 'X':
+ handler.on_loc_time(numeric_system::standard);
+ break;
+ case 'D':
+ handler.on_us_date();
+ break;
+ case 'F':
+ handler.on_iso_date();
+ break;
+ case 'r':
+ handler.on_12_hour_time();
+ break;
+ case 'R':
+ handler.on_24_hour_time();
+ break;
+ case 'T':
+ handler.on_iso_time();
+ break;
+ case 'p':
+ handler.on_am_pm();
+ break;
+ case 'z':
+ handler.on_utc_offset();
+ break;
+ case 'Z':
+ handler.on_tz_name();
+ break;
+ // Alternative representation:
+ case 'E': {
+ if (ptr == end)
+ throw format_error("invalid format");
+ c = *ptr++;
+ switch (c) {
+ case 'c':
+ handler.on_datetime(numeric_system::alternative);
+ break;
+ case 'x':
+ handler.on_loc_date(numeric_system::alternative);
+ break;
+ case 'X':
+ handler.on_loc_time(numeric_system::alternative);
+ break;
+ default:
+ throw format_error("invalid format");
+ }
+ break;
+ }
+ case 'O':
+ if (ptr == end)
+ throw format_error("invalid format");
+ c = *ptr++;
+ switch (c) {
+ case 'w':
+ handler.on_dec0_weekday(numeric_system::alternative);
+ break;
+ case 'u':
+ handler.on_dec1_weekday(numeric_system::alternative);
+ break;
+ case 'H':
+ handler.on_24_hour(numeric_system::alternative);
+ break;
+ case 'I':
+ handler.on_12_hour(numeric_system::alternative);
+ break;
+ case 'M':
+ handler.on_minute(numeric_system::alternative);
+ break;
+ case 'S':
+ handler.on_second(numeric_system::alternative);
+ break;
+ default:
+ throw format_error("invalid format");
+ }
+ break;
+ default:
+ throw format_error("invalid format");
+ }
+ begin = ptr;
+ }
+ if (begin != ptr)
+ handler.on_text(begin, ptr);
+ return ptr;
+}
+
+struct chrono_format_checker {
+ void report_no_date() { throw format_error("no date"); }
+
+ template <typename Char>
+ void on_text(const Char *, const Char *) {}
+ void on_abbr_weekday() { report_no_date(); }
+ void on_full_weekday() { report_no_date(); }
+ void on_dec0_weekday(numeric_system) { report_no_date(); }
+ void on_dec1_weekday(numeric_system) { report_no_date(); }
+ void on_abbr_month() { report_no_date(); }
+ void on_full_month() { report_no_date(); }
+ void on_24_hour(numeric_system) {}
+ void on_12_hour(numeric_system) {}
+ void on_minute(numeric_system) {}
+ void on_second(numeric_system) {}
+ void on_datetime(numeric_system) { report_no_date(); }
+ void on_loc_date(numeric_system) { report_no_date(); }
+ void on_loc_time(numeric_system) { report_no_date(); }
+ void on_us_date() { report_no_date(); }
+ void on_iso_date() { report_no_date(); }
+ void on_12_hour_time() {}
+ void on_24_hour_time() {}
+ void on_iso_time() {}
+ void on_am_pm() {}
+ void on_utc_offset() { report_no_date(); }
+ void on_tz_name() { report_no_date(); }
+};
+
+template <typename Int>
+inline int to_int(Int value) {
+ FMT_ASSERT(value >= (std::numeric_limits<int>::min)() &&
+ value <= (std::numeric_limits<int>::max)(), "invalid value");
+ return static_cast<int>(value);
+}
+
+template <typename FormatContext, typename OutputIt>
+struct chrono_formatter {
+ FormatContext &context;
+ OutputIt out;
+ std::chrono::seconds s;
+ std::chrono::milliseconds ms;
+
+ typedef typename FormatContext::char_type char_type;
+
+ explicit chrono_formatter(FormatContext &ctx, OutputIt o)
+ : context(ctx), out(o) {}
+
+ int hour() const { return to_int((s.count() / 3600) % 24); }
+
+ int hour12() const {
+ auto hour = to_int((s.count() / 3600) % 12);
+ return hour > 0 ? hour : 12;
+ }
+
+ int minute() const { return to_int((s.count() / 60) % 60); }
+ int second() const { return to_int(s.count() % 60); }
+
+ std::tm time() const {
+ auto time = std::tm();
+ time.tm_hour = hour();
+ time.tm_min = minute();
+ time.tm_sec = second();
+ return time;
+ }
+
+ void write(int value, int width) {
+ typedef typename int_traits<int>::main_type main_type;
+ main_type n = to_unsigned(value);
+ int num_digits = internal::count_digits(n);
+ if (width > num_digits)
+ out = std::fill_n(out, width - num_digits, '0');
+ out = format_decimal<char_type>(out, n, num_digits);
+ }
+
+ void format_localized(const tm &time, const char *format) {
+ auto locale = context.locale().template get<std::locale>();
+ auto &facet = std::use_facet<std::time_put<char_type>>(locale);
+ std::basic_ostringstream<char_type> os;
+ os.imbue(locale);
+ facet.put(os, os, ' ', &time, format, format + std::strlen(format));
+ auto str = os.str();
+ std::copy(str.begin(), str.end(), out);
+ }
+
+ void on_text(const char_type *begin, const char_type *end) {
+ std::copy(begin, end, out);
+ }
+
+ // These are not implemented because durations don't have date information.
+ void on_abbr_weekday() {}
+ void on_full_weekday() {}
+ void on_dec0_weekday(numeric_system) {}
+ void on_dec1_weekday(numeric_system) {}
+ void on_abbr_month() {}
+ void on_full_month() {}
+ void on_datetime(numeric_system) {}
+ void on_loc_date(numeric_system) {}
+ void on_loc_time(numeric_system) {}
+ void on_us_date() {}
+ void on_iso_date() {}
+ void on_utc_offset() {}
+ void on_tz_name() {}
+
+ void on_24_hour(numeric_system ns) {
+ if (ns == numeric_system::standard)
+ return write(hour(), 2);
+ auto time = tm();
+ time.tm_hour = hour();
+ format_localized(time, "%OH");
+ }
+
+ void on_12_hour(numeric_system ns) {
+ if (ns == numeric_system::standard)
+ return write(hour12(), 2);
+ auto time = tm();
+ time.tm_hour = hour();
+ format_localized(time, "%OI");
+ }
+
+ void on_minute(numeric_system ns) {
+ if (ns == numeric_system::standard)
+ return write(minute(), 2);
+ auto time = tm();
+ time.tm_min = minute();
+ format_localized(time, "%OM");
+ }
+
+ void on_second(numeric_system ns) {
+ if (ns == numeric_system::standard) {
+ write(second(), 2);
+ if (ms != std::chrono::milliseconds(0)) {
+ *out++ = '.';
+ write(to_int(ms.count()), 3);
+ }
+ return;
+ }
+ auto time = tm();
+ time.tm_sec = second();
+ format_localized(time, "%OS");
+ }
+
+ void on_12_hour_time() { format_localized(time(), "%r"); }
+
+ void on_24_hour_time() {
+ write(hour(), 2);
+ *out++ = ':';
+ write(minute(), 2);
+ }
+
+ void on_iso_time() {
+ on_24_hour_time();
+ *out++ = ':';
+ write(second(), 2);
+ }
+
+ void on_am_pm() { format_localized(time(), "%p"); }
+};
+} // namespace internal
+
+template <typename Period> FMT_CONSTEXPR const char *get_units() {
+ return FMT_NULL;
+}
+template <> FMT_CONSTEXPR const char *get_units<std::atto>() { return "as"; }
+template <> FMT_CONSTEXPR const char *get_units<std::femto>() { return "fs"; }
+template <> FMT_CONSTEXPR const char *get_units<std::pico>() { return "ps"; }
+template <> FMT_CONSTEXPR const char *get_units<std::nano>() { return "ns"; }
+template <> 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";
+}
+template <> FMT_CONSTEXPR const char *get_units<std::ratio<3600>>() {
+ return "h";
+}
+
+template <typename Rep, typename Period, typename Char>
+struct formatter<std::chrono::duration<Rep, Period>, Char> {
+ private:
+ align_spec spec;
+ internal::arg_ref<Char> width_ref;
+ mutable basic_string_view<Char> format_str;
+ typedef std::chrono::duration<Rep, Period> duration;
+
+ struct spec_handler {
+ formatter &f;
+ basic_parse_context<Char> &context;
+
+ typedef internal::arg_ref<Char> arg_ref_type;
+
+ template <typename Id>
+ FMT_CONSTEXPR arg_ref_type make_arg_ref(Id arg_id) {
+ context.check_arg_id(arg_id);
+ return arg_ref_type(arg_id);
+ }
+
+ FMT_CONSTEXPR arg_ref_type make_arg_ref(internal::auto_id) {
+ return arg_ref_type(context.next_arg_id());
+ }
+
+ void on_error(const char *msg) { throw format_error(msg); }
+ void on_fill(Char fill) { f.spec.fill_ = fill; }
+ void on_align(alignment align) { f.spec.align_ = align; }
+ void on_width(unsigned width) { f.spec.width_ = width; }
+
+ template <typename Id>
+ void on_dynamic_width(Id arg_id) {
+ f.width_ref = make_arg_ref(arg_id);
+ }
+ };
+
+ public:
+ formatter() : spec() {}
+
+ FMT_CONSTEXPR auto parse(basic_parse_context<Char> &ctx)
+ -> decltype(ctx.begin()) {
+ auto begin = ctx.begin(), end = ctx.end();
+ if (begin == end) return begin;
+ spec_handler handler{*this, ctx};
+ begin = internal::parse_align(begin, end, handler);
+ if (begin == end) return begin;
+ begin = internal::parse_width(begin, end, handler);
+ end = parse_chrono_format(begin, end, internal::chrono_format_checker());
+ format_str = basic_string_view<Char>(&*begin, internal::to_unsigned(end - begin));
+ return end;
+ }
+
+ template <typename FormatContext>
+ 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<decltype(ctx.out()), Char> range;
+ basic_writer<range> w(range(ctx.out()));
+ if (begin == end || *begin == '}') {
+ if (const char *unit = get_units<Period>())
+ 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);
+ internal::handle_dynamic_spec<internal::width_checker>(
+ spec.width_, width_ref, ctx);
+ } else {
+ 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);
+ }
+ w.write(buf.data(), buf.size(), spec);
+ return w.out();
+ }
+};
+
+FMT_END_NAMESPACE
+
+#endif // FMT_CHRONO_H_