YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/gutil/strings/split_internal.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2012 Google Inc. All Rights Reserved.
2
//
3
// The following only applies to changes made to this file as part of YugaByte development.
4
//
5
// Portions Copyright (c) YugaByte, Inc.
6
//
7
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8
// in compliance with the License.  You may obtain a copy of the License at
9
//
10
// http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software distributed under the License
13
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14
// or implied.  See the License for the specific language governing permissions and limitations
15
// under the License.
16
//
17
// This file declares INTERNAL parts of the Split API that are inline/templated
18
// or otherwise need to be available at compile time. The main two abstractions
19
// defined in here are
20
//
21
//   - SplitIterator<>
22
//   - Splitter<>
23
//
24
// Everything else is plumbing for those two.
25
//
26
// DO NOT INCLUDE THIS FILE DIRECTLY. Use this file by including
27
// strings/split.h.
28
//
29
// IWYU pragma: private, include "strings/split.h"
30
31
#ifndef YB_GUTIL_STRINGS_SPLIT_INTERNAL_H
32
#define YB_GUTIL_STRINGS_SPLIT_INTERNAL_H
33
34
#include <iterator>
35
using std::back_insert_iterator;
36
using std::iterator_traits;
37
#include <map>
38
using std::map;
39
using std::multimap;
40
#include <vector>
41
using std::vector;
42
43
#include "yb/gutil/port.h"  // for LANG_CXX11
44
#include "yb/gutil/strings/stringpiece.h"
45
#include "yb/gutil/type_traits.h"
46
47
#ifdef LANG_CXX11
48
// This must be included after "base/port.h", which defines LANG_CXX11.
49
#include <initializer_list>
50
#endif  // LANG_CXX11
51
52
namespace strings {
53
54
namespace internal {
55
56
// The default Predicate object, which doesn't filter out anything.
57
struct NoFilter {
58
801k
  bool operator()(GStringPiece /* ignored */) {
59
801k
    return true;
60
801k
  }
61
};
62
63
// This class splits a string using the given delimiter, returning the split
64
// substrings via an iterator interface. An optional Predicate functor may be
65
// supplied, which will be used to filter the split strings: strings for which
66
// the predicate returns false will be skipped. A Predicate object is any
67
// functor that takes a GStringPiece and returns bool. By default, the NoFilter
68
// Predicate is used, which does not filter out anything.
69
//
70
// This class is NOT part of the public splitting API.
71
//
72
// Usage:
73
//
74
//   using strings::delimiter::Literal;
75
//   Literal d(",");
76
//   for (SplitIterator<Literal> it("a,b,c", d), end(d); it != end; ++it) {
77
//     GStringPiece substring = *it;
78
//     DoWork(substring);
79
//   }
80
//
81
// The explicit single-argument constructor is used to create an "end" iterator.
82
// The two-argument constructor is used to split the given text using the given
83
// delimiter.
84
template <typename Delimiter, typename Predicate = NoFilter>
85
class SplitIterator
86
    : public std::iterator<std::input_iterator_tag, GStringPiece> {
87
 public:
88
  // Two constructors for "end" iterators.
89
  explicit SplitIterator(Delimiter d)
90
222k
      : delimiter_(std::move(d)), predicate_(), is_end_(true) {}
strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter>::SplitIterator(strings::delimiter::Literal)
Line
Count
Source
90
222k
      : delimiter_(std::move(d)), predicate_(), is_end_(true) {}
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::internal::NoFilter>::SplitIterator(strings::delimiter::AnyOf)
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::SplitIterator(strings::delimiter::LimitImpl<strings::delimiter::AnyOf>)
91
  SplitIterator(Delimiter d, Predicate p)
92
332k
      : delimiter_(std::move(d)), predicate_(std::move(p)), is_end_(true) {}
strings::internal::SplitIterator<strings::delimiter::Literal, strings::SkipEmpty>::SplitIterator(strings::delimiter::Literal, strings::SkipEmpty)
Line
Count
Source
92
332k
      : delimiter_(std::move(d)), predicate_(std::move(p)), is_end_(true) {}
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::SkipEmpty>::SplitIterator(strings::delimiter::AnyOf, strings::SkipEmpty)
strings::internal::SplitIterator<strings::delimiter::Literal, strings::AllowEmpty>::SplitIterator(strings::delimiter::Literal, strings::AllowEmpty)
Line
Count
Source
92
101
      : delimiter_(std::move(d)), predicate_(std::move(p)), is_end_(true) {}
93
  // Two constructors taking the text to iterator.
94
  SplitIterator(GStringPiece text, Delimiter d)
95
      : text_(std::move(text)),
96
        delimiter_(std::move(d)),
97
        predicate_(),
98
222k
        is_end_(false) {
99
222k
    ++(*this);
100
222k
  }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter>::SplitIterator(GStringPiece, strings::delimiter::Literal)
Line
Count
Source
98
222k
        is_end_(false) {
99
222k
    ++(*this);
100
222k
  }
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::internal::NoFilter>::SplitIterator(GStringPiece, strings::delimiter::AnyOf)
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::SplitIterator(GStringPiece, strings::delimiter::LimitImpl<strings::delimiter::AnyOf>)
101
  SplitIterator(GStringPiece text, Delimiter d, Predicate p)
102
      : text_(std::move(text)),
103
        delimiter_(std::move(d)),
104
        predicate_(std::move(p)),
105
332k
        is_end_(false) {
106
332k
    ++(*this);
107
332k
  }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::SkipEmpty>::SplitIterator(GStringPiece, strings::delimiter::Literal, strings::SkipEmpty)
Line
Count
Source
105
332k
        is_end_(false) {
106
332k
    ++(*this);
107
332k
  }
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::SkipEmpty>::SplitIterator(GStringPiece, strings::delimiter::AnyOf, strings::SkipEmpty)
strings::internal::SplitIterator<strings::delimiter::Literal, strings::AllowEmpty>::SplitIterator(GStringPiece, strings::delimiter::Literal, strings::AllowEmpty)
Line
Count
Source
105
101
        is_end_(false) {
106
101
    ++(*this);
107
101
  }
108
109
1.20M
  GStringPiece operator*() { return curr_piece_; }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::SkipEmpty>::operator*()
Line
Count
Source
109
399k
  GStringPiece operator*() { return curr_piece_; }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter>::operator*()
Line
Count
Source
109
801k
  GStringPiece operator*() { return curr_piece_; }
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::internal::NoFilter>::operator*()
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::operator*()
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::SkipEmpty>::operator*()
strings::internal::SplitIterator<strings::delimiter::Literal, strings::AllowEmpty>::operator*()
Line
Count
Source
109
212
  GStringPiece operator*() { return curr_piece_; }
110
0
  GStringPiece* operator->() { return &curr_piece_; }
111
112
1.75M
  SplitIterator& operator++() {
113
1.76M
    do {
114
1.76M
      if (text_.end() == curr_piece_.end()) {
115
        // Already consumed all of text_, so we're done.
116
554k
        is_end_ = true;
117
554k
        return *this;
118
554k
      }
119
1.21M
      GStringPiece found_delimiter = delimiter_.Find(text_);
120
1.21M
      assert(found_delimiter.data() != NULL);
121
0
      assert(text_.begin() <= found_delimiter.begin());
122
0
      assert(found_delimiter.end() <= text_.end());
123
      // found_delimiter is allowed to be empty.
124
      // Sets curr_piece_ to all text up to but excluding the delimiter itself.
125
      // Sets text_ to remaining data after the delimiter.
126
0
      curr_piece_.set(text_.begin(), found_delimiter.begin() - text_.begin());
127
1.21M
      text_.remove_prefix(found_delimiter.end() - text_.begin());
128
1.21M
    } while (!predicate_(curr_piece_));
129
1.20M
    return *this;
130
1.75M
  }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::SkipEmpty>::operator++()
Line
Count
Source
112
731k
  SplitIterator& operator++() {
113
744k
    do {
114
744k
      if (text_.end() == curr_piece_.end()) {
115
        // Already consumed all of text_, so we're done.
116
332k
        is_end_ = true;
117
332k
        return *this;
118
332k
      }
119
412k
      GStringPiece found_delimiter = delimiter_.Find(text_);
120
412k
      assert(found_delimiter.data() != NULL);
121
0
      assert(text_.begin() <= found_delimiter.begin());
122
0
      assert(found_delimiter.end() <= text_.end());
123
      // found_delimiter is allowed to be empty.
124
      // Sets curr_piece_ to all text up to but excluding the delimiter itself.
125
      // Sets text_ to remaining data after the delimiter.
126
0
      curr_piece_.set(text_.begin(), found_delimiter.begin() - text_.begin());
127
412k
      text_.remove_prefix(found_delimiter.end() - text_.begin());
128
412k
    } while (!predicate_(curr_piece_));
129
399k
    return *this;
130
731k
  }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter>::operator++()
Line
Count
Source
112
1.02M
  SplitIterator& operator++() {
113
1.02M
    do {
114
1.02M
      if (text_.end() == curr_piece_.end()) {
115
        // Already consumed all of text_, so we're done.
116
222k
        is_end_ = true;
117
222k
        return *this;
118
222k
      }
119
801k
      GStringPiece found_delimiter = delimiter_.Find(text_);
120
801k
      assert(found_delimiter.data() != NULL);
121
0
      assert(text_.begin() <= found_delimiter.begin());
122
0
      assert(found_delimiter.end() <= text_.end());
123
      // found_delimiter is allowed to be empty.
124
      // Sets curr_piece_ to all text up to but excluding the delimiter itself.
125
      // Sets text_ to remaining data after the delimiter.
126
0
      curr_piece_.set(text_.begin(), found_delimiter.begin() - text_.begin());
127
801k
      text_.remove_prefix(found_delimiter.end() - text_.begin());
128
801k
    } while (!predicate_(curr_piece_));
129
801k
    return *this;
130
1.02M
  }
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::internal::NoFilter>::operator++()
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::operator++()
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::SkipEmpty>::operator++()
strings::internal::SplitIterator<strings::delimiter::Literal, strings::AllowEmpty>::operator++()
Line
Count
Source
112
313
  SplitIterator& operator++() {
113
313
    do {
114
313
      if (text_.end() == curr_piece_.end()) {
115
        // Already consumed all of text_, so we're done.
116
101
        is_end_ = true;
117
101
        return *this;
118
101
      }
119
212
      GStringPiece found_delimiter = delimiter_.Find(text_);
120
212
      assert(found_delimiter.data() != NULL);
121
0
      assert(text_.begin() <= found_delimiter.begin());
122
0
      assert(found_delimiter.end() <= text_.end());
123
      // found_delimiter is allowed to be empty.
124
      // Sets curr_piece_ to all text up to but excluding the delimiter itself.
125
      // Sets text_ to remaining data after the delimiter.
126
0
      curr_piece_.set(text_.begin(), found_delimiter.begin() - text_.begin());
127
212
      text_.remove_prefix(found_delimiter.end() - text_.begin());
128
212
    } while (!predicate_(curr_piece_));
129
212
    return *this;
130
313
  }
131
132
  SplitIterator operator++(int /* postincrement */) {
133
    SplitIterator old(*this);
134
    ++(*this);
135
    return old;
136
  }
137
138
1.75M
  bool operator==(const SplitIterator& other) const {
139
    // Two "end" iterators are always equal. If the two iterators being compared
140
    // aren't both end iterators, then we fallback to comparing their fields.
141
    // Importantly, the text being split must be equal and the current piece
142
    // within the text being split must also be equal. The delimiter_ and
143
    // predicate_ fields need not be checked here because they're template
144
    // parameters that are already part of the SplitIterator's type.
145
1.75M
    return (is_end_ && 
other.is_end_554k
) ||
146
1.75M
           
(1.20M
is_end_ == other.is_end_1.20M
&&
147
1.20M
            
text_ == other.text_0
&&
148
1.20M
            
text_.data() == other.text_.data()0
&&
149
1.20M
            
curr_piece_ == other.curr_piece_0
&&
150
1.20M
            
curr_piece_.data() == other.curr_piece_.data()0
);
151
1.75M
  }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::SkipEmpty>::operator==(strings::internal::SplitIterator<strings::delimiter::Literal, strings::SkipEmpty> const&) const
Line
Count
Source
138
731k
  bool operator==(const SplitIterator& other) const {
139
    // Two "end" iterators are always equal. If the two iterators being compared
140
    // aren't both end iterators, then we fallback to comparing their fields.
141
    // Importantly, the text being split must be equal and the current piece
142
    // within the text being split must also be equal. The delimiter_ and
143
    // predicate_ fields need not be checked here because they're template
144
    // parameters that are already part of the SplitIterator's type.
145
731k
    return (is_end_ && 
other.is_end_332k
) ||
146
731k
           
(399k
is_end_ == other.is_end_399k
&&
147
399k
            
text_ == other.text_0
&&
148
399k
            
text_.data() == other.text_.data()0
&&
149
399k
            
curr_piece_ == other.curr_piece_0
&&
150
399k
            
curr_piece_.data() == other.curr_piece_.data()0
);
151
731k
  }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter>::operator==(strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter> const&) const
Line
Count
Source
138
1.02M
  bool operator==(const SplitIterator& other) const {
139
    // Two "end" iterators are always equal. If the two iterators being compared
140
    // aren't both end iterators, then we fallback to comparing their fields.
141
    // Importantly, the text being split must be equal and the current piece
142
    // within the text being split must also be equal. The delimiter_ and
143
    // predicate_ fields need not be checked here because they're template
144
    // parameters that are already part of the SplitIterator's type.
145
1.02M
    return (is_end_ && 
other.is_end_222k
) ||
146
1.02M
           
(801k
is_end_ == other.is_end_801k
&&
147
801k
            
text_ == other.text_0
&&
148
801k
            
text_.data() == other.text_.data()0
&&
149
801k
            
curr_piece_ == other.curr_piece_0
&&
150
801k
            
curr_piece_.data() == other.curr_piece_.data()0
);
151
1.02M
  }
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::internal::NoFilter>::operator==(strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::internal::NoFilter> const&) const
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::operator==(strings::internal::SplitIterator<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter> const&) const
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::SkipEmpty>::operator==(strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::SkipEmpty> const&) const
strings::internal::SplitIterator<strings::delimiter::Literal, strings::AllowEmpty>::operator==(strings::internal::SplitIterator<strings::delimiter::Literal, strings::AllowEmpty> const&) const
Line
Count
Source
138
313
  bool operator==(const SplitIterator& other) const {
139
    // Two "end" iterators are always equal. If the two iterators being compared
140
    // aren't both end iterators, then we fallback to comparing their fields.
141
    // Importantly, the text being split must be equal and the current piece
142
    // within the text being split must also be equal. The delimiter_ and
143
    // predicate_ fields need not be checked here because they're template
144
    // parameters that are already part of the SplitIterator's type.
145
313
    return (is_end_ && 
other.is_end_101
) ||
146
313
           
(212
is_end_ == other.is_end_212
&&
147
212
            
text_ == other.text_0
&&
148
212
            
text_.data() == other.text_.data()0
&&
149
212
            
curr_piece_ == other.curr_piece_0
&&
150
212
            
curr_piece_.data() == other.curr_piece_.data()0
);
151
313
  }
152
153
1.75M
  bool operator!=(const SplitIterator& other) const {
154
1.75M
    return !(*this == other);
155
1.75M
  }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::SkipEmpty>::operator!=(strings::internal::SplitIterator<strings::delimiter::Literal, strings::SkipEmpty> const&) const
Line
Count
Source
153
731k
  bool operator!=(const SplitIterator& other) const {
154
731k
    return !(*this == other);
155
731k
  }
strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter>::operator!=(strings::internal::SplitIterator<strings::delimiter::Literal, strings::internal::NoFilter> const&) const
Line
Count
Source
153
1.02M
  bool operator!=(const SplitIterator& other) const {
154
1.02M
    return !(*this == other);
155
1.02M
  }
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::internal::NoFilter>::operator!=(strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::internal::NoFilter> const&) const
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::operator!=(strings::internal::SplitIterator<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter> const&) const
Unexecuted instantiation: strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::SkipEmpty>::operator!=(strings::internal::SplitIterator<strings::delimiter::AnyOf, strings::SkipEmpty> const&) const
strings::internal::SplitIterator<strings::delimiter::Literal, strings::AllowEmpty>::operator!=(strings::internal::SplitIterator<strings::delimiter::Literal, strings::AllowEmpty> const&) const
Line
Count
Source
153
313
  bool operator!=(const SplitIterator& other) const {
154
313
    return !(*this == other);
155
313
  }
156
157
 private:
158
  // The text being split. Modified as delimited pieces are consumed.
159
  GStringPiece text_;
160
  Delimiter delimiter_;
161
  Predicate predicate_;
162
  bool is_end_;
163
  // Holds the currently split piece of text. Will always refer to string data
164
  // within text_. This value is returned when the iterator is dereferenced.
165
  GStringPiece curr_piece_;
166
};
167
168
// Declares a functor that can convert a GStringPiece to another type. This works
169
// for any type that has a constructor (explicit or not) taking a single
170
// GStringPiece argument. A specialization exists for converting to string
171
// because the underlying data needs to be copied. In theory, these
172
// specializations could be extended to work with other types (e.g., int32), but
173
// then a solution for error reporting would need to be devised.
174
template <typename To>
175
struct GStringPieceTo {
176
1.90k
  To operator()(GStringPiece from) const {
177
1.90k
    return To(from);
178
1.90k
  }
179
};
180
181
// Specialization for converting to string.
182
template <>
183
struct GStringPieceTo<string> {
184
1.19M
  string operator()(GStringPiece from) const {
185
1.19M
    return from.ToString();
186
1.19M
  }
187
};
188
189
// Specialization for converting to *const* string.
190
template <>
191
struct GStringPieceTo<const string> {
192
0
  string operator()(GStringPiece from) const {
193
0
    return from.ToString();
194
0
  }
195
};
196
197
#ifdef LANG_CXX11
198
// IsNotInitializerList<T>::type exists iff T is not an initializer_list. More
199
// details below in Splitter<> where this is used.
200
template <typename T>
201
struct IsNotInitializerList {
202
  typedef void type;
203
};
204
template <typename T>
205
struct IsNotInitializerList<std::initializer_list<T> > {};
206
#endif  // LANG_CXX11
207
208
// This class implements the behavior of the split API by giving callers access
209
// to the underlying split substrings in various convenient ways, such as
210
// through iterators or implicit conversion functions. Do not construct this
211
// class directly, rather use the Split() function instead.
212
//
213
// Output containers can be collections of either GStringPiece or string objects.
214
// GStringPiece is more efficient because the underlying data will not need to be
215
// copied; the returned GStringPieces will all refer to the data within the
216
// original input string. If a collection of string objects is used, then each
217
// substring will be copied.
218
//
219
// An optional Predicate functor may be supplied. This predicate will be used to
220
// filter the split strings: only strings for which the predicate returns true
221
// will be kept. A Predicate object is any unary functor that takes a
222
// GStringPiece and returns bool. By default, the NoFilter predicate is used,
223
// which does not filter out anything.
224
template <typename Delimiter, typename Predicate = NoFilter>
225
class Splitter {
226
 public:
227
  typedef internal::SplitIterator<Delimiter, Predicate> Iterator;
228
229
  Splitter(GStringPiece text, Delimiter d)
230
222k
      : begin_(text, d), end_(d) {}
strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::Splitter(GStringPiece, strings::delimiter::Literal)
Line
Count
Source
230
222k
      : begin_(text, d), end_(d) {}
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::Splitter(GStringPiece, strings::delimiter::AnyOf)
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::Splitter(GStringPiece, strings::delimiter::LimitImpl<strings::delimiter::AnyOf>)
231
232
  Splitter(GStringPiece text, Delimiter d, Predicate p)
233
332k
      : begin_(text, d, p), end_(d, p) {}
strings::internal::Splitter<strings::delimiter::Literal, strings::SkipEmpty>::Splitter(GStringPiece, strings::delimiter::Literal, strings::SkipEmpty)
Line
Count
Source
233
332k
      : begin_(text, d, p), end_(d, p) {}
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::Splitter(GStringPiece, strings::delimiter::AnyOf, strings::SkipEmpty)
strings::internal::Splitter<strings::delimiter::Literal, strings::AllowEmpty>::Splitter(GStringPiece, strings::delimiter::Literal, strings::AllowEmpty)
Line
Count
Source
233
101
      : begin_(text, d, p), end_(d, p) {}
234
235
  // Range functions that iterate the split substrings as GStringPiece objects.
236
  // These methods enable a Splitter to be used in a range-based for loop in
237
  // C++11, for example:
238
  //
239
  //   for (GStringPiece sp : my_splitter) {
240
  //     DoWork(sp);
241
  //   }
242
554k
  const Iterator& begin() const { return begin_; }
strings::internal::Splitter<strings::delimiter::Literal, strings::SkipEmpty>::begin() const
Line
Count
Source
242
332k
  const Iterator& begin() const { return begin_; }
strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::begin() const
Line
Count
Source
242
222k
  const Iterator& begin() const { return begin_; }
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::begin() const
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::begin() const
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::begin() const
strings::internal::Splitter<strings::delimiter::Literal, strings::AllowEmpty>::begin() const
Line
Count
Source
242
101
  const Iterator& begin() const { return begin_; }
243
0
  const Iterator& end() const { return end_; }
244
245
#ifdef LANG_CXX11
246
// Support for default template arguments for function templates was added in
247
// C++11, but it is not allowed if compiled in C++98 compatibility mode. Since
248
// this code is under a LANG_CXX11 guard, we can safely ignore the
249
// -Wc++98-compat flag and use default template arguments on the implicit
250
// conversion operator below.
251
//
252
// This use of default template arguments on a function template was approved
253
// by tgs and sanjay on behalf of the c-style-arbiters in email thread
254
//
255
// All compiler flags are first saved with a diagnostic push and restored with a
256
// diagnostic pop below.
257
#pragma GCC diagnostic push
258
#pragma GCC diagnostic ignored "-Wpragmas"
259
#pragma GCC diagnostic ignored "-Wc++98-compat"
260
261
  // Uses SFINAE to restrict conversion to container-like types (by testing for
262
  // the presence of a const_iterator member type) and also to disable
263
  // conversion to an initializer_list (which also has a const_iterator).
264
  // Otherwise, code compiled in C++11 will get an error due to ambiguous
265
  // conversion paths (in C++11 vector<T>::operator= is overloaded to take
266
  // either a vector<T> or an initializer_list<T>).
267
  //
268
  // This trick was taken from util/gtl/container_literal.h
269
  template <typename Container,
270
            typename IsNotInitializerListChecker =
271
                typename IsNotInitializerList<Container>::type,
272
            typename ContainerChecker =
273
                typename Container::const_iterator>
274
554k
  operator Container() {
275
554k
    return SelectContainer<Container, is_map<Container>::value>()(this);
276
554k
  }
strings::internal::Splitter<strings::delimiter::Literal, strings::SkipEmpty>::operator 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> > > >, void, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> >()
Line
Count
Source
274
332k
  operator Container() {
275
332k
    return SelectContainer<Container, is_map<Container>::value>()(this);
276
332k
  }
strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::operator 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> > > >, void, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> >()
Line
Count
Source
274
220k
  operator Container() {
275
220k
    return SelectContainer<Container, is_map<Container>::value>()(this);
276
220k
  }
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::operator 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> > > >, void, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> >()
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::operator std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> ><std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> >, void, std::__1::__wrap_iter<GStringPiece const*> >()
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::operator 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> > > >, void, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> >()
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::operator std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> ><std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> >, void, std::__1::__wrap_iter<GStringPiece const*> >()
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::operator 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> > > >, void, 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> >()
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::operator std::__1::map<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::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<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> > > > ><std::__1::map<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::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<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> > > > >, void, 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> > >()
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::operator std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> ><std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> >, void, std::__1::__wrap_iter<GStringPiece const*> >()
strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::operator std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> ><std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> >, void, std::__1::__wrap_iter<GStringPiece const*> >()
Line
Count
Source
274
1.27k
  operator Container() {
275
1.27k
    return SelectContainer<Container, is_map<Container>::value>()(this);
276
1.27k
  }
strings::internal::Splitter<strings::delimiter::Literal, strings::AllowEmpty>::operator 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> > > >, void, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> >()
Line
Count
Source
274
101
  operator Container() {
275
101
    return SelectContainer<Container, is_map<Container>::value>()(this);
276
101
  }
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::operator std::__1::list<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::list<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> > > >, void, std::__1::__list_const_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*> >()
277
278
// Restores diagnostic settings, i.e., removes the "ignore" on -Wpragmas and
279
// -Wc++98-compat.
280
#pragma GCC diagnostic pop
281
282
#else
283
  // Not under LANG_CXX11
284
  template <typename Container>
285
  operator Container() {
286
    return SelectContainer<Container, is_map<Container>::value>()(this);
287
  }
288
#endif  // LANG_CXX11
289
290
  template <typename First, typename Second>
291
  operator std::pair<First, Second>() {
292
    return ToPair<First, Second>();
293
  }
294
295
 private:
296
  // is_map<T>::value is true iff there exists a type T::mapped_type. This is
297
  // used to dispatch to one of the SelectContainer<> functors (below) from the
298
  // implicit conversion operator (above).
299
  template <typename T>
300
  struct is_map {
301
    template <typename U> static base::big_ test(typename U::mapped_type*);
302
    template <typename> static base::small_ test(...);
303
    static const bool value = (sizeof(test<T>(0)) == sizeof(base::big_));
304
  };
305
306
  // Base template handles splitting to non-map containers
307
  template <typename Container, bool>
308
  struct SelectContainer {
309
554k
    Container operator()(Splitter* splitter) const {
310
554k
      return splitter->template ToContainer<Container>();
311
554k
    }
strings::internal::Splitter<strings::delimiter::Literal, strings::SkipEmpty>::SelectContainer<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> > > >, false>::operator()(strings::internal::Splitter<strings::delimiter::Literal, strings::SkipEmpty>*) const
Line
Count
Source
309
332k
    Container operator()(Splitter* splitter) const {
310
332k
      return splitter->template ToContainer<Container>();
311
332k
    }
strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::SelectContainer<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> > > >, false>::operator()(strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>*) const
Line
Count
Source
309
220k
    Container operator()(Splitter* splitter) const {
310
220k
      return splitter->template ToContainer<Container>();
311
220k
    }
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::SelectContainer<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> > > >, false>::operator()(strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>*) const
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::SelectContainer<std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> >, false>::operator()(strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>*) const
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::SelectContainer<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> > > >, false>::operator()(strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>*) const
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::SelectContainer<std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> >, false>::operator()(strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>*) const
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::SelectContainer<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> > > >, false>::operator()(strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>*) const
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::SelectContainer<std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> >, false>::operator()(strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>*) const
strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::SelectContainer<std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> >, false>::operator()(strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>*) const
Line
Count
Source
309
1.27k
    Container operator()(Splitter* splitter) const {
310
1.27k
      return splitter->template ToContainer<Container>();
311
1.27k
    }
strings::internal::Splitter<strings::delimiter::Literal, strings::AllowEmpty>::SelectContainer<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> > > >, false>::operator()(strings::internal::Splitter<strings::delimiter::Literal, strings::AllowEmpty>*) const
Line
Count
Source
309
101
    Container operator()(Splitter* splitter) const {
310
101
      return splitter->template ToContainer<Container>();
311
101
    }
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::SelectContainer<std::__1::list<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> > > >, false>::operator()(strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>*) const
312
  };
313
314
  // Partial template specialization for splitting to map-like containers.
315
  template <typename Container>
316
  struct SelectContainer<Container, true> {
317
0
    Container operator()(Splitter* splitter) const {
318
0
      return splitter->template ToMap<Container>();
319
0
    }
320
  };
321
322
  // Inserts split results into the container. To do this the results are first
323
  // stored in a vector<GStringPiece>. This is where the input text is actually
324
  // "parsed". This vector is then used to possibly reserve space in the output
325
  // container, and the GStringPieces in "v" are converted as necessary to the
326
  // output container's value type.
327
  //
328
  // The reason to use an intermediate vector of GStringPiece is so we can learn
329
  // the needed capacity of the output container. This is needed when the output
330
  // container is a vector<string> in which case resizes can be expensive due to
331
  // copying of the ::string objects.
332
  //
333
  // At some point in the future we might add a C++11 move constructor to
334
  // ::string, in which case the vector resizes are much less expensive and the
335
  // use of this intermediate vector "v" can be removed.
336
  template <typename Container>
337
554k
  Container ToContainer() {
338
554k
    vector<GStringPiece> v;
339
1.75M
    for (Iterator it = begin(); it != end_; 
++it1.20M
) {
340
1.20M
      v.push_back(*it);
341
1.20M
    }
342
554k
    typedef typename Container::value_type ToType;
343
554k
    internal::GStringPieceTo<ToType> converter;
344
554k
    Container c;
345
554k
    ReserveCapacity(&c, v.size());
346
554k
    std::insert_iterator<Container> inserter(c, c.begin());
347
1.20M
    for (const auto& sp : v) {
348
1.20M
      *inserter++ = converter(sp);
349
1.20M
    }
350
554k
    return c;
351
554k
  }
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> > > > strings::internal::Splitter<strings::delimiter::Literal, strings::SkipEmpty>::ToContainer<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> > > > >()
Line
Count
Source
337
332k
  Container ToContainer() {
338
332k
    vector<GStringPiece> v;
339
731k
    for (Iterator it = begin(); it != end_; 
++it399k
) {
340
399k
      v.push_back(*it);
341
399k
    }
342
332k
    typedef typename Container::value_type ToType;
343
332k
    internal::GStringPieceTo<ToType> converter;
344
332k
    Container c;
345
332k
    ReserveCapacity(&c, v.size());
346
332k
    std::insert_iterator<Container> inserter(c, c.begin());
347
398k
    for (const auto& sp : v) {
348
398k
      *inserter++ = converter(sp);
349
398k
    }
350
332k
    return c;
351
332k
  }
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> > > > strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::ToContainer<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> > > > >()
Line
Count
Source
337
220k
  Container ToContainer() {
338
220k
    vector<GStringPiece> v;
339
1.02M
    for (Iterator it = begin(); it != end_; 
++it799k
) {
340
799k
      v.push_back(*it);
341
799k
    }
342
220k
    typedef typename Container::value_type ToType;
343
220k
    internal::GStringPieceTo<ToType> converter;
344
220k
    Container c;
345
220k
    ReserveCapacity(&c, v.size());
346
220k
    std::insert_iterator<Container> inserter(c, c.begin());
347
799k
    for (const auto& sp : v) {
348
799k
      *inserter++ = converter(sp);
349
799k
    }
350
220k
    return c;
351
220k
  }
Unexecuted instantiation: 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> > > > strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::ToContainer<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> > > > >()
Unexecuted instantiation: std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> > strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::ToContainer<std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> > >()
Unexecuted instantiation: 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> > > > strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::ToContainer<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> > > > >()
Unexecuted instantiation: std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> > strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::ToContainer<std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> > >()
Unexecuted instantiation: 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> > > > strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::ToContainer<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> > > > >()
Unexecuted instantiation: std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> > strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::ToContainer<std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> > >()
std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> > strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::ToContainer<std::__1::vector<GStringPiece, std::__1::allocator<GStringPiece> > >()
Line
Count
Source
337
1.27k
  Container ToContainer() {
338
1.27k
    vector<GStringPiece> v;
339
3.18k
    for (Iterator it = begin(); it != end_; 
++it1.90k
) {
340
1.90k
      v.push_back(*it);
341
1.90k
    }
342
1.27k
    typedef typename Container::value_type ToType;
343
1.27k
    internal::GStringPieceTo<ToType> converter;
344
1.27k
    Container c;
345
1.27k
    ReserveCapacity(&c, v.size());
346
1.27k
    std::insert_iterator<Container> inserter(c, c.begin());
347
1.90k
    for (const auto& sp : v) {
348
1.90k
      *inserter++ = converter(sp);
349
1.90k
    }
350
1.27k
    return c;
351
1.27k
  }
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> > > > strings::internal::Splitter<strings::delimiter::Literal, strings::AllowEmpty>::ToContainer<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> > > > >()
Line
Count
Source
337
101
  Container ToContainer() {
338
101
    vector<GStringPiece> v;
339
313
    for (Iterator it = begin(); it != end_; 
++it212
) {
340
212
      v.push_back(*it);
341
212
    }
342
101
    typedef typename Container::value_type ToType;
343
101
    internal::GStringPieceTo<ToType> converter;
344
101
    Container c;
345
101
    ReserveCapacity(&c, v.size());
346
101
    std::insert_iterator<Container> inserter(c, c.begin());
347
212
    for (const auto& sp : v) {
348
212
      *inserter++ = converter(sp);
349
212
    }
350
101
    return c;
351
101
  }
Unexecuted instantiation: std::__1::list<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> > > > strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::ToContainer<std::__1::list<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> > > > >()
352
353
  // The algorithm is to insert a new pair into the map for each even-numbered
354
  // item, with the even-numbered item as the key with a default-constructed
355
  // value. Each odd-numbered item will then be assigned to the last pair's
356
  // value.
357
  template <typename Map>
358
0
  Map ToMap() {
359
0
    typedef typename Map::key_type Key;
360
0
    typedef typename Map::mapped_type Data;
361
0
    Map m;
362
0
    GStringPieceTo<Key> key_converter;
363
0
    GStringPieceTo<Data> val_converter;
364
0
    typename Map::iterator curr_pair;
365
0
    bool is_even = true;
366
0
    for (Iterator it = begin(); it != end_; ++it) {
367
0
      if (is_even) {
368
0
        curr_pair = InsertInMap(std::make_pair(key_converter(*it), Data()), &m);
369
0
      } else {
370
0
        curr_pair->second = val_converter(*it);
371
0
      }
372
0
      is_even = !is_even;
373
0
    }
374
0
    return m;
375
0
  }
376
377
  // Returns a pair with its .first and .second members set to the first two
378
  // strings returned by the begin() iterator. Either/both of .first and .second
379
  // will be empty strings if the iterator doesn't have a corresponding value.
380
  template <typename First, typename Second>
381
  std::pair<First, Second> ToPair() {
382
    GStringPieceTo<First> first_converter;
383
    GStringPieceTo<Second> second_converter;
384
    GStringPiece first, second;
385
    Iterator it = begin();
386
    if (it != end()) {
387
      first = *it;
388
      if (++it != end()) {
389
        second = *it;
390
      }
391
    }
392
    return std::make_pair(first_converter(first), second_converter(second));
393
  }
394
395
  // Overloaded InsertInMap() function. The first overload is the commonly used
396
  // one for most map-like objects. The second overload is a special case for
397
  // multimap, because multimap's insert() member function directly returns an
398
  // iterator, rather than a pair<iterator, bool> like map's.
399
  template <typename Map>
400
  typename Map::iterator InsertInMap(
401
0
      const typename Map::value_type& value, Map* map) {
402
0
    return map->insert(value).first;
403
0
  }
404
405
  // InsertInMap overload for multimap.
406
  template <typename K, typename T, typename C, typename A>
407
  typename std::multimap<K, T, C, A>::iterator InsertInMap(
408
      const typename std::multimap<K, T, C, A>::value_type& value,
409
      typename std::multimap<K, T, C, A>* map) {
410
    return map->insert(value);
411
  }
412
413
  // Reserves the given amount of capacity in a vector<string>
414
  template <typename A>
415
553k
  void ReserveCapacity(vector<string, A>* v, size_t size) {
416
553k
    v->reserve(size);
417
553k
  }
void strings::internal::Splitter<strings::delimiter::Literal, strings::SkipEmpty>::ReserveCapacity<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> > > >*, unsigned long)
Line
Count
Source
415
332k
  void ReserveCapacity(vector<string, A>* v, size_t size) {
416
332k
    v->reserve(size);
417
332k
  }
void strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::ReserveCapacity<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> > > >*, unsigned long)
Line
Count
Source
415
220k
  void ReserveCapacity(vector<string, A>* v, size_t size) {
416
220k
    v->reserve(size);
417
220k
  }
Unexecuted instantiation: void strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::ReserveCapacity<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> > > >*, unsigned long)
Unexecuted instantiation: void strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::ReserveCapacity<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> > > >*, unsigned long)
void strings::internal::Splitter<strings::delimiter::Literal, strings::AllowEmpty>::ReserveCapacity<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> > > >*, unsigned long)
Line
Count
Source
415
101
  void ReserveCapacity(vector<string, A>* v, size_t size) {
416
101
    v->reserve(size);
417
101
  }
418
1.27k
  void ReserveCapacity(...) {}
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::internal::NoFilter>::ReserveCapacity(...)
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::LimitImpl<strings::delimiter::AnyOf>, strings::internal::NoFilter>::ReserveCapacity(...)
Unexecuted instantiation: strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::ReserveCapacity(...)
strings::internal::Splitter<strings::delimiter::Literal, strings::internal::NoFilter>::ReserveCapacity(...)
Line
Count
Source
418
1.27k
  void ReserveCapacity(...) {}
419
420
  const Iterator begin_;
421
  const Iterator end_;
422
};
423
424
}  // namespace internal
425
426
}  // namespace strings
427
428
#endif  // YB_GUTIL_STRINGS_SPLIT_INTERNAL_H