diff --git a/include/fmt/format.h b/include/fmt/format.h index 32b42dd54c54..ee01391c98cd 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3720,7 +3720,7 @@ struct formatter, Char> { private: using value_type = typename std::iterator_traits::value_type; using formatter_type = - conditional_t::value, + conditional_t>::value, formatter, detail::fallback_formatter>; diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 0ebf96526442..4c04f9ea34a7 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -67,6 +67,12 @@ OutputIterator copy(char ch, OutputIterator out) { return out; } +template +OutputIterator copy(wchar_t ch, OutputIterator out) { + *out++ = ch; + return out; +} + /// Return true value if T has std::string interface, like std::string_view. template class is_like_std_string { template diff --git a/test/ranges-test.cc b/test/ranges-test.cc index 30ed97f21233..8fee3e14e6b8 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -224,6 +224,25 @@ TEST(RangesTest, JoinTuple) { EXPECT_EQ("4", fmt::format("{}", fmt::join(t4, "/"))); } +TEST(RangesTest, WideStringJoinTuple) { + // Value tuple args + std::tuple t1 = std::make_tuple('a', 1, 2.0f); + EXPECT_EQ(L"(a, 1, 2)", fmt::format(L"({})", fmt::join(t1, L", "))); + + // Testing lvalue tuple args + int x = 4; + std::tuple t2{'b', x}; + EXPECT_EQ(L"b + 4", fmt::format(L"{}", fmt::join(t2, L" + "))); + + // Empty tuple + std::tuple<> t3; + EXPECT_EQ(L"", fmt::format(L"{}", fmt::join(t3, L"|"))); + + // Single element tuple + std::tuple t4{4.0f}; + EXPECT_EQ(L"4", fmt::format(L"{}", fmt::join(t4, L"/"))); +} + TEST(RangesTest, JoinInitializerList) { EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join({1, 2, 3}, ", "))); EXPECT_EQ("fmt rocks !",