Use [] instead of {} in ranges for consistency with Python format

This commit is contained in:
Victor Zverovich
2021-05-04 21:04:21 -07:00
parent 38bcc04a11
commit 400b953fbb
3 changed files with 31 additions and 24 deletions

View File

@@ -28,8 +28,13 @@ template <typename Char> struct formatting_base {
template <typename Char, typename Enable = void> template <typename Char, typename Enable = void>
struct formatting_range : formatting_base<Char> { struct formatting_range : formatting_base<Char> {
#ifdef FMT_DEPRECATED_BRACED_RANGES
Char prefix = '{'; Char prefix = '{';
Char postfix = '}'; Char postfix = '}';
#else
Char prefix = '[';
Char postfix = ']';
#endif
}; };
template <typename Char, typename Enable = void> template <typename Char, typename Enable = void>
@@ -66,7 +71,7 @@ OutputIterator copy(wchar_t ch, OutputIterator out) {
} }
/// Return true value if T has std::string interface, like std::string_view. /// Return true value if T has std::string interface, like std::string_view.
template <typename T> class is_like_std_string { template <typename T> class is_std_string_like {
template <typename U> template <typename U>
static auto check(U* p) static auto check(U* p)
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int()); -> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
@@ -78,7 +83,7 @@ template <typename T> class is_like_std_string {
}; };
template <typename Char> template <typename Char>
struct is_like_std_string<fmt::basic_string_view<Char>> : std::true_type {}; struct is_std_string_like<fmt::basic_string_view<Char>> : std::true_type {};
template <typename... Ts> struct conditional_helper {}; template <typename... Ts> struct conditional_helper {};
@@ -247,7 +252,7 @@ template <typename OutputIt> OutputIt write_delimiter(OutputIt out) {
template < template <
typename Char, typename OutputIt, typename Arg, typename Char, typename OutputIt, typename Arg,
FMT_ENABLE_IF(is_like_std_string<typename std::decay<Arg>::type>::value)> FMT_ENABLE_IF(is_std_string_like<typename std::decay<Arg>::type>::value)>
OutputIt write_range_entry(OutputIt out, const Arg& v) { OutputIt write_range_entry(OutputIt out, const Arg& v) {
*out++ = '"'; *out++ = '"';
out = write<Char>(out, v); out = write<Char>(out, v);
@@ -266,7 +271,7 @@ OutputIt write_range_entry(OutputIt out, const Arg v) {
template < template <
typename Char, typename OutputIt, typename Arg, typename Char, typename OutputIt, typename Arg,
FMT_ENABLE_IF(!is_like_std_string<typename std::decay<Arg>::type>::value && FMT_ENABLE_IF(!is_std_string_like<typename std::decay<Arg>::type>::value &&
!std::is_same<Arg, Char>::value)> !std::is_same<Arg, Char>::value)>
OutputIt write_range_entry(OutputIt out, const Arg& v) { OutputIt write_range_entry(OutputIt out, const Arg& v) {
return write<Char>(out, v); return write<Char>(out, v);
@@ -318,7 +323,7 @@ struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value>> {
template <typename T, typename Char> struct is_range { template <typename T, typename Char> struct is_range {
static FMT_CONSTEXPR_DECL const bool value = static FMT_CONSTEXPR_DECL const bool value =
detail::is_range_<T>::value && !detail::is_like_std_string<T>::value && detail::is_range_<T>::value && !detail::is_std_string_like<T>::value &&
!std::is_convertible<T, std::basic_string<Char>>::value && !std::is_convertible<T, std::basic_string<Char>>::value &&
!std::is_constructible<detail::std_string_view<Char>, T>::value; !std::is_constructible<detail::std_string_view<Char>, T>::value;
}; };

View File

@@ -288,5 +288,5 @@ TEST(ostream_test, to_string) {
TEST(ostream_test, range) { TEST(ostream_test, range) {
auto strs = std::vector<TestString>{TestString("foo"), TestString("bar")}; auto strs = std::vector<TestString>{TestString("foo"), TestString("bar")};
EXPECT_EQ("{foo, bar}", fmt::format("{}", strs)); EXPECT_EQ("[foo, bar]", fmt::format("{}", strs));
} }

View File

@@ -29,33 +29,33 @@
#ifdef FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY #ifdef FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
TEST(ranges_test, format_array) { TEST(ranges_test, format_array) {
int arr[] = {1, 2, 3, 5, 7, 11}; 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}}; 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) { TEST(ranges_test, format_array_of_literals) {
const char* arr[] = {"1234", "abcd"}; 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 #endif // FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
TEST(ranges_test, format_vector) { TEST(ranges_test, format_vector) {
auto v = std::vector<int>{1, 2, 3, 5, 7, 11}; auto v = std::vector<int>{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) { TEST(ranges_test, format_vector2) {
auto v = std::vector<std::vector<int>>{{1, 2}, {3, 5}, {7, 11}}; auto v = std::vector<std::vector<int>>{{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) { TEST(ranges_test, format_map) {
auto m = std::map<std::string, int>{{"one", 1}, {"two", 2}}; auto m = std::map<std::string, int>{{"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) { TEST(ranges_test, format_pair) {
@@ -89,12 +89,14 @@ auto get(const tuple_like& t) noexcept -> decltype(t.get<N>()) {
return t.get<N>(); return t.get<N>();
} }
namespace std {
template <> template <>
struct std::tuple_size<tuple_like> : std::integral_constant<size_t, 2> {}; struct tuple_size<tuple_like> : std::integral_constant<size_t, 2> {};
template <size_t N> struct std::tuple_element<N, tuple_like> { template <size_t N> struct tuple_element<N, tuple_like> {
using type = decltype(std::declval<tuple_like>().get<N>()); using type = decltype(std::declval<tuple_like>().get<N>());
}; };
} // namespace std
TEST(ranges_test, format_struct) { TEST(ranges_test, format_struct) {
auto t = tuple_like{42, "foo"}; auto t = tuple_like{42, "foo"};
@@ -106,7 +108,7 @@ TEST(ranges_test, format_to) {
char buf[10]; char buf[10];
auto end = fmt::format_to(buf, "{}", std::vector<int>{1, 2, 3}); auto end = fmt::format_to(buf, "{}", std::vector<int>{1, 2, 3});
*end = '\0'; *end = '\0';
EXPECT_STREQ(buf, "{1, 2, 3}"); EXPECT_STREQ(buf, "[1, 2, 3]");
} }
struct path_like { struct path_like {
@@ -173,19 +175,19 @@ template <typename T> class noncopyable_range {
TEST(ranges_test, range) { TEST(ranges_test, range) {
noncopyable_range<int> w(3u, 0); noncopyable_range<int> w(3u, 0);
EXPECT_EQ(fmt::format("{}", w), "{0, 0, 0}"); EXPECT_EQ(fmt::format("{}", w), "[0, 0, 0]");
EXPECT_EQ(fmt::format("{}", noncopyable_range<int>(3u, 0)), "{0, 0, 0}"); EXPECT_EQ(fmt::format("{}", noncopyable_range<int>(3u, 0)), "[0, 0, 0]");
non_const_only_range<int> x(3u, 0); non_const_only_range<int> x(3u, 0);
EXPECT_EQ(fmt::format("{}", x), "{0, 0, 0}"); EXPECT_EQ(fmt::format("{}", x), "[0, 0, 0]");
EXPECT_EQ(fmt::format("{}", non_const_only_range<int>(3u, 0)), "{0, 0, 0}"); EXPECT_EQ(fmt::format("{}", non_const_only_range<int>(3u, 0)), "[0, 0, 0]");
auto y = std::vector<int>(3u, 0); auto y = std::vector<int>(3u, 0);
EXPECT_EQ(fmt::format("{}", y), "{0, 0, 0}"); EXPECT_EQ(fmt::format("{}", y), "[0, 0, 0]");
EXPECT_EQ(fmt::format("{}", std::vector<int>(3u, 0)), "{0, 0, 0}"); EXPECT_EQ(fmt::format("{}", std::vector<int>(3u, 0)), "[0, 0, 0]");
const auto z = std::vector<int>(3u, 0); const auto z = std::vector<int>(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 #if !FMT_MSC_VER || FMT_MSC_VER >= 1927
@@ -241,7 +243,7 @@ struct zstring {
TEST(ranges_test, join_sentinel) { TEST(ranges_test, join_sentinel) {
auto hello = zstring{"hello"}; 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"); EXPECT_EQ(fmt::format("{}", fmt::join(hello, "_")), "h_e_l_l_o");
} }