22 #ifndef FMT_SAFE_DURATION_CAST 23 # define FMT_SAFE_DURATION_CAST 1 25 #if FMT_SAFE_DURATION_CAST 35 template <
typename To,
typename From,
41 using F = std::numeric_limits<From>;
42 using T = std::numeric_limits<To>;
47 if (F::digits <= T::digits) {
57 return static_cast<To
>(from);
64 template <
typename To,
typename From,
70 using F = std::numeric_limits<From>;
71 using T = std::numeric_limits<To>;
82 if (F::digits > T::digits &&
83 from > static_cast<From>(detail::max_value<To>())) {
90 from > static_cast<From>(detail::max_value<To>())) {
94 return static_cast<To
>(from);
97 template <
typename To,
typename From,
118 template <
typename To,
typename From,
122 using T = std::numeric_limits<To>;
128 if (from >= T::lowest() && from <= (
T::max)()) {
129 return static_cast<To
>(from);
137 return static_cast<To
>(from);
140 template <
typename To,
typename From,
151 template <
typename To,
typename FromRep,
typename FromPeriod,
156 using From = std::chrono::duration<FromRep, FromPeriod>;
161 : std::ratio_divide<typename From::period, typename To::period> {};
163 static_assert(Factor::num > 0,
"num must be positive");
164 static_assert(Factor::den > 0,
"den must be positive");
170 using IntermediateRep =
171 typename std::common_type<
typename From::rep,
typename To::rep,
172 decltype(Factor::num)>::type;
175 IntermediateRep count =
176 lossless_integral_conversion<IntermediateRep>(from.count(), ec);
180 const auto max1 = detail::max_value<IntermediateRep>() / Factor::num;
191 count *= Factor::num;
195 auto tocount = lossless_integral_conversion<typename To::rep>(count, ec);
196 return ec ? To() : To(tocount);
202 template <
typename To,
typename FromRep,
typename FromPeriod,
207 using From = std::chrono::duration<FromRep, FromPeriod>;
211 return To{std::numeric_limits<typename To::rep>::quiet_NaN()};
217 if (std::isinf(from.count())) {
218 return To{from.count()};
224 : std::ratio_divide<typename From::period, typename To::period> {};
226 static_assert(Factor::num > 0,
"num must be positive");
227 static_assert(Factor::den > 0,
"den must be positive");
233 using IntermediateRep =
234 typename std::common_type<
typename From::rep,
typename To::rep,
235 decltype(Factor::num)>::type;
239 IntermediateRep count =
240 safe_float_conversion<IntermediateRep>(from.count(), ec);
246 if (Factor::num != 1) {
247 constexpr
auto max1 = detail::max_value<IntermediateRep>() /
248 static_cast<IntermediateRep>(Factor::num);
253 constexpr
auto min1 = std::numeric_limits<IntermediateRep>::lowest() /
254 static_cast<IntermediateRep
>(Factor::num);
259 count *=
static_cast<IntermediateRep
>(Factor::num);
263 if (Factor::den != 1) {
265 count /=
static_cast<common_t
>(Factor::den);
269 using ToRep =
typename To::rep;
271 const ToRep tocount = safe_float_conversion<ToRep>(count, ec);
297 dispatcher(std::time_t t) : time_(t) {}
300 using namespace fmt::detail;
301 return handle(localtime_r(&time_, &tm_));
304 bool handle(std::tm* tm) {
return tm !=
nullptr; }
307 using namespace fmt::detail;
311 bool fallback(
int res) {
return res == 0; }
315 using namespace fmt::detail;
318 return tm !=
nullptr;
329 std::chrono::time_point<std::chrono::system_clock> time_point) {
330 return localtime(std::chrono::system_clock::to_time_t(time_point));
339 dispatcher(std::time_t t) : time_(t) {}
342 using namespace fmt::detail;
343 return handle(
gmtime_r(&time_, &tm_));
346 bool handle(std::tm* tm) {
return tm !=
nullptr; }
349 using namespace fmt::detail;
350 return fallback(
gmtime_s(&tm_, &time_));
353 bool fallback(
int res) {
return res == 0; }
359 return tm !=
nullptr;
370 std::chrono::time_point<std::chrono::system_clock> time_point) {
371 return gmtime(std::chrono::system_clock::to_time_t(time_point));
376 const std::tm*
time) {
381 const std::tm*
time) {
382 return std::wcsftime(str, count, format, time);
386 template <
typename Char>
387 struct formatter<
std::chrono::time_point<std::chrono::system_clock>, Char>
389 template <
typename FormatContext>
390 auto format(std::chrono::time_point<std::chrono::system_clock> val,
391 FormatContext& ctx) -> decltype(ctx.out()) {
398 template <
typename ParseContext>
399 auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
400 auto it = ctx.begin();
401 if (it != ctx.end() && *it ==
':') ++it;
403 while (end != ctx.end() && *end !=
'}') ++end;
405 tm_format.append(it, end);
406 tm_format.push_back(
'\0');
410 template <
typename FormatContext>
411 auto format(
const std::tm& tm, FormatContext& ctx) -> decltype(ctx.out()) {
413 size_t start = buf.
size();
415 size_t size = buf.
capacity() - start;
418 buf.
resize(start + count);
421 if (size >= tm_format.size() * 256) {
428 const size_t MIN_GROWTH = 10;
431 return std::copy(buf.
begin(), buf.
end(), ctx.out());
441 template <>
FMT_CONSTEXPR const char* get_units<std::atto>() {
return "as"; }
442 template <>
FMT_CONSTEXPR const char* get_units<std::femto>() {
return "fs"; }
443 template <>
FMT_CONSTEXPR const char* get_units<std::pico>() {
return "ps"; }
444 template <>
FMT_CONSTEXPR const char* get_units<std::nano>() {
return "ns"; }
445 template <>
FMT_CONSTEXPR const char* get_units<std::micro>() {
return "µs"; }
446 template <>
FMT_CONSTEXPR const char* get_units<std::milli>() {
return "ms"; }
447 template <>
FMT_CONSTEXPR const char* get_units<std::centi>() {
return "cs"; }
448 template <>
FMT_CONSTEXPR const char* get_units<std::deci>() {
return "ds"; }
449 template <>
FMT_CONSTEXPR const char* get_units<std::ratio<1>>() {
return "s"; }
450 template <>
FMT_CONSTEXPR const char* get_units<std::deca>() {
return "das"; }
451 template <>
FMT_CONSTEXPR const char* get_units<std::hecto>() {
return "hs"; }
452 template <>
FMT_CONSTEXPR const char* get_units<std::kilo>() {
return "ks"; }
453 template <>
FMT_CONSTEXPR const char* get_units<std::mega>() {
return "Ms"; }
454 template <>
FMT_CONSTEXPR const char* get_units<std::giga>() {
return "Gs"; }
455 template <>
FMT_CONSTEXPR const char* get_units<std::tera>() {
return "Ts"; }
456 template <>
FMT_CONSTEXPR const char* get_units<std::peta>() {
return "Ps"; }
457 template <>
FMT_CONSTEXPR const char* get_units<std::exa>() {
return "Es"; }
472 template <
typename Char,
typename Handler>
484 if (begin !=
ptr) handler.on_text(begin,
ptr);
490 handler.on_text(
ptr - 1,
ptr);
493 const Char newline[] = {
'\n'};
494 handler.on_text(newline, newline + 1);
498 const Char tab[] = {
'\t'};
499 handler.on_text(tab, tab + 1);
504 handler.on_abbr_weekday();
507 handler.on_full_weekday();
510 handler.on_dec0_weekday(numeric_system::standard);
513 handler.on_dec1_weekday(numeric_system::standard);
517 handler.on_abbr_month();
520 handler.on_full_month();
524 handler.on_24_hour(numeric_system::standard);
527 handler.on_12_hour(numeric_system::standard);
530 handler.on_minute(numeric_system::standard);
533 handler.on_second(numeric_system::standard);
537 handler.on_datetime(numeric_system::standard);
540 handler.on_loc_date(numeric_system::standard);
543 handler.on_loc_time(numeric_system::standard);
546 handler.on_us_date();
549 handler.on_iso_date();
552 handler.on_12_hour_time();
555 handler.on_24_hour_time();
558 handler.on_iso_time();
564 handler.on_duration_value();
567 handler.on_duration_unit();
570 handler.on_utc_offset();
573 handler.on_tz_name();
581 handler.on_datetime(numeric_system::alternative);
584 handler.on_loc_date(numeric_system::alternative);
587 handler.on_loc_time(numeric_system::alternative);
599 handler.on_dec0_weekday(numeric_system::alternative);
602 handler.on_dec1_weekday(numeric_system::alternative);
605 handler.on_24_hour(numeric_system::alternative);
608 handler.on_12_hour(numeric_system::alternative);
611 handler.on_minute(numeric_system::alternative);
614 handler.on_second(numeric_system::alternative);
625 if (begin !=
ptr) handler.on_text(begin,
ptr);
632 template <
typename Char>
void on_text(
const Char*,
const Char*) {}
679 FMT_ASSERT(value >= 0 && value <= upper,
"invalid value");
681 return static_cast<int>(value);
686 std::isnan(value) || (value >= 0 && value <= static_cast<T>(upper)),
689 return static_cast<int>(value);
693 inline T
mod(T x,
int y) {
694 return x %
static_cast<T
>(y);
697 inline T
mod(T x,
int y) {
698 return std::fmod(x, static_cast<T>(y));
712 #if FMT_SAFE_DURATION_CAST 714 template <
typename To,
typename FromRep,
typename FromPeriod>
723 template <
typename Rep,
typename Period,
726 std::chrono::duration<Rep, Period>
d) {
729 #if FMT_SAFE_DURATION_CAST 730 using CommonSecondsType =
733 const auto d_as_whole_seconds =
736 const auto diff = d_as_common - d_as_whole_seconds;
741 auto s = std::chrono::duration_cast<std::chrono::seconds>(
d);
742 return std::chrono::duration_cast<std::chrono::milliseconds>(d - s);
746 template <
typename Rep,
typename Period,
749 std::chrono::duration<Rep, Period>
d) {
751 auto ms =
mod(d.count() *
static_cast<common_type
>(Period::num) /
752 static_cast<common_type>(Period::den) * 1000,
754 return std::chrono::duration<Rep, std::milli>(
static_cast<Rep
>(ms));
757 template <
typename Char,
typename Rep,
typename OutputIt>
759 const Char pr_f[] = {
'{',
':',
'.',
'{',
'}',
'f',
'}', 0};
760 if (precision >= 0)
return format_to(out, pr_f, val, precision);
761 const Char fp_f[] = {
'{',
':',
'g',
'}', 0};
762 const Char
format[] = {
'{',
'}', 0};
766 template <
typename Char,
typename OutputIt>
768 return std::copy(unit.
begin(), unit.
end(), out);
771 template <
typename OutputIt>
779 template <
typename Char,
typename Period,
typename OutputIt>
781 if (
const char* unit = get_units<Period>())
783 const Char num_f[] = {
'[',
'{',
'}',
']',
's', 0};
785 const Char num_def_f[] = {
'[',
'{',
'}',
'/',
'{',
'}',
']',
's', 0};
786 return format_to(out, num_def_f, Period::num, Period::den);
789 template <
typename FormatContext,
typename OutputIt,
typename Rep,
808 std::chrono::duration<Rep, Period> d)
820 #if FMT_SAFE_DURATION_CAST 822 auto tmpval = std::chrono::duration<rep, Period>(val);
825 s = std::chrono::duration_cast<
seconds>(
826 std::chrono::duration<rep, Period>(val));
848 Rep
hour()
const {
return static_cast<Rep
>(
mod((s.count() / 3600), 24)); }
851 Rep hour =
static_cast<Rep
>(
mod((s.count() / 3600), 12));
852 return hour <= 0 ? 12 : hour;
855 Rep
minute()
const {
return static_cast<Rep
>(
mod((s.count() / 60), 60)); }
856 Rep
second()
const {
return static_cast<Rep
>(
mod(s.count(), 60)); }
859 auto time = std::tm();
875 if (
isnan(value))
return write_nan();
879 if (width > num_digits) out = std::fill_n(out, width - num_digits,
'0');
880 out = format_decimal<char_type>(out, n, num_digits).end;
888 if (
isnan(val))
return write_nan();
889 auto locale = context.locale().template get<std::locale>();
890 auto& facet = std::use_facet<std::time_put<char_type>>(locale);
891 std::basic_ostringstream<char_type> os;
893 facet.put(os, os,
' ', &time, format, modifier);
895 std::copy(str.begin(), str.end(), out);
899 std::copy(begin, end, out);
918 if (handle_nan_inf())
return;
920 if (ns == numeric_system::standard)
return write(hour(), 2);
923 format_localized(
time,
'H',
'O');
927 if (handle_nan_inf())
return;
929 if (ns == numeric_system::standard)
return write(hour12(), 2);
932 format_localized(
time,
'I',
'O');
936 if (handle_nan_inf())
return;
938 if (ns == numeric_system::standard)
return write(minute(), 2);
941 format_localized(
time,
'M',
'O');
945 if (handle_nan_inf())
return;
947 if (ns == numeric_system::standard) {
949 #if FMT_SAFE_DURATION_CAST 951 using duration_rep = std::chrono::duration<rep, Period>;
952 using duration_Rep = std::chrono::duration<Rep, Period>;
955 auto tmpval = std::chrono::duration<Rep, Period>(val);
958 if (ms != std::chrono::milliseconds(0)) {
960 write(ms.count(), 3);
966 format_localized(
time,
'S',
'O');
970 if (handle_nan_inf())
return;
971 format_localized(
time(),
'r');
975 if (handle_nan_inf()) {
989 if (handle_nan_inf())
return;
994 if (handle_nan_inf())
return;
995 format_localized(
time(),
'p');
999 if (handle_nan_inf())
return;
1001 out = format_duration_value<char_type>(out, val, precision);
1005 out = format_duration_unit<char_type, Period>(out);
1010 template <
typename Rep,
typename Period,
typename Char>
1021 struct spec_handler {
1048 f.width_ref = make_arg_ref(arg_id);
1052 f.precision_ref = make_arg_ref(arg_id);
1057 struct parse_range {
1063 auto begin = ctx.
begin(), end = ctx.
end();
1064 if (begin == end || *begin ==
'}')
return {begin, begin};
1065 spec_handler handler{*
this, ctx, format_str};
1067 if (begin == end)
return {begin, begin};
1069 if (begin == end)
return {begin, begin};
1070 if (*begin ==
'.') {
1074 handler.on_error(
"precision not allowed for this argument type");
1077 return {begin, end};
1084 -> decltype(ctx.begin()) {
1085 auto range = do_parse(ctx);
1091 template <
typename FormatContext>
1093 auto begin = format_str.
begin(), end = format_str.
end();
1097 auto out = std::back_inserter(buf);
1098 detail::handle_dynamic_spec<detail::width_checker>(specs.
width, width_ref,
1100 detail::handle_dynamic_spec<detail::precision_checker>(precision,
1101 precision_ref, ctx);
1102 if (begin == end || *begin ==
'}') {
1103 out = detail::format_duration_value<Char>(out,
d.count(), precision);
1104 detail::format_duration_unit<Char, Period>(out);
1118 #endif // FMT_CHRONO_H_
#define FMT_ENABLE_IF(...)
FMT_CONSTEXPR To lossless_integral_conversion(const From from, int &ec)
enum MQTTPropertyCodes value
bool_constant< is_integral< T >::value &&!std::is_same< T, bool >::value &&!std::is_same< T, char >::value &&!std::is_same< T, wchar_t >::value > is_integer
FMT_CONSTEXPR const Char * parse_width(const Char *begin, const Char *end, Handler &&handler)
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&...args)
void reserve(size_t new_capacity)
const wchar_t * c_str() const
typename std::conditional< B, T, F >::type conditional_t
To safe_duration_cast(std::chrono::duration< FromRep, FromPeriod > from, int &ec)
constexpr T const_check(T value)
OutputIt format_duration_unit(OutputIt out)
constexpr iterator end() const FMT_NOEXCEPT
FMT_CONSTEXPR const Char * parse_align(const Char *begin, const Char *end, Handler &&handler)
std::tm gmtime(std::time_t time)
size_t size() const FMT_NOEXCEPT
size_t strftime(char *str, size_t count, const char *format, const std::tm *time)
OutputIt write(OutputIt out, basic_string_view< StrChar > s, const basic_format_specs< Char > &specs)
std::tm localtime(std::time_t time)
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_t >::value > is_signed
FMT_CONSTEXPR const Char * parse_precision(const Char *begin, const Char *end, Handler &&handler)
#define FMT_END_NAMESPACE
basic_string_view< char > string_view
FMT_CONSTEXPR std::make_unsigned< Int >::type to_unsigned(Int value)
size_t strftime(wchar_t *str, size_t count, const wchar_t *format, const std::tm *time)
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space, std::size_t &required_space)
constexpr iterator begin() const FMT_NOEXCEPT
FMT_CONSTEXPR int next_arg_id()
conditional_t< num_bits< T >()<=32 &&!FMT_REDUCE_INT_INSTANTIATIONS, uint32_t, conditional_t< num_bits< T >()<=64, uint64_t, uint128_t >> uint32_or_64_or_128_t
OutputIt format_to(OutputIt out, const S &format_str, Args &&...args)
FMT_CONSTEXPR To safe_float_conversion(const From from, int &ec)
constexpr iterator end() const
constexpr iterator begin() const
To fmt_safe_duration_cast(std::chrono::duration< FromRep, FromPeriod > from)
void resize(size_t count)
typename std::make_unsigned< T >::type type
FMT_CONSTEXPR const Char * parse_chrono_format(const Char *begin, const Char *end, Handler &&handler)
#define FMT_ASSERT(condition, message)
std::chrono::duration< Rep, std::milli > get_milliseconds(std::chrono::duration< Rep, Period > d)
#define FMT_BEGIN_NAMESPACE
FMT_CONSTEXPR const char * get_units()
FMT_CONSTEXPR void check_arg_id(int)
int to_nonnegative_int(T value, int upper)
FMT_CONSTEXPR bool is_negative(T value)
OutputIt format_duration_value(OutputIt out, Rep val, int precision)
int count_digits(uint64_t n)
size_t capacity() const FMT_NOEXCEPT
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
OutputIt copy_unit(string_view unit, OutputIt out, wchar_t)