Repository: fmtlib/fmt
File: include/fmt/chrono.h (C/C++)

Code before:
std::time_t to_time_t(
    std::chrono::time_point<std::chrono::system_clock, Duration> time_point) {
#if FMT_SAFE_DURATION_CAST
  return fmt_safe_duration_cast<std::chrono::duration<std::time_t>>(
             time_point.time_since_epoch())
      .count();
#else
  return std::chrono::duration_cast<std::chrono::duration<std::time_t>>(
             time_point.time_since_epoch())
      .count();
#endif
}

template <typename Duration,
          FMT_ENABLE_IF(std::is_floating_point<typename Duration::rep>::value)>
std::time_t to_time_t(
    std::chrono::time_point<std::chrono::system_clock, Duration> time_point) {
  return std::chrono::duration_cast<std::chrono::duration<std::time_t>>(
             time_point.time_since_epoch())
      .count();
}
}  // namespace detail

FMT_BEGIN_EXPORT

/**
  Converts given time since epoch as ``std::time_t`` value into calendar time,
  expressed in local time. Unlike ``std::localtime``, this function is
  thread-safe on most platforms.
 */
inline std::tm localtime(std::time_t time) {
  struct dispatcher {
    std::time_t time_;
    std::tm tm_;

    dispatcher(std::time_t t) : time_(t) {}

    bool run() {
      using namespace fmt::detail;
      return handle(localtime_r(&time_, &tm_));
    }

    bool handle(std::tm* tm) { return tm != nullptr; }

    bool handle(detail::null<>) {
      using namespace fmt::detail;
      return fallback(localtime_s(&tm_, &time_));
    }

    bool fallback(int res) { return res == 0; }


Review comment (suggestion):
Considering that the two overloads of `to_time_t` are identical modulo `fmt_safe_duration_cast` I suggest merging them into one and moving the difference into `fmt_safe_duration_cast` which can just forward to `duration_cast` for floating point and when `FMT_SAFE_DURATION_CAST` is disabled.

Code after:
#if FMT_SAFE_DURATION_CAST
  // throwing version of safe_duration_cast
  // only available for integer<->integer or float<->float casts
  int ec;
  To to = safe_duration_cast::safe_duration_cast<To>(from, ec);
  if (ec) FMT_THROW(format_error("cannot format duration"));
  return to;
#else
  // standard duration cast, may overflow and invoke undefined behavior
  return std::chrono::duration_cast<To>(from);
#endif
}

template <
    typename To, typename FromRep, typename FromPeriod,
    FMT_ENABLE_IF(!is_same_arithmetic_type<FromRep, typename To::rep>::value)>
To fmt_duration_cast(std::chrono::duration<FromRep, FromPeriod> from) {
  // mixed integer<->float cast is not supported with safe_duration_cast
  // fallback to standard duration cast in this case
  return std::chrono::duration_cast<To>(from);
}

template <typename Duration>
std::time_t to_time_t(
    std::chrono::time_point<std::chrono::system_clock, Duration> time_point) {
  // cannot use std::chrono::system_clock::to_time_t() since this would first
  // require a cast to std::chrono::system_clock::time_point, which could
  // overflow.
  return fmt_duration_cast<std::chrono::duration<std::time_t>>(
             time_point.time_since_epoch())
      .count();
}
}  // namespace detail

FMT_BEGIN_EXPORT

/**
  Converts given time since epoch as ``std::time_t`` value into calendar time,
  expressed in local time. Unlike ``std::localtime``, this function is
  thread-safe on most platforms.
 */
inline std::tm localtime(std::time_t time) {
  struct dispatcher {
    std::time_t time_;
    std::tm tm_;

    dispatcher(std::time_t t) : time_(t) {}

    bool run() {
      using namespace fmt::detail;
      return handle(localtime_r(&time_, &tm_));