llvm.org GIT mirror llvm / b93468a
Add llvm::join_items to StringExtras. llvm::join_items is similar to llvm::join, which produces a string by concatenating a sequence of values together separated by a given separator. But it differs in that the arguments to llvm::join() are same-type members of a container, whereas the arguments to llvm::join_items are arbitrary types passed into a variadic template. The only requirement on parameters to llvm::join_items (including for the separator themselves) is that they be implicitly convertible to std::string or have an overload of std::string::operator+ Differential Revision: https://reviews.llvm.org/D24880 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282502 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 3 years ago
3 changed file(s) with 108 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
154154 /// it if it is not printable or if it is an escape char.
155155 void PrintEscapedString(StringRef Name, raw_ostream &Out);
156156
157 namespace detail {
158
157159 template
158160 inline std::string join_impl(IteratorT Begin, IteratorT End,
159161 StringRef Separator, std::input_iterator_tag) {
188190 return S;
189191 }
190192
193 template
194 inline void join_items_impl(std::string &Result, Sep Separator) {}
195
196 template
197 inline void join_items_impl(std::string &Result, Sep Separator,
198 const Arg &Item) {
199 Result += Item;
200 }
201
202 template
203 inline void join_items_impl(std::string &Result, Sep Separator, const Arg1 &A1,
204 Args &&... Items) {
205 Result += A1;
206 Result += Separator;
207 join_items_impl(Result, Separator, std::forward(Items)...);
208 }
209
210 inline size_t join_one_item_size(char C) { return 1; }
211 inline size_t join_one_item_size(const char *S) { return S ? ::strlen(S) : 0; }
212
213 template inline size_t join_one_item_size(const T &Str) {
214 return Str.size();
215 }
216
217 inline size_t join_items_size() { return 0; }
218
219 template inline size_t join_items_size(const A1 &A) {
220 return join_one_item_size(A);
221 }
222 template
223 inline size_t join_items_size(const A1 &A, Args &&... Items) {
224 return join_one_item_size(A) + join_items_size(std::forward(Items)...);
225 }
226 }
227
191228 /// Joins the strings in the range [Begin, End), adding Separator between
192229 /// the elements.
193230 template
194231 inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
195232 typedef typename std::iterator_traits::iterator_category tag;
196 return join_impl(Begin, End, Separator, tag());
233 return detail::join_impl(Begin, End, Separator, tag());
234 }
235
236 /// Joins the strings in the parameter pack \p Items, adding \p Separator
237 /// between the elements. All arguments must be implicitly convertible to
238 /// std::string, or there should be an overload of std::string::operator+=()
239 /// that accepts the argument explicitly.
240 template
241 inline std::string join_items(Sep Separator, Args &&... Items) {
242 std::string Result;
243 if (sizeof...(Items) == 0)
244 return Result;
245
246 size_t NS = detail::join_one_item_size(Separator);
247 size_t NI = detail::join_items_size(std::forward(Items)...);
248 Result.reserve(NI + (sizeof...(Items) - 1) * NS + 1);
249 detail::join_items_impl(Result, Separator, std::forward(Items)...);
250 return Result;
197251 }
198252
199253 } // End llvm namespace
5252 SparseBitVectorTest.cpp
5353 SparseMultiSetTest.cpp
5454 SparseSetTest.cpp
55 StringExtrasTest.cpp
5556 StringMapTest.cpp
5657 StringRefTest.cpp
5758 TinyPtrVectorTest.cpp
0 //===- StringExtrasTest.cpp - Unit tests for String extras ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/StringExtras.h"
10 #include "gtest/gtest.h"
11
12 using namespace llvm;
13
14 TEST(StringExtrasTest, Join) {
15 std::vector Items;
16 EXPECT_EQ("", join(Items.begin(), Items.end(), " "));
17
18 Items = {"foo"};
19 EXPECT_EQ("foo", join(Items.begin(), Items.end(), " "));
20
21 Items = {"foo", "bar"};
22 EXPECT_EQ("foo bar", join(Items.begin(), Items.end(), " "));
23
24 Items = {"foo", "bar", "baz"};
25 EXPECT_EQ("foo bar baz",
26 join(Items.begin(), Items.end(), " "));
27 }
28
29 TEST(StringExtrasTest, JoinItems) {
30 const char *Foo = "foo";
31 std::string Bar = "bar";
32 llvm::StringRef Baz = "baz";
33 char X = 'x';
34
35 EXPECT_EQ("", join_items(" "));
36 EXPECT_EQ("", join_items('/'));
37
38 EXPECT_EQ("foo", join_items(" ", Foo));
39 EXPECT_EQ("foo", join_items('/', Foo));
40
41 EXPECT_EQ("foo bar", join_items(" ", Foo, Bar));
42 EXPECT_EQ("foo/bar", join_items('/', Foo, Bar));
43
44 EXPECT_EQ("foo bar baz", join_items(" ", Foo, Bar, Baz));
45 EXPECT_EQ("foo/bar/baz", join_items('/', Foo, Bar, Baz));
46
47 EXPECT_EQ("foo bar baz x",
48 join_items(" ", Foo, Bar, Baz, X));
49
50 EXPECT_EQ("foo/bar/baz/x", join_items('/', Foo, Bar, Baz, X));
51 }