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

Code before:
}
}  // namespace safe_duration_cast
#endif

// Prevents expansion of a preceding token as a function-style macro.
// Usage: f FMT_NOMACRO()
#define FMT_NOMACRO

namespace detail {
template <typename T = void> struct null {};
inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
inline null<> localtime_s(...) { return null<>(); }
inline null<> gmtime_r(...) { return null<>(); }
inline null<> gmtime_s(...) { return null<>(); }

template <typename Char>
inline auto do_write(const std::tm& time, const std::locale& loc, char format,
                     char modifier)
    -> decltype(std::basic_ostringstream<Char>().str()) {
  auto&& os = std::basic_ostringstream<Char>();
  os.imbue(loc);
  using iterator = std::ostreambuf_iterator<Char>;
  const auto& facet = std::use_facet<std::time_put<Char, iterator>>(loc);
  auto end = facet.put(os, os, Char(' '), &time, format, modifier);
  if (end.failed()) FMT_THROW(format_error("failed to format time"));
  return os.str();
}

template <typename Char, typename OutputIt>
auto write(Char, OutputIt out, const std::tm& time, const std::locale& loc,
           char format, char modifier = 0) -> OutputIt {
  auto str = do_write<Char>(time, loc, format, modifier);
  return std::copy(str.begin(), str.end(), out);
}

template <typename OutputIt>
auto write(char, OutputIt out, const std::tm& time, const std::locale& loc,
           char format, char modifier = 0) -> OutputIt {
  auto str = do_write<char>(time, loc, format, modifier);
  if (detail::is_utf8() && loc != std::locale::classic()) {
    // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and
    // gcc-4.
#if FMT_MSC_VER != 0 || \
    (defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI))
    // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5
    // and newer.
    using code_unit = wchar_t;
#else
    using code_unit = char32_t;
#endif


Review comment (suggestion):
Should be
```c++
return std::move(os).str();
```
to support moving the string out of the stream [in C++20](https://en.cppreference.com/w/cpp/io/basic_stringstream/str).

Code after:
}
}  // namespace safe_duration_cast
#endif

// Prevents expansion of a preceding token as a function-style macro.
// Usage: f FMT_NOMACRO()
#define FMT_NOMACRO

namespace detail {
template <typename T = void> struct null {};
inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
inline null<> localtime_s(...) { return null<>(); }
inline null<> gmtime_r(...) { return null<>(); }
inline null<> gmtime_s(...) { return null<>(); }

template <typename Char>
inline auto do_write(const std::tm& time, const std::locale& loc, char format,
                     char modifier) -> std::basic_string<Char> {
  auto&& os = std::basic_ostringstream<Char>();
  os.imbue(loc);
  using iterator = std::ostreambuf_iterator<Char>;
  const auto& facet = std::use_facet<std::time_put<Char, iterator>>(loc);
  auto end = facet.put(os, os, Char(' '), &time, format, modifier);
  if (end.failed()) FMT_THROW(format_error("failed to format time"));
  return std::move(os).str();
}

template <typename Char, typename OutputIt,
          FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
auto write(OutputIt out, const std::tm& time, const std::locale& loc,
           char format, char modifier = 0) -> OutputIt {
  auto str = do_write<Char>(time, loc, format, modifier);
  return std::copy(str.begin(), str.end(), out);
}

template <typename Char, typename OutputIt,
          FMT_ENABLE_IF(std::is_same<Char, char>::value)>
auto write(OutputIt out, const std::tm& time, const std::locale& loc,
           char format, char modifier = 0) -> OutputIt {
  auto str = do_write<char>(time, loc, format, modifier);
  if (detail::is_utf8() && loc != std::locale::classic()) {
    // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and
    // gcc-4.
#if FMT_MSC_VER != 0 || \
    (defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI))
    // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5
    // and newer.
    using code_unit = wchar_t;
#else
    using code_unit = char32_t;
#endif