diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h --- a/llvm/include/llvm/ADT/StringExtras.h +++ b/llvm/include/llvm/ADT/StringExtras.h @@ -312,23 +312,36 @@ std::string convertToCamelFromSnakeCase(StringRef input, bool capitalizeFirst = false); -namespace detail { - -template -inline std::string join_impl(IteratorT Begin, IteratorT End, - StringRef Separator, std::input_iterator_tag) { +template +inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator, + UnaryFunction F) { std::string S; if (Begin == End) return S; - S += (*Begin); + S += F(*Begin); while (++Begin != End) { S += Separator; - S += (*Begin); + S += F(*Begin); } return S; } +/// Joins the strings in the range [R.begin(), R.end()), adding Separator +/// between the elements. +template +inline std::string join(Range &&R, StringRef Separator, UnaryFunction F) { + return join(R.begin(), R.end(), Separator, F); +} + +namespace detail { + +template +inline std::string join_impl(IteratorT Begin, IteratorT End, + StringRef Separator, std::input_iterator_tag) { + return join(Begin, End, Separator, [](auto &&S) { return std::forward(S); }); +} + template inline std::string join_impl(IteratorT Begin, IteratorT End, StringRef Separator, std::forward_iterator_tag) { diff --git a/llvm/unittests/ADT/StringExtrasTest.cpp b/llvm/unittests/ADT/StringExtrasTest.cpp --- a/llvm/unittests/ADT/StringExtrasTest.cpp +++ b/llvm/unittests/ADT/StringExtrasTest.cpp @@ -47,6 +47,19 @@ Items = {"foo", "bar", "baz"}; EXPECT_EQ("foo bar baz", join(Items.begin(), Items.end(), " ")); + + std::vector Integers = {1, 2, 3}; + EXPECT_EQ("1 2 3", + join(Integers.begin(), Integers.end(), " ", + [](auto I) { return StringRef(utostr(I)); })); + + Integers = {4, 5, 6}; + EXPECT_EQ("4 5 6", join(Integers, " ", [](auto I) { + return StringRef(utostr(I)); + })); + EXPECT_EQ("4 5 6", + join(std::move(Integers), " ", + [](auto I) { return StringRef(utostr(I)); })); } TEST(StringExtrasTest, JoinItems) {