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

Code before:
#endif

template <typename Rep, typename Period,
          FMT_ENABLE_IF(std::is_integral<Rep>::value)>
inline std::chrono::duration<Rep, std::milli> get_milliseconds(
    std::chrono::duration<Rep, Period> d) {
  // this may overflow and/or the result may not fit in the
  // target type.
#if FMT_SAFE_DURATION_CAST
  using CommonSecondsType =
      typename std::common_type<decltype(d), std::chrono::seconds>::type;
  const auto d_as_common = fmt_safe_duration_cast<CommonSecondsType>(d);
  const auto d_as_whole_seconds =
      fmt_safe_duration_cast<std::chrono::seconds>(d_as_common);
  // this conversion should be nonproblematic
  const auto diff = d_as_common - d_as_whole_seconds;
  const auto ms =
      fmt_safe_duration_cast<std::chrono::duration<Rep, std::milli>>(diff);
  return ms;
#else
  auto s = std::chrono::duration_cast<std::chrono::seconds>(d);
  return std::chrono::duration_cast<std::chrono::milliseconds>(d - s);
#endif
}

template <class Duration> class subsecond_helper {
  /// Returns the amount of digits according to the c++ 20 spec
  /// In the range [0, 18], if more than 18 fractional digits are required,
  /// then we return 6 for microseconds precision
  static constexpr int num_digits(std::intmax_t num, std::intmax_t den,
                                  int n = 0) {
    return num % den == 0 ? n : (n > 18 ? 6 : num_digits(num * 10, den, n + 1));
  }

  static constexpr std::intmax_t pow10(std::uint32_t n) {
    return n == 0 ? 1 : 10 * pow10(n - 1);
  }

  template <class Rep, class Period,
            FMT_ENABLE_IF(std::numeric_limits<Rep>::is_signed)>
  static constexpr std::chrono::duration<Rep, Period> abs(
      std::chrono::duration<Rep, Period> d) {
    return d >= d.zero() ? d : -d;
  }

  template <class Rep, class Period,
            FMT_ENABLE_IF(!std::numeric_limits<Rep>::is_signed)>
  static constexpr std::chrono::duration<Rep, Period> abs(
      std::chrono::duration<Rep, Period> d) {
    return d;
  }

Review comment (refactor):
Having a utility struct seems unnecessary. I suggest converting it into a function (e.g. `write_fractional_seconds`) or merging the logic into `write` where it is used.

Code after:
#endif

template <typename Rep, typename Period,
          FMT_ENABLE_IF(std::is_integral<Rep>::value)>
inline std::chrono::duration<Rep, std::milli> get_milliseconds(
    std::chrono::duration<Rep, Period> d) {
  // this may overflow and/or the result may not fit in the
  // target type.
#if FMT_SAFE_DURATION_CAST
  using CommonSecondsType =
      typename std::common_type<decltype(d), std::chrono::seconds>::type;
  const auto d_as_common = fmt_safe_duration_cast<CommonSecondsType>(d);
  const auto d_as_whole_seconds =
      fmt_safe_duration_cast<std::chrono::seconds>(d_as_common);
  // this conversion should be nonproblematic
  const auto diff = d_as_common - d_as_whole_seconds;
  const auto ms =
      fmt_safe_duration_cast<std::chrono::duration<Rep, std::milli>>(diff);
  return ms;
#else
  auto s = std::chrono::duration_cast<std::chrono::seconds>(d);
  return std::chrono::duration_cast<std::chrono::milliseconds>(d - s);
#endif
}

// Returns the number of digits according to the c++ 20 spec
// In the range [0, 18], if more than 18 fractional digits are required,
// then we return 6 for microseconds precision.
constexpr int num_digits(long long num, long long den, int n = 0) {
  return num % den == 0 ? n : (n > 18 ? 6 : num_digits(num * 10, den, n + 1));
}

constexpr long long pow10(std::uint32_t n) {
  return n == 0 ? 1 : 10 * pow10(n - 1);
}

template <class Rep, class Period,
          FMT_ENABLE_IF(std::numeric_limits<Rep>::is_signed)>
constexpr std::chrono::duration<Rep, Period> abs(
    std::chrono::duration<Rep, Period> d) {
  // We need to compare the duration using the count() method directly
  // due to a compiler bug in clang-11 regarding the spaceship operator,
  // when -Wzero-as-null-pointer-constant is enabled.
  // In clang-12 the bug has been fixed. See
  // https://bugs.llvm.org/show_bug.cgi?id=46235 and the reproducible example:
  // https://www.godbolt.org/z/Knbb5joYx
  return d.count() >= d.zero().count() ? d : -d;
}

template <class Rep, class Period,
          FMT_ENABLE_IF(!std::numeric_limits<Rep>::is_signed)>