abseil-cpp/absl/strings/internal/str_join_internal.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 // This file declares INTERNAL parts of the Join API that are inlined/templated
18 // or otherwise need to be available at compile time. The main abstractions
19 // defined in this file are:
20 //
21 // - A handful of default Formatters
22 // - JoinAlgorithm() overloads
23 // - JoinRange() overloads
24 // - JoinTuple()
25 //
26 // DO NOT INCLUDE THIS FILE DIRECTLY. Use this file by including
27 // absl/strings/str_join.h
28 //
29 // IWYU pragma: private, include "absl/strings/str_join.h"
30 
31 #ifndef ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_
32 #define ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_
33 
34 #include <cstring>
35 #include <iterator>
36 #include <memory>
37 #include <string>
38 #include <type_traits>
39 #include <utility>
40 
41 #include "absl/strings/internal/ostringstream.h"
42 #include "absl/strings/internal/resize_uninitialized.h"
43 #include "absl/strings/str_cat.h"
44 
45 namespace absl {
47 namespace strings_internal {
48 
49 //
50 // Formatter objects
51 //
52 // The following are implementation classes for standard Formatter objects. The
53 // factory functions that users will call to create and use these formatters are
54 // defined and documented in strings/join.h.
55 //
56 
57 // The default formatter. Converts alpha-numeric types to strings.
59  // This template is needed in order to support passing in a dereferenced
60  // vector<bool>::iterator
61  template <typename T>
62  void operator()(std::string* out, const T& t) const {
63  StrAppend(out, AlphaNum(t));
64  }
65 
66  void operator()(std::string* out, const AlphaNum& t) const {
67  StrAppend(out, t);
68  }
69 };
70 
71 // A type that's used to overload the JoinAlgorithm() function (defined below)
72 // for ranges that do not require additional formatting (e.g., a range of
73 // strings).
74 
76 
77 // Formats types to strings using the << operator.
79  public:
80  // The method isn't const because it mutates state. Making it const will
81  // render StreamFormatterImpl thread-hostile.
82  template <typename T>
83  void operator()(std::string* out, const T& t) {
84  // The stream is created lazily to avoid paying the relatively high cost
85  // of its construction when joining an empty range.
86  if (strm_) {
87  strm_->clear(); // clear the bad, fail and eof bits in case they were set
88  strm_->str(out);
89  } else {
91  }
92  *strm_ << t;
93  }
94 
95  private:
96  std::unique_ptr<strings_internal::OStringStream> strm_;
97 };
98 
99 // Formats a std::pair<>. The 'first' member is formatted using f1_ and the
100 // 'second' member is formatted using f2_. sep_ is the separator.
101 template <typename F1, typename F2>
103  public:
105  : f1_(std::move(f1)), sep_(sep), f2_(std::move(f2)) {}
106 
107  template <typename T>
108  void operator()(std::string* out, const T& p) {
109  f1_(out, p.first);
110  out->append(sep_);
111  f2_(out, p.second);
112  }
113 
114  template <typename T>
115  void operator()(std::string* out, const T& p) const {
116  f1_(out, p.first);
117  out->append(sep_);
118  f2_(out, p.second);
119  }
120 
121  private:
125 };
126 
127 // Wraps another formatter and dereferences the argument to operator() then
128 // passes the dereferenced argument to the wrapped formatter. This can be
129 // useful, for example, to join a std::vector<int*>.
130 template <typename Formatter>
132  public:
135  : f_(std::forward<Formatter>(f)) {}
136 
137  template <typename T>
138  void operator()(std::string* out, const T& t) {
139  f_(out, *t);
140  }
141 
142  template <typename T>
143  void operator()(std::string* out, const T& t) const {
144  f_(out, *t);
145  }
146 
147  private:
149 };
150 
151 // DefaultFormatter<T> is a traits class that selects a default Formatter to use
152 // for the given type T. The ::Type member names the Formatter to use. This is
153 // used by the strings::Join() functions that do NOT take a Formatter argument,
154 // in which case a default Formatter must be chosen.
155 //
156 // AlphaNumFormatterImpl is the default in the base template, followed by
157 // specializations for other types.
158 template <typename ValueType>
161 };
162 template <>
163 struct DefaultFormatter<const char*> {
165 };
166 template <>
167 struct DefaultFormatter<char*> {
169 };
170 template <>
172  typedef NoFormatter Type;
173 };
174 template <>
176  typedef NoFormatter Type;
177 };
178 template <typename ValueType>
182 };
183 
184 template <typename ValueType>
185 struct DefaultFormatter<std::unique_ptr<ValueType>>
186  : public DefaultFormatter<ValueType*> {};
187 
188 //
189 // JoinAlgorithm() functions
190 //
191 
192 // The main joining algorithm. This simply joins the elements in the given
193 // iterator range, each separated by the given separator, into an output string,
194 // and formats each element using the provided Formatter object.
195 template <typename Iterator, typename Formatter>
197  Formatter&& f) {
200  for (Iterator it = start; it != end; ++it) {
201  result.append(sep.data(), sep.size());
202  f(&result, *it);
203  sep = s;
204  }
205  return result;
206 }
207 
208 // A joining algorithm that's optimized for a forward iterator range of
209 // string-like objects that do not need any additional formatting. This is to
210 // optimize the common case of joining, say, a std::vector<string> or a
211 // std::vector<absl::string_view>.
212 //
213 // This is an overload of the previous JoinAlgorithm() function. Here the
214 // Formatter argument is of type NoFormatter. Since NoFormatter is an internal
215 // type, this overload is only invoked when strings::Join() is called with a
216 // range of string-like objects (e.g., std::string, absl::string_view), and an
217 // explicit Formatter argument was NOT specified.
218 //
219 // The optimization is that the needed space will be reserved in the output
220 // string to avoid the need to resize while appending. To do this, the iterator
221 // range will be traversed twice: once to calculate the total needed size, and
222 // then again to copy the elements and delimiters to the output string.
223 template <typename Iterator,
224  typename = typename std::enable_if<std::is_convertible<
225  typename std::iterator_traits<Iterator>::iterator_category,
226  std::forward_iterator_tag>::value>::type>
228  NoFormatter) {
230  if (start != end) {
231  // Sums size
232  auto&& start_value = *start;
233  size_t result_size = start_value.size();
234  for (Iterator it = start; ++it != end;) {
235  result_size += s.size();
236  result_size += (*it).size();
237  }
238 
239  if (result_size > 0) {
240  STLStringResizeUninitialized(&result, result_size);
241 
242  // Joins strings
243  char* result_buf = &*result.begin();
244 
245  memcpy(result_buf, start_value.data(), start_value.size());
246  result_buf += start_value.size();
247  for (Iterator it = start; ++it != end;) {
248  memcpy(result_buf, s.data(), s.size());
249  result_buf += s.size();
250  auto&& value = *it;
251  memcpy(result_buf, value.data(), value.size());
252  result_buf += value.size();
253  }
254  }
255  }
256 
257  return result;
258 }
259 
260 // JoinTupleLoop implements a loop over the elements of a std::tuple, which
261 // are heterogeneous. The primary template matches the tuple interior case. It
262 // continues the iteration after appending a separator (for nonzero indices)
263 // and formatting an element of the tuple. The specialization for the I=N case
264 // matches the end-of-tuple, and terminates the iteration.
265 template <size_t I, size_t N>
267  template <typename Tup, typename Formatter>
269  Formatter&& fmt) {
270  if (I > 0) out->append(sep.data(), sep.size());
271  fmt(out, std::get<I>(tup));
273  }
274 };
275 template <size_t N>
276 struct JoinTupleLoop<N, N> {
277  template <typename Tup, typename Formatter>
279 };
280 
281 template <typename... T, typename Formatter>
282 std::string JoinAlgorithm(const std::tuple<T...>& tup, absl::string_view sep,
283  Formatter&& fmt) {
285  JoinTupleLoop<0, sizeof...(T)>()(&result, tup, sep, fmt);
286  return result;
287 }
288 
289 template <typename Iterator>
291  absl::string_view separator) {
292  // No formatter was explicitly given, so a default must be chosen.
295  return JoinAlgorithm(first, last, separator, Formatter());
296 }
297 
298 template <typename Range, typename Formatter>
300  Formatter&& fmt) {
301  using std::begin;
302  using std::end;
303  return JoinAlgorithm(begin(range), end(range), separator, fmt);
304 }
305 
306 template <typename Range>
308  using std::begin;
309  using std::end;
310  return JoinRange(begin(range), end(range), separator);
311 }
312 
313 } // namespace strings_internal
315 } // namespace absl
316 
317 #endif // ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_
absl::strings_internal::StreamFormatterImpl::operator()
void operator()(std::string *out, const T &t)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:83
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
regen-readme.it
it
Definition: regen-readme.py:15
absl::StrAppend
void StrAppend(std::string *dest, const AlphaNum &a)
Definition: abseil-cpp/absl/strings/str_cat.cc:193
const
#define const
Definition: bloaty/third_party/zlib/zconf.h:230
begin
char * begin
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1007
absl::strings_internal::AlphaNumFormatterImpl::operator()
void operator()(std::string *out, const AlphaNum &t) const
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:66
absl::strings_internal::DefaultFormatter< char * >::Type
AlphaNumFormatterImpl Type
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:168
capstone.range
range
Definition: third_party/bloaty/third_party/capstone/bindings/python/capstone/__init__.py:6
xds_manager.f1
f1
Definition: xds_manager.py:42
absl::strings_internal::JoinTupleLoop
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:266
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
absl::strings_internal::PairFormatterImpl::operator()
void operator()(std::string *out, const T &p) const
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:115
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::strings_internal::StreamFormatterImpl::strm_
std::unique_ptr< strings_internal::OStringStream > strm_
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:96
absl::strings_internal::PairFormatterImpl
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:102
absl::strings_internal::OStringStream
Definition: abseil-cpp/absl/strings/internal/ostringstream.h:63
absl::FormatConversionChar::s
@ s
absl::strings_internal::PairFormatterImpl::f2_
F2 f2_
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:124
absl::strings_internal::JoinTupleLoop::operator()
void operator()(std::string *out, const Tup &tup, absl::string_view sep, Formatter &&fmt)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:268
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
T
#define T(upbtypeconst, upbtype, ctype, default_value)
absl::strings_internal::JoinRange
std::string JoinRange(Iterator first, Iterator last, absl::string_view separator)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:290
absl::strings_internal::PairFormatterImpl::f1_
F1 f1_
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:122
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
start
static uint64_t start
Definition: benchmark-pound.c:74
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::strings_internal::NoFormatter
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:75
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
absl::strings_internal::AlphaNumFormatterImpl
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:58
absl::strings_internal::PairFormatterImpl::sep_
std::string sep_
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:123
absl::AlphaNum
Definition: abseil-cpp/absl/strings/str_cat.h:211
text_format_test_wrapper.sep
sep
Definition: text_format_test_wrapper.py:34
absl::strings_internal::DereferenceFormatterImpl::DereferenceFormatterImpl
DereferenceFormatterImpl()
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:133
absl::strings_internal::PairFormatterImpl::operator()
void operator()(std::string *out, const T &p)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:108
absl::strings_internal::JoinTupleLoop< N, N >::operator()
void operator()(std::string *, const Tup &, absl::string_view, Formatter &&)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:278
absl::compare_internal::value_type
int8_t value_type
Definition: abseil-cpp/absl/types/compare.h:45
absl::strings_internal::DefaultFormatter< std::string >::Type
NoFormatter Type
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:172
absl::strings_internal::JoinAlgorithm
std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s, Formatter &&f)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:196
Json::ValueType
ValueType
Type of the value held by a Value object.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:463
absl::strings_internal::DefaultFormatter::Type
AlphaNumFormatterImpl Type
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:160
absl::strings_internal::DereferenceFormatterImpl::f_
Formatter f_
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:148
value
const char * value
Definition: hpack_parser_table.cc:165
testing::internal::fmt
GTEST_API_ const char * fmt
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1808
absl::strings_internal::DefaultFormatter
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:159
absl::strings_internal::DereferenceFormatterImpl::DereferenceFormatterImpl
DereferenceFormatterImpl(Formatter &&f)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:134
N
#define N
Definition: sync_test.cc:37
I
#define I(b, c, d)
Definition: md5.c:120
Range
Range(0, 512)
absl::strings_internal::STLStringResizeUninitialized
void STLStringResizeUninitialized(string_type *s, size_t new_size)
Definition: abseil-cpp/absl/strings/internal/resize_uninitialized.h:67
absl::strings_internal::DereferenceFormatterImpl
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:131
absl::strings_internal::DereferenceFormatterImpl::operator()
void operator()(std::string *out, const T &t) const
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:143
absl::strings_internal::DereferenceFormatterImpl::operator()
void operator()(std::string *out, const T &t)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:138
F2
#define F2(x, y, z)
Definition: ripemd.c:110
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
first
StrT first
Definition: cxa_demangle.cpp:4884
F1
#define F1(x, y, z)
Definition: ripemd.c:109
absl::inlined_vector_internal::Iterator
Pointer< A > Iterator
Definition: abseil-cpp/absl/container/internal/inlined_vector.h:64
absl::strings_internal::DefaultFormatter< absl::string_view >::Type
NoFormatter Type
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:176
absl::strings_internal::DefaultFormatter< const char * >::Type
AlphaNumFormatterImpl Type
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:164
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
xds_manager.f2
f2
Definition: xds_manager.py:85
absl::strings_internal::StreamFormatterImpl
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:78
absl::forward
constexpr T && forward(absl::remove_reference_t< T > &t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:230
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
absl::out
char * out
Definition: abseil-cpp/absl/synchronization/mutex.h:1048
absl::strings_internal::AlphaNumFormatterImpl::operator()
void operator()(std::string *out, const T &t) const
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:62
absl::strings_internal::PairFormatterImpl::PairFormatterImpl
PairFormatterImpl(F1 f1, absl::string_view sep, F2 f2)
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:104
framework.helpers.highlighter.Formatter
Formatter
Definition: highlighter.py:53
absl::strings_internal::DefaultFormatter< ValueType * >::Type
DereferenceFormatterImpl< typename DefaultFormatter< ValueType >::Type > Type
Definition: abseil-cpp/absl/strings/internal/str_join_internal.h:181


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:20