Refactor chrono formatting
This commit is contained in:
parent
b955e7a6b2
commit
35a2c2a743
@ -288,20 +288,18 @@ inline null<> localtime_s(...) { return null<>(); }
|
|||||||
inline null<> gmtime_r(...) { return null<>(); }
|
inline null<> gmtime_r(...) { return null<>(); }
|
||||||
inline null<> gmtime_s(...) { return null<>(); }
|
inline null<> gmtime_s(...) { return null<>(); }
|
||||||
|
|
||||||
template <typename OutputIt>
|
inline auto do_write(const std::tm& time, const std::locale& loc, char format,
|
||||||
OutputIt write(OutputIt out, const std::tm& time, const std::locale& loc,
|
char modifier) -> std::string {
|
||||||
char format, char modifier = 0) {
|
|
||||||
auto&& os = std::ostringstream();
|
auto&& os = std::ostringstream();
|
||||||
using iterator = std::ostreambuf_iterator<char>;
|
using iterator = std::ostreambuf_iterator<char>;
|
||||||
const auto& facet = std::use_facet<std::time_put<char, iterator>>(loc);
|
const auto& facet = std::use_facet<std::time_put<char, iterator>>(loc);
|
||||||
auto end = facet.put(os, os, ' ', &time, format, modifier);
|
auto end = facet.put(os, os, ' ', &time, format, modifier);
|
||||||
if (end.failed()) FMT_THROW(format_error("failed to format time"));
|
if (end.failed()) FMT_THROW(format_error("failed to format time"));
|
||||||
auto str = os.str();
|
auto str = os.str();
|
||||||
if (detail::is_utf8() && loc != std::locale::classic()) {
|
if (!detail::is_utf8() || loc == std::locale::classic()) return str;
|
||||||
// char16_t and char32_t codecvts are broken in MSVC (linkage errors).
|
// char16_t and char32_t codecvts are broken in MSVC (linkage errors).
|
||||||
using code_unit = conditional_t<FMT_MSC_VER, wchar_t, char16_t>;
|
using code_unit = conditional_t<FMT_MSC_VER, wchar_t, char16_t>;
|
||||||
auto& f =
|
auto& f = std::use_facet<std::codecvt<code_unit, char, std::mbstate_t>>(loc);
|
||||||
std::use_facet<std::codecvt<code_unit, char, std::mbstate_t>>(loc);
|
|
||||||
auto mb = std::mbstate_t();
|
auto mb = std::mbstate_t();
|
||||||
const char* from_next = nullptr;
|
const char* from_next = nullptr;
|
||||||
code_unit* to_next = nullptr;
|
code_unit* to_next = nullptr;
|
||||||
@ -313,7 +311,7 @@ OutputIt write(OutputIt out, const std::tm& time, const std::locale& loc,
|
|||||||
FMT_THROW(format_error("failed to format time"));
|
FMT_THROW(format_error("failed to format time"));
|
||||||
str.clear();
|
str.clear();
|
||||||
for (code_unit* p = buf; p != to_next; ++p) {
|
for (code_unit* p = buf; p != to_next; ++p) {
|
||||||
code_unit c = *p;
|
auto c = *p;
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
str.push_back(static_cast<char>(c));
|
str.push_back(static_cast<char>(c));
|
||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
@ -323,7 +321,13 @@ OutputIt write(OutputIt out, const std::tm& time, const std::locale& loc,
|
|||||||
FMT_THROW(format_error("failed to format time"));
|
FMT_THROW(format_error("failed to format time"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt>
|
||||||
|
auto write(OutputIt out, const std::tm& time, const std::locale& loc,
|
||||||
|
char format, char modifier = 0) -> OutputIt {
|
||||||
|
auto str = do_write(time, loc, format, modifier);
|
||||||
return std::copy(str.begin(), str.end(), out);
|
return std::copy(str.begin(), str.end(), out);
|
||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
@ -376,13 +376,14 @@ TEST(chrono_test, unsigned_duration) {
|
|||||||
EXPECT_EQ("42s", fmt::format("{}", std::chrono::duration<unsigned>(42)));
|
EXPECT_EQ("42s", fmt::format("{}", std::chrono::duration<unsigned>(42)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(chrono_test, format_weekday) {
|
TEST(chrono_test, weekday) {
|
||||||
auto loc = get_locale("ru_RU.UTF-8");
|
auto loc = get_locale("ru_RU.UTF-8");
|
||||||
std::locale::global(loc);
|
std::locale::global(loc);
|
||||||
EXPECT_EQ(fmt::format("{}", fmt::weekday(1)), "Mon");
|
auto mon = fmt::weekday(1);
|
||||||
|
EXPECT_EQ(fmt::format("{}", mon), "Mon");
|
||||||
if (loc != std::locale::classic()) {
|
if (loc != std::locale::classic()) {
|
||||||
EXPECT_THAT((std::vector<std::string>{"пн", "Пн"}),
|
EXPECT_THAT((std::vector<std::string>{"пн", "Пн"}),
|
||||||
Contains(fmt::format(loc, "{:L}", fmt::weekday(1))));
|
Contains(fmt::format(loc, "{:L}", mon)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user