/Users/deen/code/yugabyte-db/src/yb/gutil/strings/join.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2008 and onwards Google, Inc. |
2 | | // |
3 | | // #status: RECOMMENDED |
4 | | // #category: operations on strings |
5 | | // #summary: Functions for joining strings and numbers using a delimiter. |
6 | | // |
7 | | // The following only applies to changes made to this file as part of YugaByte development. |
8 | | // |
9 | | // Portions Copyright (c) YugaByte, Inc. |
10 | | // |
11 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
12 | | // in compliance with the License. You may obtain a copy of the License at |
13 | | // |
14 | | // http://www.apache.org/licenses/LICENSE-2.0 |
15 | | // |
16 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
17 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
18 | | // or implied. See the License for the specific language governing permissions and limitations |
19 | | // under the License. |
20 | | // |
21 | | #ifndef YB_GUTIL_STRINGS_JOIN_H |
22 | | #define YB_GUTIL_STRINGS_JOIN_H |
23 | | |
24 | | #include <stdio.h> |
25 | | #include <string.h> |
26 | | |
27 | | #include <map> |
28 | | #include <set> |
29 | | #include <string> |
30 | | #include <vector> |
31 | | |
32 | | #include "yb/gutil/integral_types.h" |
33 | | #include "yb/gutil/macros.h" |
34 | | #include "yb/gutil/strings/numbers.h" |
35 | | #include "yb/gutil/strings/strcat.h" // For backward compatibility. |
36 | | #include "yb/gutil/strings/stringpiece.h" |
37 | | |
38 | | using std::back_insert_iterator; |
39 | | using std::iterator_traits; |
40 | | using std::map; |
41 | | using std::multimap; |
42 | | using std::multiset; |
43 | | using std::set; |
44 | | using std::string; |
45 | | using std::make_pair; |
46 | | using std::pair; |
47 | | using std::vector; |
48 | | |
49 | | |
50 | | // ---------------------------------------------------------------------- |
51 | | // JoinUsing() |
52 | | // This concatenates a vector of strings "components" into a new char[] |
53 | | // buffer, using the C-string "delim" as a separator between components. |
54 | | // |
55 | | // This is essentially the same as JoinUsingToBuffer except |
56 | | // the return result is dynamically allocated using "new char[]". |
57 | | // It is the caller's responsibility to "delete []" the char* that is |
58 | | // returned. |
59 | | // |
60 | | // If result_length_p is not NULL, it will contain the length of the |
61 | | // result string (not including the trailing '\0'). |
62 | | // ---------------------------------------------------------------------- |
63 | | char* JoinUsing(const vector<const char*>& components, |
64 | | const char* delim, |
65 | | size_t* result_length_p); |
66 | | |
67 | | // ---------------------------------------------------------------------- |
68 | | // JoinUsingToBuffer() |
69 | | // This concatenates a vector of strings "components" into a given char[] |
70 | | // buffer, using the C-string "delim" as a separator between components. |
71 | | // User supplies the result buffer with specified buffer size. |
72 | | // The result is also returned for convenience. |
73 | | // |
74 | | // If result_length_p is not NULL, it will contain the length of the |
75 | | // result string (not including the trailing '\0'). |
76 | | // ---------------------------------------------------------------------- |
77 | | char* JoinUsingToBuffer(const vector<const char*>& components, |
78 | | const char* delim, |
79 | | size_t result_buffer_size, |
80 | | char* result_buffer, |
81 | | size_t* result_length_p); |
82 | | |
83 | | // ---------------------------------------------------------------------- |
84 | | // JoinStrings(), JoinStringsIterator(), JoinStringsInArray() |
85 | | // |
86 | | // JoinStrings concatenates a container of strings into a C++ string, |
87 | | // using the string "delim" as a separator between components. |
88 | | // "components" can be any sequence container whose values are C++ strings |
89 | | // or GStringPieces. More precisely, "components" must support STL container |
90 | | // iteration; i.e. it must have begin() and end() methods with appropriate |
91 | | // semantics, which return forward iterators whose value type is |
92 | | // string or GStringPiece. Repeated string fields of protocol messages |
93 | | // satisfy these requirements. |
94 | | // |
95 | | // JoinStringsIterator is the same as JoinStrings, except that the input |
96 | | // strings are specified with a pair of iterators. The requirements on |
97 | | // the iterators are the same as the requirements on components.begin() |
98 | | // and components.end() for JoinStrings. |
99 | | // |
100 | | // JoinStringsInArray is the same as JoinStrings, but operates on |
101 | | // an array of C++ strings or string pointers. |
102 | | // |
103 | | // There are two flavors of each function, one flavor returns the |
104 | | // concatenated string, another takes a pointer to the target string. In |
105 | | // the latter case the target string is cleared and overwritten. |
106 | | // ---------------------------------------------------------------------- |
107 | | template <class CONTAINER> |
108 | | void JoinStrings(const CONTAINER& components, |
109 | | const GStringPiece& delim, |
110 | | string* result); |
111 | | template <class CONTAINER> |
112 | | string JoinStrings(const CONTAINER& components, |
113 | | const GStringPiece& delim); |
114 | | |
115 | | template <class ITERATOR> |
116 | | void JoinStringsIterator(const ITERATOR& start, |
117 | | const ITERATOR& end, |
118 | | const GStringPiece& delim, |
119 | | string* result); |
120 | | template <class ITERATOR> |
121 | | string JoinStringsIterator(const ITERATOR& start, |
122 | | const ITERATOR& end, |
123 | | const GStringPiece& delim); |
124 | | |
125 | | // Join the keys of a map using the specified delimiter. |
126 | | template<typename ITERATOR> |
127 | | void JoinKeysIterator(const ITERATOR& start, |
128 | | const ITERATOR& end, |
129 | | const GStringPiece& delim, |
130 | 1 | string *result) { |
131 | 1 | result->clear(); |
132 | 6 | for (ITERATOR iter = start; iter != end; ++iter) { |
133 | 5 | if (iter == start) { |
134 | 1 | StrAppend(result, iter->first); |
135 | 4 | } else { |
136 | 4 | StrAppend(result, delim, iter->first); |
137 | 4 | } |
138 | 5 | } |
139 | 1 | } |
140 | | |
141 | | template <typename ITERATOR> |
142 | | string JoinKeysIterator(const ITERATOR& start, |
143 | | const ITERATOR& end, |
144 | 1 | const GStringPiece& delim) { |
145 | 1 | string result; |
146 | 1 | JoinKeysIterator(start, end, delim, &result); |
147 | 1 | return result; |
148 | 1 | } |
149 | | |
150 | | // Join the keys and values of a map using the specified delimiters. |
151 | | template<typename ITERATOR> |
152 | | void JoinKeysAndValuesIterator(const ITERATOR& start, |
153 | | const ITERATOR& end, |
154 | | const GStringPiece& intra_delim, |
155 | | const GStringPiece& inter_delim, |
156 | 0 | string *result) { |
157 | 0 | result->clear(); |
158 | 0 | for (ITERATOR iter = start; iter != end; ++iter) { |
159 | 0 | if (iter == start) { |
160 | 0 | StrAppend(result, iter->first, intra_delim, iter->second); |
161 | 0 | } else { |
162 | 0 | StrAppend(result, inter_delim, iter->first, intra_delim, iter->second); |
163 | 0 | } |
164 | 0 | } |
165 | 0 | } Unexecuted instantiation: _Z25JoinKeysAndValuesIteratorINSt3__120__map_const_iteratorINS0_21__tree_const_iteratorINS0_12__value_typeINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES9_EEPNS0_11__tree_nodeISA_PvEElEEEEEvRKT_SJ_RK12GStringPieceSM_PS9_ Unexecuted instantiation: _Z25JoinKeysAndValuesIteratorINSt3__111__wrap_iterIPKNS0_4pairINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_EEEEEvRKT_SF_RK12GStringPieceSI_PS8_ |
166 | | |
167 | | template <typename ITERATOR> |
168 | | string JoinKeysAndValuesIterator(const ITERATOR& start, |
169 | | const ITERATOR& end, |
170 | | const GStringPiece& intra_delim, |
171 | | const GStringPiece& inter_delim) { |
172 | | string result; |
173 | | JoinKeysAndValuesIterator(start, end, intra_delim, inter_delim, &result); |
174 | | return result; |
175 | | } |
176 | | |
177 | | void JoinStringsInArray(string const* const* components, |
178 | | size_t num_components, |
179 | | const char* delim, |
180 | | string* result); |
181 | | void JoinStringsInArray(string const* components, |
182 | | size_t num_components, |
183 | | const char* delim, |
184 | | string* result); |
185 | | string JoinStringsInArray(string const* const* components, |
186 | | size_t num_components, |
187 | | const char* delim); |
188 | | string JoinStringsInArray(string const* components, |
189 | | size_t num_components, |
190 | | const char* delim); |
191 | | |
192 | | // ---------------------------------------------------------------------- |
193 | | // Definitions of above JoinStrings* methods |
194 | | // ---------------------------------------------------------------------- |
195 | | template <class CONTAINER> |
196 | | inline void JoinStrings(const CONTAINER& components, |
197 | | const GStringPiece& delim, |
198 | 194k | string* result) { |
199 | 194k | JoinStringsIterator(components.begin(), components.end(), delim, result); |
200 | 194k | } Unexecuted instantiation: _Z11JoinStringsIN7strings8internal8SplitterINS0_9delimiter7LiteralENS1_8NoFilterEEEEvRKT_RK12GStringPiecePNSt3__112basic_stringIcNSD_11char_traitsIcEENSD_9allocatorIcEEEE _Z11JoinStringsINSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEEEvRKT_RK12GStringPiecePS7_ Line | Count | Source | 198 | 176k | string* result) { | 199 | 176k | JoinStringsIterator(components.begin(), components.end(), delim, result); | 200 | 176k | } |
Unexecuted instantiation: cql-tablet-split-test.cc:_Z11JoinStringsIN5boost12range_detail17transformed_rangeIZN2yb46CqlTabletSplitTest_SecondaryIndexWithDrop_Test8TestBodyEvE3$_3NSt3__16vectorINS6_10shared_ptrINS3_6tablet10TabletPeerEEENS6_9allocatorISB_EEEEEEEvRKT_RK12GStringPiecePNS6_12basic_stringIcNS6_11char_traitsIcEENSC_IcEEEE Unexecuted instantiation: tablet-split-itest-base.cc:_Z11JoinStringsIN5boost12range_detail17transformed_rangeIZN2yb16TabletSplitITest46WaitForTestTablePostSplitTabletsFullyCompactedENS3_9MonoDeltaEE3$_7NSt3__16vectorINS7_10shared_ptrINS3_6tablet10TabletPeerEEENS7_9allocatorISC_EEEEEEEvRKT_RK12GStringPiecePNS7_12basic_stringIcNS7_11char_traitsIcEENSD_IcEEEE Unexecuted instantiation: _Z11JoinStringsISt16initializer_listINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEEvRKT_RK12GStringPiecePS7_ _Z11JoinStringsINSt3__13setINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_4lessIS7_EENS5_IS7_EEEEEvRKT_RK12GStringPiecePS7_ Line | Count | Source | 198 | 17.6k | string* result) { | 199 | 17.6k | JoinStringsIterator(components.begin(), components.end(), delim, result); | 200 | 17.6k | } |
Unexecuted instantiation: _Z11JoinStringsINSt3__113unordered_setINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_4hashIS7_EENS0_8equal_toIS7_EENS5_IS7_EEEEEvRKT_RK12GStringPiecePS7_ |
201 | | |
202 | | template <class CONTAINER> |
203 | | inline string JoinStrings(const CONTAINER& components, |
204 | 177k | const GStringPiece& delim) { |
205 | 177k | string result; |
206 | 177k | JoinStrings(components, delim, &result); |
207 | 177k | return result; |
208 | 177k | } Unexecuted instantiation: _Z11JoinStringsIN7strings8internal8SplitterINS0_9delimiter7LiteralENS1_8NoFilterEEEENSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEERKT_RK12GStringPiece _Z11JoinStringsINSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEEES7_RKT_RK12GStringPiece Line | Count | Source | 204 | 159k | const GStringPiece& delim) { | 205 | 159k | string result; | 206 | 159k | JoinStrings(components, delim, &result); | 207 | 159k | return result; | 208 | 159k | } |
Unexecuted instantiation: cql-tablet-split-test.cc:_Z11JoinStringsIN5boost12range_detail17transformed_rangeIZN2yb46CqlTabletSplitTest_SecondaryIndexWithDrop_Test8TestBodyEvE3$_3NSt3__16vectorINS6_10shared_ptrINS3_6tablet10TabletPeerEEENS6_9allocatorISB_EEEEEEENS6_12basic_stringIcNS6_11char_traitsIcEENSC_IcEEEERKT_RK12GStringPiece Unexecuted instantiation: tablet-split-itest-base.cc:_Z11JoinStringsIN5boost12range_detail17transformed_rangeIZN2yb16TabletSplitITest46WaitForTestTablePostSplitTabletsFullyCompactedENS3_9MonoDeltaEE3$_7NSt3__16vectorINS7_10shared_ptrINS3_6tablet10TabletPeerEEENS7_9allocatorISC_EEEEEEENS7_12basic_stringIcNS7_11char_traitsIcEENSD_IcEEEERKT_RK12GStringPiece Unexecuted instantiation: _Z11JoinStringsISt16initializer_listINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEES7_RKT_RK12GStringPiece _Z11JoinStringsINSt3__13setINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_4lessIS7_EENS5_IS7_EEEEES7_RKT_RK12GStringPiece Line | Count | Source | 204 | 17.6k | const GStringPiece& delim) { | 205 | 17.6k | string result; | 206 | 17.6k | JoinStrings(components, delim, &result); | 207 | 17.6k | return result; | 208 | 17.6k | } |
Unexecuted instantiation: _Z11JoinStringsINSt3__113unordered_setINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_4hashIS7_EENS0_8equal_toIS7_EENS5_IS7_EEEEES7_RKT_RK12GStringPiece |
209 | | |
210 | | template <class ITERATOR> |
211 | | void JoinStringsIterator(const ITERATOR& start, |
212 | | const ITERATOR& end, |
213 | | const GStringPiece& delim, |
214 | 194k | string* result) { |
215 | 194k | result->clear(); |
216 | | |
217 | | // Precompute resulting length so we can reserve() memory in one shot. |
218 | 194k | if (start != end) { |
219 | 194k | auto length = delim.size()*(distance(start, end)-1); |
220 | 892k | for (ITERATOR iter = start; iter != end; ++iter) { |
221 | 698k | length += iter->size(); |
222 | 698k | } |
223 | 194k | result->reserve(length); |
224 | 194k | } |
225 | | |
226 | | // Now combine everything. |
227 | 893k | for (ITERATOR iter = start; iter != end; ++iter) { |
228 | 699k | if (iter != start) { |
229 | 506k | result->append(delim.data(), delim.size()); |
230 | 506k | } |
231 | 699k | result->append(iter->data(), iter->size()); |
232 | 699k | } |
233 | 194k | } Unexecuted instantiation: _Z19JoinStringsIteratorIN7strings8internal13SplitIteratorINS0_9delimiter7LiteralENS1_8NoFilterEEEEvRKT_S9_RK12GStringPiecePNSt3__112basic_stringIcNSD_11char_traitsIcEENSD_9allocatorIcEEEE _Z19JoinStringsIteratorINSt3__111__wrap_iterIPKNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEEEvRKT_SD_RK12GStringPiecePS7_ Line | Count | Source | 214 | 176k | string* result) { | 215 | 176k | result->clear(); | 216 | | | 217 | | // Precompute resulting length so we can reserve() memory in one shot. | 218 | 176k | if (start != end) { | 219 | 176k | auto length = delim.size()*(distance(start, end)-1); | 220 | 857k | for (ITERATOR iter = start; iter != end; ++iter) { | 221 | 680k | length += iter->size(); | 222 | 680k | } | 223 | 176k | result->reserve(length); | 224 | 176k | } | 225 | | | 226 | | // Now combine everything. | 227 | 858k | for (ITERATOR iter = start; iter != end; ++iter) { | 228 | 681k | if (iter != start) { | 229 | 505k | result->append(delim.data(), delim.size()); | 230 | 505k | } | 231 | 681k | result->append(iter->data(), iter->size()); | 232 | 681k | } | 233 | 176k | } |
Unexecuted instantiation: cql-tablet-split-test.cc:_Z19JoinStringsIteratorIN5boost9iterators18transform_iteratorINS0_12range_detail38default_constructible_unary_fn_wrapperIZN2yb46CqlTabletSplitTest_SecondaryIndexWithDrop_Test8TestBodyEvE3$_3NSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEEENS8_11__wrap_iterIPNS8_10shared_ptrINS5_6tablet10TabletPeerEEEEENS0_11use_defaultESN_EEEvRKT_SR_RK12GStringPiecePSE_ Unexecuted instantiation: _Z19JoinStringsIteratorIPKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEvRKT_SB_RK12GStringPiecePS6_ Unexecuted instantiation: tablet-split-itest-base.cc:_Z19JoinStringsIteratorIN5boost9iterators18transform_iteratorINS0_12range_detail38default_constructible_unary_fn_wrapperIZN2yb16TabletSplitITest46WaitForTestTablePostSplitTabletsFullyCompactedENS5_9MonoDeltaEE3$_7NSt3__112basic_stringIcNS9_11char_traitsIcEENS9_9allocatorIcEEEEEENS9_11__wrap_iterIPNS9_10shared_ptrINS5_6tablet10TabletPeerEEEEENS0_11use_defaultESO_EEEvRKT_SS_RK12GStringPiecePSF_ _Z19JoinStringsIteratorINSt3__121__tree_const_iteratorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPNS0_11__tree_nodeIS7_PvEElEEEvRKT_SF_RK12GStringPiecePS7_ Line | Count | Source | 214 | 17.6k | string* result) { | 215 | 17.6k | result->clear(); | 216 | | | 217 | | // Precompute resulting length so we can reserve() memory in one shot. | 218 | 17.6k | if (start != end) { | 219 | 17.6k | auto length = delim.size()*(distance(start, end)-1); | 220 | 35.5k | for (ITERATOR iter = start; iter != end; ++iter) { | 221 | 17.8k | length += iter->size(); | 222 | 17.8k | } | 223 | 17.6k | result->reserve(length); | 224 | 17.6k | } | 225 | | | 226 | | // Now combine everything. | 227 | 35.5k | for (ITERATOR iter = start; iter != end; ++iter) { | 228 | 17.8k | if (iter != start) { | 229 | 178 | result->append(delim.data(), delim.size()); | 230 | 178 | } | 231 | 17.8k | result->append(iter->data(), iter->size()); | 232 | 17.8k | } | 233 | 17.6k | } |
Unexecuted instantiation: _Z19JoinStringsIteratorINSt3__121__hash_const_iteratorIPNS0_11__hash_nodeINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPvEEEEEvRKT_SF_RK12GStringPiecePS8_ |
234 | | |
235 | | template <class ITERATOR> |
236 | | inline string JoinStringsIterator(const ITERATOR& start, |
237 | | const ITERATOR& end, |
238 | | const GStringPiece& delim) { |
239 | | string result; |
240 | | JoinStringsIterator(start, end, delim, &result); |
241 | | return result; |
242 | | } |
243 | | |
244 | | inline string JoinStringsInArray(string const* const* components, |
245 | | size_t num_components, |
246 | 0 | const char* delim) { |
247 | 0 | string result; |
248 | 0 | JoinStringsInArray(components, num_components, delim, &result); |
249 | 0 | return result; |
250 | 0 | } |
251 | | |
252 | | inline string JoinStringsInArray(string const* components, |
253 | | size_t num_components, |
254 | 0 | const char* delim) { |
255 | 0 | string result; |
256 | 0 | JoinStringsInArray(components, num_components, delim, &result); |
257 | 0 | return result; |
258 | 0 | } |
259 | | |
260 | | // ---------------------------------------------------------------------- |
261 | | // JoinMapKeysAndValues() |
262 | | // JoinHashMapKeysAndValues() |
263 | | // JoinVectorKeysAndValues() |
264 | | // This merges the keys and values of a string -> string map or pair |
265 | | // of strings vector, with one delim (intra_delim) between each key |
266 | | // and its associated value and another delim (inter_delim) between |
267 | | // each key/value pair. The result is returned in a string (passed |
268 | | // as the last argument). |
269 | | // ---------------------------------------------------------------------- |
270 | | |
271 | | void JoinMapKeysAndValues(const map<string, string>& components, |
272 | | const GStringPiece& intra_delim, |
273 | | const GStringPiece& inter_delim, |
274 | | string* result); |
275 | | void JoinVectorKeysAndValues(const vector< pair<string, string> >& components, |
276 | | const GStringPiece& intra_delim, |
277 | | const GStringPiece& inter_delim, |
278 | | string* result); |
279 | | |
280 | | // DEPRECATED(jyrki): use JoinKeysAndValuesIterator directly. |
281 | | template<typename T> |
282 | | void JoinHashMapKeysAndValues(const T& container, |
283 | | const GStringPiece& intra_delim, |
284 | | const GStringPiece& inter_delim, |
285 | | string* result) { |
286 | | JoinKeysAndValuesIterator(container.begin(), container.end(), |
287 | | intra_delim, inter_delim, |
288 | | result); |
289 | | } |
290 | | |
291 | | // ---------------------------------------------------------------------- |
292 | | // JoinCSVLineWithDelimiter() |
293 | | // This function is the inverse of SplitCSVLineWithDelimiter() in that the |
294 | | // string returned by JoinCSVLineWithDelimiter() can be passed to |
295 | | // SplitCSVLineWithDelimiter() to get the original string vector back. |
296 | | // Quotes and escapes the elements of original_cols according to CSV quoting |
297 | | // rules, and the joins the escaped quoted strings with commas using |
298 | | // JoinStrings(). Note that JoinCSVLineWithDelimiter() will not necessarily |
299 | | // return the same string originally passed in to |
300 | | // SplitCSVLineWithDelimiter(), since SplitCSVLineWithDelimiter() can handle |
301 | | // gratuitous spacing and quoting. 'output' must point to an empty string. |
302 | | // |
303 | | // Example: |
304 | | // [Google], [x], [Buchheit, Paul], [string with " quoite in it], [ space ] |
305 | | // ---> [Google,x,"Buchheit, Paul","string with "" quote in it"," space "] |
306 | | // |
307 | | // JoinCSVLine() |
308 | | // A convenience wrapper around JoinCSVLineWithDelimiter which uses |
309 | | // ',' as the delimiter. |
310 | | // ---------------------------------------------------------------------- |
311 | | void JoinCSVLine(const vector<string>& original_cols, string* output); |
312 | | string JoinCSVLine(const vector<string>& original_cols); |
313 | | void JoinCSVLineWithDelimiter(const vector<string>& original_cols, |
314 | | char delimiter, |
315 | | string* output); |
316 | | |
317 | | // ---------------------------------------------------------------------- |
318 | | // JoinElements() |
319 | | // This merges a container of any type supported by StrAppend() with delim |
320 | | // inserted as separators between components. This is essentially a |
321 | | // templatized version of JoinUsingToBuffer(). |
322 | | // |
323 | | // JoinElementsIterator() |
324 | | // Same as JoinElements(), except that the input elements are specified |
325 | | // with a pair of forward iterators. |
326 | | // ---------------------------------------------------------------------- |
327 | | |
328 | | template <class ITERATOR> |
329 | | void JoinElementsIterator(ITERATOR first, |
330 | | ITERATOR last, |
331 | | GStringPiece delim, |
332 | 400 | string* result) { |
333 | 400 | result->clear(); |
334 | 871 | for (ITERATOR it = first; it != last; ++it) { |
335 | 471 | if (it != first) { |
336 | 71 | StrAppend(result, delim); |
337 | 71 | } |
338 | 471 | StrAppend(result, *it); |
339 | 471 | } |
340 | 400 | } _Z20JoinElementsIteratorINSt3__111__wrap_iterIPKmEEEvT_S5_12GStringPiecePNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE Line | Count | Source | 332 | 2 | string* result) { | 333 | 2 | result->clear(); | 334 | 9 | for (ITERATOR it = first; it != last; ++it) { | 335 | 7 | if (it != first) { | 336 | 5 | StrAppend(result, delim); | 337 | 5 | } | 338 | 7 | StrAppend(result, *it); | 339 | 7 | } | 340 | 2 | } |
_Z20JoinElementsIteratorINSt3__111__wrap_iterIPKtEEEvT_S5_12GStringPiecePNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE Line | Count | Source | 332 | 398 | string* result) { | 333 | 398 | result->clear(); | 334 | 862 | for (ITERATOR it = first; it != last; ++it) { | 335 | 464 | if (it != first) { | 336 | 66 | StrAppend(result, delim); | 337 | 66 | } | 338 | 464 | StrAppend(result, *it); | 339 | 464 | } | 340 | 398 | } |
Unexecuted instantiation: _Z20JoinElementsIteratorIN6google8protobuf8internal19RepeatedPtrIteratorIKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEEEvT_SD_12GStringPiecePSA_ |
341 | | |
342 | | template <class ITERATOR> |
343 | | string JoinElementsIterator(ITERATOR first, |
344 | | ITERATOR last, |
345 | 0 | GStringPiece delim) { |
346 | 0 | string result; |
347 | 0 | JoinElementsIterator(first, last, delim, &result); |
348 | 0 | return result; |
349 | 0 | } |
350 | | |
351 | | template <class CONTAINER> |
352 | | inline void JoinElements(const CONTAINER& components, |
353 | | GStringPiece delim, |
354 | 400 | string* result) { |
355 | 400 | JoinElementsIterator(components.begin(), components.end(), delim, result); |
356 | 400 | } _Z12JoinElementsINSt3__16vectorImNS0_9allocatorImEEEEEvRKT_12GStringPiecePNS0_12basic_stringIcNS0_11char_traitsIcEENS2_IcEEEE Line | Count | Source | 354 | 2 | string* result) { | 355 | 2 | JoinElementsIterator(components.begin(), components.end(), delim, result); | 356 | 2 | } |
_Z12JoinElementsINSt3__16vectorItNS0_9allocatorItEEEEEvRKT_12GStringPiecePNS0_12basic_stringIcNS0_11char_traitsIcEENS2_IcEEEE Line | Count | Source | 354 | 398 | string* result) { | 355 | 398 | JoinElementsIterator(components.begin(), components.end(), delim, result); | 356 | 398 | } |
|
357 | | |
358 | | template <class CONTAINER> |
359 | 400 | inline string JoinElements(const CONTAINER& components, GStringPiece delim) { |
360 | 400 | string result; |
361 | 400 | JoinElements(components, delim, &result); |
362 | 400 | return result; |
363 | 400 | } _Z12JoinElementsINSt3__16vectorImNS0_9allocatorImEEEEENS0_12basic_stringIcNS0_11char_traitsIcEENS2_IcEEEERKT_12GStringPiece Line | Count | Source | 359 | 2 | inline string JoinElements(const CONTAINER& components, GStringPiece delim) { | 360 | 2 | string result; | 361 | 2 | JoinElements(components, delim, &result); | 362 | 2 | return result; | 363 | 2 | } |
_Z12JoinElementsINSt3__16vectorItNS0_9allocatorItEEEEENS0_12basic_stringIcNS0_11char_traitsIcEENS2_IcEEEERKT_12GStringPiece Line | Count | Source | 359 | 398 | inline string JoinElements(const CONTAINER& components, GStringPiece delim) { | 360 | 398 | string result; | 361 | 398 | JoinElements(components, delim, &result); | 362 | 398 | return result; | 363 | 398 | } |
|
364 | | |
365 | | template <class CONTAINER> |
366 | | void JoinInts(const CONTAINER& components, |
367 | | const char* delim, |
368 | | string* result) { |
369 | | JoinElements(components, delim, result); |
370 | | } |
371 | | |
372 | | template <class CONTAINER> |
373 | | inline string JoinInts(const CONTAINER& components, |
374 | 398 | const char* delim) { |
375 | 398 | return JoinElements(components, delim); |
376 | 398 | } |
377 | | |
378 | | #endif // YB_GUTIL_STRINGS_JOIN_H |