YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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; 
++iter5
) {
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: void JoinKeysAndValuesIterator<std::__1::__map_const_iterator<std::__1::__tree_const_iterator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, void*>*, long> > >(std::__1::__map_const_iterator<std::__1::__tree_const_iterator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, void*>*, long> > const&, std::__1::__map_const_iterator<std::__1::__tree_const_iterator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, void*>*, long> > const&, GStringPiece const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Unexecuted instantiation: void JoinKeysAndValuesIterator<std::__1::__wrap_iter<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*> >(std::__1::__wrap_iter<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*> const&, std::__1::__wrap_iter<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*> const&, GStringPiece const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
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
287k
                        string* result) {
199
287k
  JoinStringsIterator(components.begin(), components.end(), delim, result);
200
287k
}
Unexecuted instantiation: void JoinStrings<strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter> >(strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter> const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Unexecuted instantiation: tablet-split-itest-base.cc:void JoinStrings<boost::range_detail::transformed_range<yb::TabletSplitITest::WaitForTestTablePostSplitTabletsFullyCompacted(yb::MonoDelta)::$_7, std::__1::vector<std::__1::shared_ptr<yb::tablet::TabletPeer>, std::__1::allocator<std::__1::shared_ptr<yb::tablet::TabletPeer> > > > >(boost::range_detail::transformed_range<yb::TabletSplitITest::WaitForTestTablePostSplitTabletsFullyCompacted(yb::MonoDelta)::$_7, std::__1::vector<std::__1::shared_ptr<yb::tablet::TabletPeer>, std::__1::allocator<std::__1::shared_ptr<yb::tablet::TabletPeer> > > > const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
void JoinStrings<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Line
Count
Source
198
261k
                        string* result) {
199
261k
  JoinStringsIterator(components.begin(), components.end(), delim, result);
200
261k
}
Unexecuted instantiation: void JoinStrings<std::initializer_list<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >(std::initializer_list<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
void JoinStrings<std::__1::set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(std::__1::set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Line
Count
Source
198
26.5k
                        string* result) {
199
26.5k
  JoinStringsIterator(components.begin(), components.end(), delim, result);
200
26.5k
}
Unexecuted instantiation: void JoinStrings<std::__1::unordered_set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(std::__1::unordered_set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
201
202
template <class CONTAINER>
203
inline string JoinStrings(const CONTAINER& components,
204
260k
                          const GStringPiece& delim) {
205
260k
  string result;
206
260k
  JoinStrings(components, delim, &result);
207
260k
  return result;
208
260k
}
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > JoinStrings<strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter> >(strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter> const&, GStringPiece const&)
Unexecuted instantiation: tablet-split-itest-base.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > JoinStrings<boost::range_detail::transformed_range<yb::TabletSplitITest::WaitForTestTablePostSplitTabletsFullyCompacted(yb::MonoDelta)::$_7, std::__1::vector<std::__1::shared_ptr<yb::tablet::TabletPeer>, std::__1::allocator<std::__1::shared_ptr<yb::tablet::TabletPeer> > > > >(boost::range_detail::transformed_range<yb::TabletSplitITest::WaitForTestTablePostSplitTabletsFullyCompacted(yb::MonoDelta)::$_7, std::__1::vector<std::__1::shared_ptr<yb::tablet::TabletPeer>, std::__1::allocator<std::__1::shared_ptr<yb::tablet::TabletPeer> > > > const&, GStringPiece const&)
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > JoinStrings<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, GStringPiece const&)
Line
Count
Source
204
233k
                          const GStringPiece& delim) {
205
233k
  string result;
206
233k
  JoinStrings(components, delim, &result);
207
233k
  return result;
208
233k
}
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > JoinStrings<std::initializer_list<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >(std::initializer_list<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&, GStringPiece const&)
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > JoinStrings<std::__1::set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(std::__1::set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, GStringPiece const&)
Line
Count
Source
204
26.5k
                          const GStringPiece& delim) {
205
26.5k
  string result;
206
26.5k
  JoinStrings(components, delim, &result);
207
26.5k
  return result;
208
26.5k
}
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > JoinStrings<std::__1::unordered_set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(std::__1::unordered_set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, GStringPiece const&)
209
210
template <class ITERATOR>
211
void JoinStringsIterator(const ITERATOR& start,
212
                         const ITERATOR& end,
213
                         const GStringPiece& delim,
214
287k
                         string* result) {
215
287k
  result->clear();
216
217
  // Precompute resulting length so we can reserve() memory in one shot.
218
287k
  if (start != end) {
219
286k
    auto length = delim.size()*(distance(start, end)-1);
220
1.23M
    for (ITERATOR iter = start; iter != end; 
++iter945k
) {
221
945k
      length += iter->size();
222
945k
    }
223
286k
    result->reserve(length);
224
286k
  }
225
226
  // Now combine everything.
227
1.23M
  for (ITERATOR iter = start; iter != end; 
++iter946k
) {
228
946k
    if (iter != start) {
229
660k
      result->append(delim.data(), delim.size());
230
660k
    }
231
946k
    result->append(iter->data(), iter->size());
232
946k
  }
233
287k
}
Unexecuted instantiation: void JoinStringsIterator<strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter> >(strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter> const&, strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter> const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Unexecuted instantiation: tablet-split-itest-base.cc:void JoinStringsIterator<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<yb::TabletSplitITest::WaitForTestTablePostSplitTabletsFullyCompacted(yb::MonoDelta)::$_7, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__wrap_iter<std::__1::shared_ptr<yb::tablet::TabletPeer>*>, boost::use_default, boost::use_default> >(boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<yb::TabletSplitITest::WaitForTestTablePostSplitTabletsFullyCompacted(yb::MonoDelta)::$_7, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__wrap_iter<std::__1::shared_ptr<yb::tablet::TabletPeer>*>, boost::use_default, boost::use_default> const&, boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<yb::TabletSplitITest::WaitForTestTablePostSplitTabletsFullyCompacted(yb::MonoDelta)::$_7, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__wrap_iter<std::__1::shared_ptr<yb::tablet::TabletPeer>*>, boost::use_default, boost::use_default> const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
void JoinStringsIterator<std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> >(std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> const&, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Line
Count
Source
214
260k
                         string* result) {
215
260k
  result->clear();
216
217
  // Precompute resulting length so we can reserve() memory in one shot.
218
260k
  if (start != end) {
219
260k
    auto length = delim.size()*(distance(start, end)-1);
220
1.17M
    for (ITERATOR iter = start; iter != end; 
++iter918k
) {
221
918k
      length += iter->size();
222
918k
    }
223
260k
    result->reserve(length);
224
260k
  }
225
226
  // Now combine everything.
227
1.18M
  for (ITERATOR iter = start; iter != end; 
++iter919k
) {
228
919k
    if (iter != start) {
229
660k
      result->append(delim.data(), delim.size());
230
660k
    }
231
919k
    result->append(iter->data(), iter->size());
232
919k
  }
233
260k
}
Unexecuted instantiation: void JoinStringsIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
void JoinStringsIterator<std::__1::__tree_const_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*, long> >(std::__1::__tree_const_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*, long> const&, std::__1::__tree_const_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*, long> const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Line
Count
Source
214
26.5k
                         string* result) {
215
26.5k
  result->clear();
216
217
  // Precompute resulting length so we can reserve() memory in one shot.
218
26.5k
  if (start != end) {
219
26.5k
    auto length = delim.size()*(distance(start, end)-1);
220
53.3k
    for (ITERATOR iter = start; iter != end; 
++iter26.7k
) {
221
26.7k
      length += iter->size();
222
26.7k
    }
223
26.5k
    result->reserve(length);
224
26.5k
  }
225
226
  // Now combine everything.
227
53.3k
  for (ITERATOR iter = start; iter != end; 
++iter26.7k
) {
228
26.7k
    if (iter != start) {
229
178
      result->append(delim.data(), delim.size());
230
178
    }
231
26.7k
    result->append(iter->data(), iter->size());
232
26.7k
  }
233
26.5k
}
Unexecuted instantiation: void JoinStringsIterator<std::__1::__hash_const_iterator<std::__1::__hash_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*> >(std::__1::__hash_const_iterator<std::__1::__hash_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*> const&, std::__1::__hash_const_iterator<std::__1::__hash_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*> const&, GStringPiece const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
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
992
                          string* result) {
333
992
  result->clear();
334
2.06k
  for (ITERATOR it = first; it != last; 
++it1.07k
) {
335
1.07k
    if (it != first) {
336
84
      StrAppend(result, delim);
337
84
    }
338
1.07k
    StrAppend(result, *it);
339
1.07k
  }
340
992
}
Unexecuted instantiation: void JoinElementsIterator<google::protobuf::internal::RepeatedPtrIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const> >(google::protobuf::internal::RepeatedPtrIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const>, google::protobuf::internal::RepeatedPtrIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const>, GStringPiece, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
void JoinElementsIterator<std::__1::__wrap_iter<unsigned short const*> >(std::__1::__wrap_iter<unsigned short const*>, std::__1::__wrap_iter<unsigned short const*>, GStringPiece, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Line
Count
Source
332
992
                          string* result) {
333
992
  result->clear();
334
2.06k
  for (ITERATOR it = first; it != last; 
++it1.07k
) {
335
1.07k
    if (it != first) {
336
84
      StrAppend(result, delim);
337
84
    }
338
1.07k
    StrAppend(result, *it);
339
1.07k
  }
340
992
}
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
992
                         string* result) {
355
992
  JoinElementsIterator(components.begin(), components.end(), delim, result);
356
992
}
357
358
template <class CONTAINER>
359
992
inline string JoinElements(const CONTAINER& components, GStringPiece delim) {
360
992
  string result;
361
992
  JoinElements(components, delim, &result);
362
992
  return result;
363
992
}
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
992
                       const char* delim) {
375
992
  return JoinElements(components, delim);
376
992
}
377
378
#endif  // YB_GUTIL_STRINGS_JOIN_H