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

Code before:
      typename std::common_type<typename Duration::rep,
                                std::chrono::seconds::rep>::type,
      std::ratio<1, detail::pow10(num_fractional_digits)>>;
  if (std::ratio_less<typename subsecond_precision::period,
                      std::chrono::seconds::period>::value) {
    *out++ = '.';
    auto fractional =
        detail::abs(d) - std::chrono::duration_cast<std::chrono::seconds>(d);
    auto subseconds =
        std::chrono::treat_as_floating_point<
            typename subsecond_precision::rep>::value
            ? fractional.count()
            : std::chrono::duration_cast<subsecond_precision>(fractional)
                  .count();
    uint32_or_64_or_128_t<long long> n =
        to_unsigned(to_nonnegative_int(subseconds, max_value<long long>()));
    int num_digits = detail::count_digits(n);
    if (num_fractional_digits > num_digits)
      out = std::fill_n(out, num_fractional_digits - num_digits, '0');
    out = format_decimal<char_type>(out, n, num_digits).end;
  }
}

// Format fractional seconds with an appropiate number of digits.
template <typename Rep, long long Num, long long Den>
basic_memory_buffer<char> format_sec_fractional(Rep val) {
  auto num_fractional_digits = count_fractional_digits<Num, Den>::value;
  // For non-integer values, we ensure at least 6 digits to get microsecond
  // precision.
  if (!(std::round(val) == val) && num_fractional_digits < 6) {
    num_fractional_digits = 6;
  }
  auto buf = memory_buffer();
  format_to(std::back_inserter(buf), runtime("{:.{}f}"),
            std::fmod(val * static_cast<Rep>(Num) / static_cast<Rep>(Den),
                      static_cast<Rep>(60)),
            num_fractional_digits);
  return buf;
}

template <typename OutputIt, typename Char, typename Rep = int,
          typename Period = std::ratio<1, 1>>
class tm_writer {
 private:
  static constexpr int days_per_week = 7;

  const std::locale& loc_;
  const bool is_classic_;
  OutputIt out_;
  std::chrono::duration<Rep, Period> subsecs_;
  bool hasSubsecs_;

Review comment (suggestion):
Moving ``basic_memory_buffer`` may use copy (for buffers shorter than 500 chars).
See implementation:

https://github.com/fmtlib/fmt/blob/662adf4f33346ba9aba8b072194e319869ede54a/include/fmt/format.h#L864-L893

I think it's better to pass basic_memory_buffer by reference, like this:

https://github.com/fmtlib/fmt/blob/662adf4f33346ba9aba8b072194e319869ede54a/include/fmt/std.h#L50-L53


Code after:
  using subsecond_precision = std::chrono::duration<
      typename std::common_type<typename Duration::rep,
                                std::chrono::seconds::rep>::type,
      std::ratio<1, detail::pow10(num_fractional_digits)>>;
  if (std::ratio_less<typename subsecond_precision::period,
                      std::chrono::seconds::period>::value) {
    *out++ = '.';
    auto fractional =
        detail::abs(d) - std::chrono::duration_cast<std::chrono::seconds>(d);
    auto subseconds =
        std::chrono::treat_as_floating_point<
            typename subsecond_precision::rep>::value
            ? fractional.count()
            : std::chrono::duration_cast<subsecond_precision>(fractional)
                  .count();
    uint32_or_64_or_128_t<long long> n =
        to_unsigned(to_nonnegative_int(subseconds, max_value<long long>()));
    int num_digits = detail::count_digits(n);
    if (num_fractional_digits > num_digits)
      out = std::fill_n(out, num_fractional_digits - num_digits, '0');
    out = format_decimal<Char>(out, n, num_digits).end;
  }
}

// Format subseconds which are given as a floating point type with an appropiate
// number of digits. We cannot pass the Duration here, as we explicitly need to
// pass the Rep value in the chrono_formatter.
template <typename Duration>
void write_floating_seconds(memory_buffer& buf, Duration duration) {
  FMT_ASSERT(std::is_floating_point<typename Duration::rep>::value, "");
  auto num_fractional_digits =
      count_fractional_digits<Duration::period::num,
                              Duration::period::den>::value;
  // For non-integer values, we ensure at least 6 digits to get microsecond
  // precision.
  auto val = duration.count();
  if (num_fractional_digits < 6 &&
      static_cast<typename Duration::rep>(std::round(val)) != val)
    num_fractional_digits = 6;

  format_to(
      std::back_inserter(buf), runtime("{:.{}f}"),
      std::fmod(val *
                    static_cast<typename Duration::rep>(Duration::period::num) /
                    static_cast<typename Duration::rep>(Duration::period::den),
                static_cast<typename Duration::rep>(60)),
      num_fractional_digits);
}

template <typename OutputIt, typename Char,
          typename Duration = std::chrono::seconds>