From 400b953fbb420ff1e47565303c64223445a51955 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Tue, 4 May 2021 21:04:21 -0700 Subject: [PATCH] Use [] instead of {} in ranges for consistency with Python format --- include/fmt/ranges.h | 15 ++++++++++----- test/ostream-test.cc | 2 +- test/ranges-test.cc | 38 ++++++++++++++++++++------------------ 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 8ff1e762..f04be5ba 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -28,8 +28,13 @@ template struct formatting_base { template struct formatting_range : formatting_base { +#ifdef FMT_DEPRECATED_BRACED_RANGES Char prefix = '{'; Char postfix = '}'; +#else + Char prefix = '['; + Char postfix = ']'; +#endif }; template @@ -66,7 +71,7 @@ OutputIterator copy(wchar_t ch, OutputIterator out) { } /// Return true value if T has std::string interface, like std::string_view. -template class is_like_std_string { +template class is_std_string_like { template static auto check(U* p) -> decltype((void)p->find('a'), p->length(), (void)p->data(), int()); @@ -78,7 +83,7 @@ template class is_like_std_string { }; template -struct is_like_std_string> : std::true_type {}; +struct is_std_string_like> : std::true_type {}; template struct conditional_helper {}; @@ -247,7 +252,7 @@ template OutputIt write_delimiter(OutputIt out) { template < typename Char, typename OutputIt, typename Arg, - FMT_ENABLE_IF(is_like_std_string::type>::value)> + FMT_ENABLE_IF(is_std_string_like::type>::value)> OutputIt write_range_entry(OutputIt out, const Arg& v) { *out++ = '"'; out = write(out, v); @@ -266,7 +271,7 @@ OutputIt write_range_entry(OutputIt out, const Arg v) { template < typename Char, typename OutputIt, typename Arg, - FMT_ENABLE_IF(!is_like_std_string::type>::value && + FMT_ENABLE_IF(!is_std_string_like::type>::value && !std::is_same::value)> OutputIt write_range_entry(OutputIt out, const Arg& v) { return write(out, v); @@ -318,7 +323,7 @@ struct formatter::value>> { template struct is_range { static FMT_CONSTEXPR_DECL const bool value = - detail::is_range_::value && !detail::is_like_std_string::value && + detail::is_range_::value && !detail::is_std_string_like::value && !std::is_convertible>::value && !std::is_constructible, T>::value; }; diff --git a/test/ostream-test.cc b/test/ostream-test.cc index 3bd175fc..15e6b086 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -288,5 +288,5 @@ TEST(ostream_test, to_string) { TEST(ostream_test, range) { auto strs = std::vector{TestString("foo"), TestString("bar")}; - EXPECT_EQ("{foo, bar}", fmt::format("{}", strs)); + EXPECT_EQ("[foo, bar]", fmt::format("{}", strs)); } diff --git a/test/ranges-test.cc b/test/ranges-test.cc index f2e04d7a..64f65e46 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -29,33 +29,33 @@ #ifdef FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY TEST(ranges_test, format_array) { int arr[] = {1, 2, 3, 5, 7, 11}; - EXPECT_EQ(fmt::format("{}", arr), "{1, 2, 3, 5, 7, 11}"); + EXPECT_EQ(fmt::format("{}", arr), "[1, 2, 3, 5, 7, 11]"); } -TEST(ranges_test, format_2d_Array) { +TEST(ranges_test, format_2d_array) { int arr[][2] = {{1, 2}, {3, 5}, {7, 11}}; - EXPECT_EQ(fmt::format("{}", arr), "{{1, 2}, {3, 5}, {7, 11}}"); + EXPECT_EQ(fmt::format("{}", arr), "[[1, 2], [3, 5], [7, 11]]"); } TEST(ranges_test, format_array_of_literals) { const char* arr[] = {"1234", "abcd"}; - EXPECT_EQ(fmt::format("{}", arr), "{\"1234\", \"abcd\"}"); + EXPECT_EQ(fmt::format("{}", arr), "[\"1234\", \"abcd\"]"); } #endif // FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY TEST(ranges_test, format_vector) { auto v = std::vector{1, 2, 3, 5, 7, 11}; - EXPECT_EQ(fmt::format("{}", v), "{1, 2, 3, 5, 7, 11}"); + EXPECT_EQ(fmt::format("{}", v), "[1, 2, 3, 5, 7, 11]"); } TEST(ranges_test, format_vector2) { auto v = std::vector>{{1, 2}, {3, 5}, {7, 11}}; - EXPECT_EQ(fmt::format("{}", v), "{{1, 2}, {3, 5}, {7, 11}}"); + EXPECT_EQ(fmt::format("{}", v), "[[1, 2], [3, 5], [7, 11]]"); } TEST(ranges_test, format_map) { auto m = std::map{{"one", 1}, {"two", 2}}; - EXPECT_EQ(fmt::format("{}", m), "{(\"one\", 1), (\"two\", 2)}"); + EXPECT_EQ(fmt::format("{}", m), "[(\"one\", 1), (\"two\", 2)]"); } TEST(ranges_test, format_pair) { @@ -89,12 +89,14 @@ auto get(const tuple_like& t) noexcept -> decltype(t.get()) { return t.get(); } +namespace std { template <> -struct std::tuple_size : std::integral_constant {}; +struct tuple_size : std::integral_constant {}; -template struct std::tuple_element { +template struct tuple_element { using type = decltype(std::declval().get()); }; +} // namespace std TEST(ranges_test, format_struct) { auto t = tuple_like{42, "foo"}; @@ -106,7 +108,7 @@ TEST(ranges_test, format_to) { char buf[10]; auto end = fmt::format_to(buf, "{}", std::vector{1, 2, 3}); *end = '\0'; - EXPECT_STREQ(buf, "{1, 2, 3}"); + EXPECT_STREQ(buf, "[1, 2, 3]"); } struct path_like { @@ -173,19 +175,19 @@ template class noncopyable_range { TEST(ranges_test, range) { noncopyable_range w(3u, 0); - EXPECT_EQ(fmt::format("{}", w), "{0, 0, 0}"); - EXPECT_EQ(fmt::format("{}", noncopyable_range(3u, 0)), "{0, 0, 0}"); + EXPECT_EQ(fmt::format("{}", w), "[0, 0, 0]"); + EXPECT_EQ(fmt::format("{}", noncopyable_range(3u, 0)), "[0, 0, 0]"); non_const_only_range x(3u, 0); - EXPECT_EQ(fmt::format("{}", x), "{0, 0, 0}"); - EXPECT_EQ(fmt::format("{}", non_const_only_range(3u, 0)), "{0, 0, 0}"); + EXPECT_EQ(fmt::format("{}", x), "[0, 0, 0]"); + EXPECT_EQ(fmt::format("{}", non_const_only_range(3u, 0)), "[0, 0, 0]"); auto y = std::vector(3u, 0); - EXPECT_EQ(fmt::format("{}", y), "{0, 0, 0}"); - EXPECT_EQ(fmt::format("{}", std::vector(3u, 0)), "{0, 0, 0}"); + EXPECT_EQ(fmt::format("{}", y), "[0, 0, 0]"); + EXPECT_EQ(fmt::format("{}", std::vector(3u, 0)), "[0, 0, 0]"); const auto z = std::vector(3u, 0); - EXPECT_EQ(fmt::format("{}", z), "{0, 0, 0}"); + EXPECT_EQ(fmt::format("{}", z), "[0, 0, 0]"); } #if !FMT_MSC_VER || FMT_MSC_VER >= 1927 @@ -241,7 +243,7 @@ struct zstring { TEST(ranges_test, join_sentinel) { auto hello = zstring{"hello"}; - EXPECT_EQ(fmt::format("{}", hello), "{'h', 'e', 'l', 'l', 'o'}"); + EXPECT_EQ(fmt::format("{}", hello), "['h', 'e', 'l', 'l', 'o']"); EXPECT_EQ(fmt::format("{}", fmt::join(hello, "_")), "h_e_l_l_o"); }