str_join.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 // File: str_join.h
18 // -----------------------------------------------------------------------------
19 //
20 // This header file contains functions for joining a range of elements and
21 // returning the result as a std::string. StrJoin operations are specified by
22 // passing a range, a separator string to use between the elements joined, and
23 // an optional Formatter responsible for converting each argument in the range
24 // to a string. If omitted, a default `AlphaNumFormatter()` is called on the
25 // elements to be joined, using the same formatting that `absl::StrCat()` uses.
26 // This package defines a number of default formatters, and you can define your
27 // own implementations.
28 //
29 // Ranges are specified by passing a container with `std::begin()` and
30 // `std::end()` iterators, container-specific `begin()` and `end()` iterators, a
31 // brace-initialized `std::initializer_list`, or a `std::tuple` of heterogeneous
32 // objects. The separator string is specified as an `absl::string_view`.
33 //
34 // Because the default formatter uses the `absl::AlphaNum` class,
35 // `absl::StrJoin()`, like `absl::StrCat()`, will work out-of-the-box on
36 // collections of strings, ints, floats, doubles, etc.
37 //
38 // Example:
39 //
40 // std::vector<std::string> v = {"foo", "bar", "baz"};
41 // std::string s = absl::StrJoin(v, "-");
42 // EXPECT_EQ("foo-bar-baz", s);
43 //
44 // See comments on the `absl::StrJoin()` function for more examples.
45 
46 #ifndef ABSL_STRINGS_STR_JOIN_H_
47 #define ABSL_STRINGS_STR_JOIN_H_
48 
49 #include <cstdio>
50 #include <cstring>
51 #include <initializer_list>
52 #include <iterator>
53 #include <string>
54 #include <tuple>
55 #include <type_traits>
56 #include <utility>
57 
58 #include "absl/base/macros.h"
61 
62 namespace absl {
63 
64 // -----------------------------------------------------------------------------
65 // Concept: Formatter
66 // -----------------------------------------------------------------------------
67 //
68 // A Formatter is a function object that is responsible for formatting its
69 // argument as a string and appending it to a given output std::string.
70 // Formatters may be implemented as function objects, lambdas, or normal
71 // functions. You may provide your own Formatter to enable `absl::StrJoin()` to
72 // work with arbitrary types.
73 //
74 // The following is an example of a custom Formatter that simply uses
75 // `std::to_string()` to format an integer as a std::string.
76 //
77 // struct MyFormatter {
78 // void operator()(std::string* out, int i) const {
79 // out->append(std::to_string(i));
80 // }
81 // };
82 //
83 // You would use the above formatter by passing an instance of it as the final
84 // argument to `absl::StrJoin()`:
85 //
86 // std::vector<int> v = {1, 2, 3, 4};
87 // std::string s = absl::StrJoin(v, "-", MyFormatter());
88 // EXPECT_EQ("1-2-3-4", s);
89 //
90 // The following standard formatters are provided within this file:
91 //
92 // - `AlphaNumFormatter()` (the default)
93 // - `StreamFormatter()`
94 // - `PairFormatter()`
95 // - `DereferenceFormatter()`
96 
97 // AlphaNumFormatter()
98 //
99 // Default formatter used if none is specified. Uses `absl::AlphaNum` to convert
100 // numeric arguments to strings.
103 }
104 
105 // StreamFormatter()
106 //
107 // Formats its argument using the << operator.
110 }
111 
112 // Function Template: PairFormatter(Formatter, absl::string_view, Formatter)
113 //
114 // Formats a `std::pair` by putting a given separator between the pair's
115 // `.first` and `.second` members. This formatter allows you to specify
116 // custom Formatters for both the first and second member of each pair.
117 template <typename FirstFormatter, typename SecondFormatter>
119 PairFormatter(FirstFormatter f1, absl::string_view sep, SecondFormatter f2) {
121  std::move(f1), sep, std::move(f2));
122 }
123 
124 // Function overload of PairFormatter() for using a default
125 // `AlphaNumFormatter()` for each Formatter in the pair.
128  strings_internal::AlphaNumFormatterImpl>
131 }
132 
133 // Function Template: DereferenceFormatter(Formatter)
134 //
135 // Formats its argument by dereferencing it and then applying the given
136 // formatter. This formatter is useful for formatting a container of
137 // pointer-to-T. This pattern often shows up when joining repeated fields in
138 // protocol buffers.
139 template <typename Formatter>
141  Formatter&& f) {
143  std::forward<Formatter>(f));
144 }
145 
146 // Function overload of `DererefenceFormatter()` for using a default
147 // `AlphaNumFormatter()`.
149  strings_internal::AlphaNumFormatterImpl>
152  strings_internal::AlphaNumFormatterImpl>(AlphaNumFormatter());
153 }
154 
155 // -----------------------------------------------------------------------------
156 // StrJoin()
157 // -----------------------------------------------------------------------------
158 //
159 // Joins a range of elements and returns the result as a std::string.
160 // `absl::StrJoin()` takes a range, a separator string to use between the
161 // elements joined, and an optional Formatter responsible for converting each
162 // argument in the range to a string.
163 //
164 // If omitted, the default `AlphaNumFormatter()` is called on the elements to be
165 // joined.
166 //
167 // Example 1:
168 // // Joins a collection of strings. This pattern also works with a collection
169 // // of `absl::string_view` or even `const char*`.
170 // std::vector<std::string> v = {"foo", "bar", "baz"};
171 // std::string s = absl::StrJoin(v, "-");
172 // EXPECT_EQ("foo-bar-baz", s);
173 //
174 // Example 2:
175 // // Joins the values in the given `std::initializer_list<>` specified using
176 // // brace initialization. This pattern also works with an initializer_list
177 // // of ints or `absl::string_view` -- any `AlphaNum`-compatible type.
178 // std::string s = absl::StrJoin({"foo", "bar", "baz"}, "-");
179 // EXPECT_EQ("foo-bar-baz", s);
180 //
181 // Example 3:
182 // // Joins a collection of ints. This pattern also works with floats,
183 // // doubles, int64s -- any `StrCat()`-compatible type.
184 // std::vector<int> v = {1, 2, 3, -4};
185 // std::string s = absl::StrJoin(v, "-");
186 // EXPECT_EQ("1-2-3--4", s);
187 //
188 // Example 4:
189 // // Joins a collection of pointer-to-int. By default, pointers are
190 // // dereferenced and the pointee is formatted using the default format for
191 // // that type; such dereferencing occurs for all levels of indirection, so
192 // // this pattern works just as well for `std::vector<int**>` as for
193 // // `std::vector<int*>`.
194 // int x = 1, y = 2, z = 3;
195 // std::vector<int*> v = {&x, &y, &z};
196 // std::string s = absl::StrJoin(v, "-");
197 // EXPECT_EQ("1-2-3", s);
198 //
199 // Example 5:
200 // // Dereferencing of `std::unique_ptr<>` is also supported:
201 // std::vector<std::unique_ptr<int>> v
202 // v.emplace_back(new int(1));
203 // v.emplace_back(new int(2));
204 // v.emplace_back(new int(3));
205 // std::string s = absl::StrJoin(v, "-");
206 // EXPECT_EQ("1-2-3", s);
207 //
208 // Example 6:
209 // // Joins a `std::map`, with each key-value pair separated by an equals
210 // // sign. This pattern would also work with, say, a
211 // // `std::vector<std::pair<>>`.
212 // std::map<std::string, int> m = {
213 // std::make_pair("a", 1),
214 // std::make_pair("b", 2),
215 // std::make_pair("c", 3)};
216 // std::string s = absl::StrJoin(m, ",", absl::PairFormatter("="));
217 // EXPECT_EQ("a=1,b=2,c=3", s);
218 //
219 // Example 7:
220 // // These examples show how `absl::StrJoin()` handles a few common edge
221 // // cases:
222 // std::vector<std::string> v_empty;
223 // EXPECT_EQ("", absl::StrJoin(v_empty, "-"));
224 //
225 // std::vector<std::string> v_one_item = {"foo"};
226 // EXPECT_EQ("foo", absl::StrJoin(v_one_item, "-"));
227 //
228 // std::vector<std::string> v_empty_string = {""};
229 // EXPECT_EQ("", absl::StrJoin(v_empty_string, "-"));
230 //
231 // std::vector<std::string> v_one_item_empty_string = {"a", ""};
232 // EXPECT_EQ("a-", absl::StrJoin(v_one_item_empty_string, "-"));
233 //
234 // std::vector<std::string> v_two_empty_string = {"", ""};
235 // EXPECT_EQ("-", absl::StrJoin(v_two_empty_string, "-"));
236 //
237 // Example 8:
238 // // Joins a `std::tuple<T...>` of heterogeneous types, converting each to
239 // // a std::string using the `absl::AlphaNum` class.
240 // std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
241 // EXPECT_EQ("123-abc-0.456", s);
242 
243 template <typename Iterator, typename Formatter>
244 std::string StrJoin(Iterator start, Iterator end, absl::string_view sep,
245  Formatter&& fmt) {
246  return strings_internal::JoinAlgorithm(start, end, sep, fmt);
247 }
248 
249 template <typename Range, typename Formatter>
250 std::string StrJoin(const Range& range, absl::string_view separator,
251  Formatter&& fmt) {
252  return strings_internal::JoinRange(range, separator, fmt);
253 }
254 
255 template <typename T, typename Formatter>
256 std::string StrJoin(std::initializer_list<T> il, absl::string_view separator,
257  Formatter&& fmt) {
258  return strings_internal::JoinRange(il, separator, fmt);
259 }
260 
261 template <typename... T, typename Formatter>
262 std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator,
263  Formatter&& fmt) {
264  return strings_internal::JoinAlgorithm(value, separator, fmt);
265 }
266 
267 template <typename Iterator>
268 std::string StrJoin(Iterator start, Iterator end, absl::string_view separator) {
269  return strings_internal::JoinRange(start, end, separator);
270 }
271 
272 template <typename Range>
273 std::string StrJoin(const Range& range, absl::string_view separator) {
274  return strings_internal::JoinRange(range, separator);
275 }
276 
277 template <typename T>
278 std::string StrJoin(std::initializer_list<T> il, absl::string_view separator) {
279  return strings_internal::JoinRange(il, separator);
280 }
281 
282 template <typename... T>
283 std::string StrJoin(const std::tuple<T...>& value,
284  absl::string_view separator) {
285  return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter());
286 }
287 
288 } // namespace absl
289 
290 #endif // ABSL_STRINGS_STR_JOIN_H_
std::string StrJoin(Iterator start, Iterator end, absl::string_view sep, Formatter &&fmt)
Definition: str_join.h:244
strings_internal::PairFormatterImpl< FirstFormatter, SecondFormatter > PairFormatter(FirstFormatter f1, absl::string_view sep, SecondFormatter f2)
Definition: str_join.h:119
char * end
std::string JoinRange(Iterator first, Iterator last, absl::string_view separator)
Definition: algorithm.h:29
std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s, Formatter &&f)
strings_internal::AlphaNumFormatterImpl AlphaNumFormatter()
Definition: str_join.h:101
size_t value
strings_internal::DereferenceFormatterImpl< Formatter > DereferenceFormatter(Formatter &&f)
Definition: str_join.h:140
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: utility.h:219
strings_internal::StreamFormatterImpl StreamFormatter()
Definition: str_join.h:108


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:20