From 6c87e3424e9d4c126e0cc4bc4c6fa11f2b84336c Mon Sep 17 00:00:00 2001 From: olivier80 Date: Sun, 5 Feb 2017 22:41:29 +0100 Subject: [PATCH 1/6] Add join argument allowing formating list of values separated by a string. Each value is formated according the format specifier. --- fmt/format.h | 73 +++++++++++++++++++++++++++++++++++++++++++++ test/format-test.cc | 21 +++++++++++++ 2 files changed, 94 insertions(+) diff --git a/fmt/format.h b/fmt/format.h index 1f5fa26b0f73..4b8ba4e344e5 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -3865,6 +3865,79 @@ void BasicFormatter::format(BasicCStringRef format_str) { } write(writer_, start, s); } + + +template +struct ArgJoin +{ + It first; + It last; + BasicCStringRef sep; + + ArgJoin(It first, It last, const BasicCStringRef& sep) : + first(first), + last(last), + sep(sep) + { + } +}; + +template +ArgJoin join(It first, It last, const BasicCStringRef& sep) +{ + return ArgJoin(first, last, sep); +} + +template +ArgJoin join(It first, It last, const BasicCStringRef& sep) +{ + return ArgJoin(first, last, sep); +} + +#if FMT_HAS_GXX_CXX11 +template +auto join(const Range& range, const BasicCStringRef& sep) -> ArgJoin +{ + return join(std::begin(range), std::end(range), sep); +} + +template +auto join(const Range& range, const BasicCStringRef& sep) -> ArgJoin +{ + return join(std::begin(range), std::end(range), sep); +} +#endif + + +template +void format_arg(fmt::BasicFormatter &f, + const Char *&format_str, const ArgJoin& e) { + const Char* end = format_str; + if (*end == ':') + ++end; + while (*end && *end != '}') + ++end; + if (*end != '}') + FMT_THROW(FormatError("missing '}' in format string")); + + It it = e.first; + if (it != e.last) + { + const Char* save = format_str; + f.format(format_str, internal::MakeArg>(*it++)); + while (it != e.last) + { + f.writer().write(e.sep); + format_str = save; + f.format(format_str, internal::MakeArg>(*it++)); + } + } + format_str = end + 1; +} + + + + } // namespace fmt #if FMT_USE_USER_DEFINED_LITERALS diff --git a/test/format-test.cc b/test/format-test.cc index 6d4a8fcd22b1..f4b0fc067e18 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1552,6 +1552,27 @@ TEST(FormatTest, Variadic) { EXPECT_EQ(L"abc1", format(L"{}c{}", L"ab", 1)); } +TEST(FormatTest, JoinArg) { + using fmt::join; + int v1[] { 1, 2, 3 }; + std::vector v2; + v2.push_back(1.2); + v2.push_back(3.4); + + EXPECT_EQ("(1, 2, 3)", format("({})", join(v1 + 0, v1 + 3, ", "))); + EXPECT_EQ("(1)", format("({})", join(v1 + 0, v1 + 1, ", "))); + EXPECT_EQ("()", format("({})", join(v1 + 0, v1 + 0, ", "))); + EXPECT_EQ("(001, 002, 003)", format("({:03})", join(v1 + 0, v1 + 3, ", "))); + EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2.begin(), v2.end(), ", "))); + + EXPECT_EQ(L"(1, 2, 3)", format(L"({})", join(v1 + 0, v1 + 3, L", "))); + +#if FMT_HAS_GXX_CXX11 + EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, ", "))); + EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2, ", "))); +#endif +} + template std::string str(const T &value) { return fmt::format("{}", value); From 7bc91f856bab4a1c212f802ecd1f5d04b34afc2b Mon Sep 17 00:00:00 2001 From: olivier80 Date: Sun, 5 Feb 2017 23:00:15 +0100 Subject: [PATCH 2/6] fix template >> without c++11. --- fmt/format.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fmt/format.h b/fmt/format.h index 4b8ba4e344e5..038bfd941879 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -3924,12 +3924,12 @@ void format_arg(fmt::BasicFormatter &f, if (it != e.last) { const Char* save = format_str; - f.format(format_str, internal::MakeArg>(*it++)); + f.format(format_str, internal::MakeArg >(*it++)); while (it != e.last) { f.writer().write(e.sep); format_str = save; - f.format(format_str, internal::MakeArg>(*it++)); + f.format(format_str, internal::MakeArg >(*it++)); } } format_str = end + 1; From 61a1ab27dd1d893898e9552bab352ebc39af87be Mon Sep 17 00:00:00 2001 From: olivier80 Date: Sun, 5 Feb 2017 23:11:11 +0100 Subject: [PATCH 3/6] fix array initialization (c++98) --- test/format-test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/format-test.cc b/test/format-test.cc index f4b0fc067e18..e0d3ea740e2c 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1554,7 +1554,7 @@ TEST(FormatTest, Variadic) { TEST(FormatTest, JoinArg) { using fmt::join; - int v1[] { 1, 2, 3 }; + int v1[3] = { 1, 2, 3 }; std::vector v2; v2.push_back(1.2); v2.push_back(3.4); From 74b1f38715afec8112e830a491a0bacc193ef5d8 Mon Sep 17 00:00:00 2001 From: olivier80 Date: Sun, 5 Feb 2017 23:18:12 +0100 Subject: [PATCH 4/6] fix coding conventions. --- fmt/format.h | 80 ++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/fmt/format.h b/fmt/format.h index 038bfd941879..fd8fc657b462 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -3870,69 +3870,63 @@ void BasicFormatter::format(BasicCStringRef format_str) { template struct ArgJoin { - It first; - It last; - BasicCStringRef sep; - - ArgJoin(It first, It last, const BasicCStringRef& sep) : - first(first), - last(last), - sep(sep) - { - } + It first; + It last; + BasicCStringRef sep; + + ArgJoin(It first, It last, const BasicCStringRef& sep) : + first(first), + last(last), + sep(sep) {} }; template -ArgJoin join(It first, It last, const BasicCStringRef& sep) -{ - return ArgJoin(first, last, sep); +ArgJoin join(It first, It last, const BasicCStringRef& sep) { + return ArgJoin(first, last, sep); } template -ArgJoin join(It first, It last, const BasicCStringRef& sep) -{ - return ArgJoin(first, last, sep); +ArgJoin join(It first, It last, const BasicCStringRef& sep) { + return ArgJoin(first, last, sep); } #if FMT_HAS_GXX_CXX11 template -auto join(const Range& range, const BasicCStringRef& sep) -> ArgJoin -{ - return join(std::begin(range), std::end(range), sep); +auto join(const Range& range, const BasicCStringRef& sep) + -> ArgJoin { + return join(std::begin(range), std::end(range), sep); } template -auto join(const Range& range, const BasicCStringRef& sep) -> ArgJoin -{ - return join(std::begin(range), std::end(range), sep); +auto join(const Range& range, const BasicCStringRef& sep) + -> ArgJoin { + return join(std::begin(range), std::end(range), sep); } #endif template void format_arg(fmt::BasicFormatter &f, - const Char *&format_str, const ArgJoin& e) { - const Char* end = format_str; - if (*end == ':') - ++end; - while (*end && *end != '}') - ++end; - if (*end != '}') - FMT_THROW(FormatError("missing '}' in format string")); - - It it = e.first; - if (it != e.last) - { - const Char* save = format_str; + const Char *&format_str, const ArgJoin& e) { + const Char* end = format_str; + if (*end == ':') + ++end; + while (*end && *end != '}') + ++end; + if (*end != '}') + FMT_THROW(FormatError("missing '}' in format string")); + + It it = e.first; + if (it != e.last) { + const Char* save = format_str; + f.format(format_str, internal::MakeArg >(*it++)); + while (it != e.last) { + f.writer().write(e.sep); + format_str = save; f.format(format_str, internal::MakeArg >(*it++)); - while (it != e.last) - { - f.writer().write(e.sep); - format_str = save; - f.format(format_str, internal::MakeArg >(*it++)); - } - } - format_str = end + 1; + } + } + format_str = end + 1; } From 6c092d5dc4fab4891dfd3ae1ce55242a42273661 Mon Sep 17 00:00:00 2001 From: olivier80 Date: Mon, 6 Feb 2017 08:27:49 +0100 Subject: [PATCH 5/6] fix brace position. --- fmt/format.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fmt/format.h b/fmt/format.h index fd8fc657b462..05de09c8386a 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -3868,8 +3868,7 @@ void BasicFormatter::format(BasicCStringRef format_str) { template -struct ArgJoin -{ +struct ArgJoin { It first; It last; BasicCStringRef sep; From 19cc6651ddd8a9c2e035c91565450166136e8a99 Mon Sep 17 00:00:00 2001 From: olivier80 Date: Tue, 7 Feb 2017 16:55:30 +0100 Subject: [PATCH 6/6] remove extra empty lines. --- fmt/format.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/fmt/format.h b/fmt/format.h index 05de09c8386a..ea49eef0f9e7 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -3866,7 +3866,6 @@ void BasicFormatter::format(BasicCStringRef format_str) { write(writer_, start, s); } - template struct ArgJoin { It first; @@ -3903,7 +3902,6 @@ auto join(const Range& range, const BasicCStringRef& sep) } #endif - template void format_arg(fmt::BasicFormatter &f, const Char *&format_str, const ArgJoin& e) { @@ -3927,10 +3925,6 @@ void format_arg(fmt::BasicFormatter &f, } format_str = end + 1; } - - - - } // namespace fmt #if FMT_USE_USER_DEFINED_LITERALS