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>
struct formatting_range : formatting_base<Char> {
#ifdef FMT_DEPRECATED_BRACED_RANGES
Char prefix = '{';
Char postfix = '}';
#else
Char prefix = '[';
Char postfix = ']';
#endif
};
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.
template <typename T> class is_like_std_string {
template <typename T> class is_std_string_like {
template <typename U>
static auto check(U* p)
-> 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>
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 {};
@ -247,7 +252,7 @@ template <typename OutputIt> OutputIt write_delimiter(OutputIt out) {
template <
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) {
*out++ = '"';
out = write<Char>(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<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)>
OutputIt write_range_entry(OutputIt out, const Arg& 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 {
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_constructible<detail::std_string_view<Char>, T>::value;
};

View File

@ -288,5 +288,5 @@ TEST(ostream_test, to_string) {
TEST(ostream_test, range) {
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
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<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) {
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) {
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) {
@ -89,12 +89,14 @@ auto get(const tuple_like& t) noexcept -> decltype(t.get<N>()) {
return t.get<N>();
}
namespace std {
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>());
};
} // 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<int>{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 <typename T> class noncopyable_range {
TEST(ranges_test, range) {
noncopyable_range<int> w(3u, 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("{}", w), "[0, 0, 0]");
EXPECT_EQ(fmt::format("{}", noncopyable_range<int>(3u, 0)), "[0, 0, 0]");
non_const_only_range<int> x(3u, 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("{}", x), "[0, 0, 0]");
EXPECT_EQ(fmt::format("{}", non_const_only_range<int>(3u, 0)), "[0, 0, 0]");
auto y = std::vector<int>(3u, 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("{}", y), "[0, 0, 0]");
EXPECT_EQ(fmt::format("{}", std::vector<int>(3u, 0)), "[0, 0, 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
@ -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");
}