xref: /aosp_15_r20/external/abseil-cpp/absl/strings/str_join.h (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker //
2*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
3*9356374aSAndroid Build Coastguard Worker //
4*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*9356374aSAndroid Build Coastguard Worker //
8*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
9*9356374aSAndroid Build Coastguard Worker //
10*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*9356374aSAndroid Build Coastguard Worker // limitations under the License.
15*9356374aSAndroid Build Coastguard Worker //
16*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
17*9356374aSAndroid Build Coastguard Worker // File: str_join.h
18*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
19*9356374aSAndroid Build Coastguard Worker //
20*9356374aSAndroid Build Coastguard Worker // This header file contains functions for joining a range of elements and
21*9356374aSAndroid Build Coastguard Worker // returning the result as a std::string. StrJoin operations are specified by
22*9356374aSAndroid Build Coastguard Worker // passing a range, a separator string to use between the elements joined, and
23*9356374aSAndroid Build Coastguard Worker // an optional Formatter responsible for converting each argument in the range
24*9356374aSAndroid Build Coastguard Worker // to a string. If omitted, a default `AlphaNumFormatter()` is called on the
25*9356374aSAndroid Build Coastguard Worker // elements to be joined, using the same formatting that `absl::StrCat()` uses.
26*9356374aSAndroid Build Coastguard Worker // This package defines a number of default formatters, and you can define your
27*9356374aSAndroid Build Coastguard Worker // own implementations.
28*9356374aSAndroid Build Coastguard Worker //
29*9356374aSAndroid Build Coastguard Worker // Ranges are specified by passing a container with `std::begin()` and
30*9356374aSAndroid Build Coastguard Worker // `std::end()` iterators, container-specific `begin()` and `end()` iterators, a
31*9356374aSAndroid Build Coastguard Worker // brace-initialized `std::initializer_list`, or a `std::tuple` of heterogeneous
32*9356374aSAndroid Build Coastguard Worker // objects. The separator string is specified as an `absl::string_view`.
33*9356374aSAndroid Build Coastguard Worker //
34*9356374aSAndroid Build Coastguard Worker // Because the default formatter uses the `absl::AlphaNum` class,
35*9356374aSAndroid Build Coastguard Worker // `absl::StrJoin()`, like `absl::StrCat()`, will work out-of-the-box on
36*9356374aSAndroid Build Coastguard Worker // collections of strings, ints, floats, doubles, etc.
37*9356374aSAndroid Build Coastguard Worker //
38*9356374aSAndroid Build Coastguard Worker // Example:
39*9356374aSAndroid Build Coastguard Worker //
40*9356374aSAndroid Build Coastguard Worker //   std::vector<std::string> v = {"foo", "bar", "baz"};
41*9356374aSAndroid Build Coastguard Worker //   std::string s = absl::StrJoin(v, "-");
42*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ("foo-bar-baz", s);
43*9356374aSAndroid Build Coastguard Worker //
44*9356374aSAndroid Build Coastguard Worker // See comments on the `absl::StrJoin()` function for more examples.
45*9356374aSAndroid Build Coastguard Worker 
46*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_STRINGS_STR_JOIN_H_
47*9356374aSAndroid Build Coastguard Worker #define ABSL_STRINGS_STR_JOIN_H_
48*9356374aSAndroid Build Coastguard Worker 
49*9356374aSAndroid Build Coastguard Worker #include <cstdio>
50*9356374aSAndroid Build Coastguard Worker #include <cstring>
51*9356374aSAndroid Build Coastguard Worker #include <initializer_list>
52*9356374aSAndroid Build Coastguard Worker #include <iterator>
53*9356374aSAndroid Build Coastguard Worker #include <string>
54*9356374aSAndroid Build Coastguard Worker #include <tuple>
55*9356374aSAndroid Build Coastguard Worker #include <type_traits>
56*9356374aSAndroid Build Coastguard Worker #include <utility>
57*9356374aSAndroid Build Coastguard Worker 
58*9356374aSAndroid Build Coastguard Worker #include "absl/base/macros.h"
59*9356374aSAndroid Build Coastguard Worker #include "absl/strings/internal/str_join_internal.h"
60*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
61*9356374aSAndroid Build Coastguard Worker 
62*9356374aSAndroid Build Coastguard Worker namespace absl {
63*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
64*9356374aSAndroid Build Coastguard Worker 
65*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
66*9356374aSAndroid Build Coastguard Worker // Concept: Formatter
67*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
68*9356374aSAndroid Build Coastguard Worker //
69*9356374aSAndroid Build Coastguard Worker // A Formatter is a function object that is responsible for formatting its
70*9356374aSAndroid Build Coastguard Worker // argument as a string and appending it to a given output std::string.
71*9356374aSAndroid Build Coastguard Worker // Formatters may be implemented as function objects, lambdas, or normal
72*9356374aSAndroid Build Coastguard Worker // functions. You may provide your own Formatter to enable `absl::StrJoin()` to
73*9356374aSAndroid Build Coastguard Worker // work with arbitrary types.
74*9356374aSAndroid Build Coastguard Worker //
75*9356374aSAndroid Build Coastguard Worker // The following is an example of a custom Formatter that uses
76*9356374aSAndroid Build Coastguard Worker // `absl::FormatDuration` to join a list of `absl::Duration`s.
77*9356374aSAndroid Build Coastguard Worker //
78*9356374aSAndroid Build Coastguard Worker //   std::vector<absl::Duration> v = {absl::Seconds(1), absl::Milliseconds(10)};
79*9356374aSAndroid Build Coastguard Worker //   std::string s =
80*9356374aSAndroid Build Coastguard Worker //       absl::StrJoin(v, ", ", [](std::string* out, absl::Duration dur) {
81*9356374aSAndroid Build Coastguard Worker //         absl::StrAppend(out, absl::FormatDuration(dur));
82*9356374aSAndroid Build Coastguard Worker //       });
83*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(s, "1s, 10ms");
84*9356374aSAndroid Build Coastguard Worker //
85*9356374aSAndroid Build Coastguard Worker // The following standard formatters are provided within this file:
86*9356374aSAndroid Build Coastguard Worker //
87*9356374aSAndroid Build Coastguard Worker // - `AlphaNumFormatter()` (the default)
88*9356374aSAndroid Build Coastguard Worker // - `StreamFormatter()`
89*9356374aSAndroid Build Coastguard Worker // - `PairFormatter()`
90*9356374aSAndroid Build Coastguard Worker // - `DereferenceFormatter()`
91*9356374aSAndroid Build Coastguard Worker 
92*9356374aSAndroid Build Coastguard Worker // AlphaNumFormatter()
93*9356374aSAndroid Build Coastguard Worker //
94*9356374aSAndroid Build Coastguard Worker // Default formatter used if none is specified. Uses `absl::AlphaNum` to convert
95*9356374aSAndroid Build Coastguard Worker // numeric arguments to strings.
AlphaNumFormatter()96*9356374aSAndroid Build Coastguard Worker inline strings_internal::AlphaNumFormatterImpl AlphaNumFormatter() {
97*9356374aSAndroid Build Coastguard Worker   return strings_internal::AlphaNumFormatterImpl();
98*9356374aSAndroid Build Coastguard Worker }
99*9356374aSAndroid Build Coastguard Worker 
100*9356374aSAndroid Build Coastguard Worker // StreamFormatter()
101*9356374aSAndroid Build Coastguard Worker //
102*9356374aSAndroid Build Coastguard Worker // Formats its argument using the << operator.
StreamFormatter()103*9356374aSAndroid Build Coastguard Worker inline strings_internal::StreamFormatterImpl StreamFormatter() {
104*9356374aSAndroid Build Coastguard Worker   return strings_internal::StreamFormatterImpl();
105*9356374aSAndroid Build Coastguard Worker }
106*9356374aSAndroid Build Coastguard Worker 
107*9356374aSAndroid Build Coastguard Worker // Function Template: PairFormatter(Formatter, absl::string_view, Formatter)
108*9356374aSAndroid Build Coastguard Worker //
109*9356374aSAndroid Build Coastguard Worker // Formats a `std::pair` by putting a given separator between the pair's
110*9356374aSAndroid Build Coastguard Worker // `.first` and `.second` members. This formatter allows you to specify
111*9356374aSAndroid Build Coastguard Worker // custom Formatters for both the first and second member of each pair.
112*9356374aSAndroid Build Coastguard Worker template <typename FirstFormatter, typename SecondFormatter>
113*9356374aSAndroid Build Coastguard Worker inline strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>
PairFormatter(FirstFormatter f1,absl::string_view sep,SecondFormatter f2)114*9356374aSAndroid Build Coastguard Worker PairFormatter(FirstFormatter f1, absl::string_view sep, SecondFormatter f2) {
115*9356374aSAndroid Build Coastguard Worker   return strings_internal::PairFormatterImpl<FirstFormatter, SecondFormatter>(
116*9356374aSAndroid Build Coastguard Worker       std::move(f1), sep, std::move(f2));
117*9356374aSAndroid Build Coastguard Worker }
118*9356374aSAndroid Build Coastguard Worker 
119*9356374aSAndroid Build Coastguard Worker // Function overload of PairFormatter() for using a default
120*9356374aSAndroid Build Coastguard Worker // `AlphaNumFormatter()` for each Formatter in the pair.
121*9356374aSAndroid Build Coastguard Worker inline strings_internal::PairFormatterImpl<
122*9356374aSAndroid Build Coastguard Worker     strings_internal::AlphaNumFormatterImpl,
123*9356374aSAndroid Build Coastguard Worker     strings_internal::AlphaNumFormatterImpl>
PairFormatter(absl::string_view sep)124*9356374aSAndroid Build Coastguard Worker PairFormatter(absl::string_view sep) {
125*9356374aSAndroid Build Coastguard Worker   return PairFormatter(AlphaNumFormatter(), sep, AlphaNumFormatter());
126*9356374aSAndroid Build Coastguard Worker }
127*9356374aSAndroid Build Coastguard Worker 
128*9356374aSAndroid Build Coastguard Worker // Function Template: DereferenceFormatter(Formatter)
129*9356374aSAndroid Build Coastguard Worker //
130*9356374aSAndroid Build Coastguard Worker // Formats its argument by dereferencing it and then applying the given
131*9356374aSAndroid Build Coastguard Worker // formatter. This formatter is useful for formatting a container of
132*9356374aSAndroid Build Coastguard Worker // pointer-to-T. This pattern often shows up when joining repeated fields in
133*9356374aSAndroid Build Coastguard Worker // protocol buffers.
134*9356374aSAndroid Build Coastguard Worker template <typename Formatter>
DereferenceFormatter(Formatter && f)135*9356374aSAndroid Build Coastguard Worker strings_internal::DereferenceFormatterImpl<Formatter> DereferenceFormatter(
136*9356374aSAndroid Build Coastguard Worker     Formatter&& f) {
137*9356374aSAndroid Build Coastguard Worker   return strings_internal::DereferenceFormatterImpl<Formatter>(
138*9356374aSAndroid Build Coastguard Worker       std::forward<Formatter>(f));
139*9356374aSAndroid Build Coastguard Worker }
140*9356374aSAndroid Build Coastguard Worker 
141*9356374aSAndroid Build Coastguard Worker // Function overload of `DereferenceFormatter()` for using a default
142*9356374aSAndroid Build Coastguard Worker // `AlphaNumFormatter()`.
143*9356374aSAndroid Build Coastguard Worker inline strings_internal::DereferenceFormatterImpl<
144*9356374aSAndroid Build Coastguard Worker     strings_internal::AlphaNumFormatterImpl>
DereferenceFormatter()145*9356374aSAndroid Build Coastguard Worker DereferenceFormatter() {
146*9356374aSAndroid Build Coastguard Worker   return strings_internal::DereferenceFormatterImpl<
147*9356374aSAndroid Build Coastguard Worker       strings_internal::AlphaNumFormatterImpl>(AlphaNumFormatter());
148*9356374aSAndroid Build Coastguard Worker }
149*9356374aSAndroid Build Coastguard Worker 
150*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
151*9356374aSAndroid Build Coastguard Worker // StrJoin()
152*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
153*9356374aSAndroid Build Coastguard Worker //
154*9356374aSAndroid Build Coastguard Worker // Joins a range of elements and returns the result as a std::string.
155*9356374aSAndroid Build Coastguard Worker // `absl::StrJoin()` takes a range, a separator string to use between the
156*9356374aSAndroid Build Coastguard Worker // elements joined, and an optional Formatter responsible for converting each
157*9356374aSAndroid Build Coastguard Worker // argument in the range to a string.
158*9356374aSAndroid Build Coastguard Worker //
159*9356374aSAndroid Build Coastguard Worker // If omitted, the default `AlphaNumFormatter()` is called on the elements to be
160*9356374aSAndroid Build Coastguard Worker // joined.
161*9356374aSAndroid Build Coastguard Worker //
162*9356374aSAndroid Build Coastguard Worker // Example 1:
163*9356374aSAndroid Build Coastguard Worker //   // Joins a collection of strings. This pattern also works with a collection
164*9356374aSAndroid Build Coastguard Worker //   // of `absl::string_view` or even `const char*`.
165*9356374aSAndroid Build Coastguard Worker //   std::vector<std::string> v = {"foo", "bar", "baz"};
166*9356374aSAndroid Build Coastguard Worker //   std::string s = absl::StrJoin(v, "-");
167*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(s, "foo-bar-baz");
168*9356374aSAndroid Build Coastguard Worker //
169*9356374aSAndroid Build Coastguard Worker // Example 2:
170*9356374aSAndroid Build Coastguard Worker //   // Joins the values in the given `std::initializer_list<>` specified using
171*9356374aSAndroid Build Coastguard Worker //   // brace initialization. This pattern also works with an initializer_list
172*9356374aSAndroid Build Coastguard Worker //   // of ints or `absl::string_view` -- any `AlphaNum`-compatible type.
173*9356374aSAndroid Build Coastguard Worker //   std::string s = absl::StrJoin({"foo", "bar", "baz"}, "-");
174*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQs, "foo-bar-baz");
175*9356374aSAndroid Build Coastguard Worker //
176*9356374aSAndroid Build Coastguard Worker // Example 3:
177*9356374aSAndroid Build Coastguard Worker //   // Joins a collection of ints. This pattern also works with floats,
178*9356374aSAndroid Build Coastguard Worker //   // doubles, int64s -- any `StrCat()`-compatible type.
179*9356374aSAndroid Build Coastguard Worker //   std::vector<int> v = {1, 2, 3, -4};
180*9356374aSAndroid Build Coastguard Worker //   std::string s = absl::StrJoin(v, "-");
181*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(s, "1-2-3--4");
182*9356374aSAndroid Build Coastguard Worker //
183*9356374aSAndroid Build Coastguard Worker // Example 4:
184*9356374aSAndroid Build Coastguard Worker //   // Joins a collection of pointer-to-int. By default, pointers are
185*9356374aSAndroid Build Coastguard Worker //   // dereferenced and the pointee is formatted using the default format for
186*9356374aSAndroid Build Coastguard Worker //   // that type; such dereferencing occurs for all levels of indirection, so
187*9356374aSAndroid Build Coastguard Worker //   // this pattern works just as well for `std::vector<int**>` as for
188*9356374aSAndroid Build Coastguard Worker //   // `std::vector<int*>`.
189*9356374aSAndroid Build Coastguard Worker //   int x = 1, y = 2, z = 3;
190*9356374aSAndroid Build Coastguard Worker //   std::vector<int*> v = {&x, &y, &z};
191*9356374aSAndroid Build Coastguard Worker //   std::string s = absl::StrJoin(v, "-");
192*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(s, "1-2-3");
193*9356374aSAndroid Build Coastguard Worker //
194*9356374aSAndroid Build Coastguard Worker // Example 5:
195*9356374aSAndroid Build Coastguard Worker //   // Dereferencing of `std::unique_ptr<>` is also supported:
196*9356374aSAndroid Build Coastguard Worker //   std::vector<std::unique_ptr<int>> v
197*9356374aSAndroid Build Coastguard Worker //   v.emplace_back(new int(1));
198*9356374aSAndroid Build Coastguard Worker //   v.emplace_back(new int(2));
199*9356374aSAndroid Build Coastguard Worker //   v.emplace_back(new int(3));
200*9356374aSAndroid Build Coastguard Worker //   std::string s = absl::StrJoin(v, "-");
201*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(s, "1-2-3");
202*9356374aSAndroid Build Coastguard Worker //
203*9356374aSAndroid Build Coastguard Worker // Example 6:
204*9356374aSAndroid Build Coastguard Worker //   // Joins a `std::map`, with each key-value pair separated by an equals
205*9356374aSAndroid Build Coastguard Worker //   // sign. This pattern would also work with, say, a
206*9356374aSAndroid Build Coastguard Worker //   // `std::vector<std::pair<>>`.
207*9356374aSAndroid Build Coastguard Worker //   std::map<std::string, int> m = {
208*9356374aSAndroid Build Coastguard Worker //       {"a", 1},
209*9356374aSAndroid Build Coastguard Worker //       {"b", 2},
210*9356374aSAndroid Build Coastguard Worker //       {"c", 3}};
211*9356374aSAndroid Build Coastguard Worker //   std::string s = absl::StrJoin(m, ",", absl::PairFormatter("="));
212*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(s, "a=1,b=2,c=3");
213*9356374aSAndroid Build Coastguard Worker //
214*9356374aSAndroid Build Coastguard Worker // Example 7:
215*9356374aSAndroid Build Coastguard Worker //   // These examples show how `absl::StrJoin()` handles a few common edge
216*9356374aSAndroid Build Coastguard Worker //   // cases:
217*9356374aSAndroid Build Coastguard Worker //   std::vector<std::string> v_empty;
218*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(absl::StrJoin(v_empty, "-"), "");
219*9356374aSAndroid Build Coastguard Worker //
220*9356374aSAndroid Build Coastguard Worker //   std::vector<std::string> v_one_item = {"foo"};
221*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(absl::StrJoin(v_one_item, "-"), "foo");
222*9356374aSAndroid Build Coastguard Worker //
223*9356374aSAndroid Build Coastguard Worker //   std::vector<std::string> v_empty_string = {""};
224*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(absl::StrJoin(v_empty_string, "-"), "");
225*9356374aSAndroid Build Coastguard Worker //
226*9356374aSAndroid Build Coastguard Worker //   std::vector<std::string> v_one_item_empty_string = {"a", ""};
227*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(absl::StrJoin(v_one_item_empty_string, "-"), "a-");
228*9356374aSAndroid Build Coastguard Worker //
229*9356374aSAndroid Build Coastguard Worker //   std::vector<std::string> v_two_empty_string = {"", ""};
230*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(absl::StrJoin(v_two_empty_string, "-"), "-");
231*9356374aSAndroid Build Coastguard Worker //
232*9356374aSAndroid Build Coastguard Worker // Example 8:
233*9356374aSAndroid Build Coastguard Worker //   // Joins a `std::tuple<T...>` of heterogeneous types, converting each to
234*9356374aSAndroid Build Coastguard Worker //   // a std::string using the `absl::AlphaNum` class.
235*9356374aSAndroid Build Coastguard Worker //   std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
236*9356374aSAndroid Build Coastguard Worker //   EXPECT_EQ(s, "123-abc-0.456");
237*9356374aSAndroid Build Coastguard Worker 
238*9356374aSAndroid Build Coastguard Worker template <typename Iterator, typename Formatter>
StrJoin(Iterator start,Iterator end,absl::string_view sep,Formatter && fmt)239*9356374aSAndroid Build Coastguard Worker std::string StrJoin(Iterator start, Iterator end, absl::string_view sep,
240*9356374aSAndroid Build Coastguard Worker                     Formatter&& fmt) {
241*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinAlgorithm(start, end, sep, fmt);
242*9356374aSAndroid Build Coastguard Worker }
243*9356374aSAndroid Build Coastguard Worker 
244*9356374aSAndroid Build Coastguard Worker template <typename Range, typename Formatter>
StrJoin(const Range & range,absl::string_view separator,Formatter && fmt)245*9356374aSAndroid Build Coastguard Worker std::string StrJoin(const Range& range, absl::string_view separator,
246*9356374aSAndroid Build Coastguard Worker                     Formatter&& fmt) {
247*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinRange(range, separator, fmt);
248*9356374aSAndroid Build Coastguard Worker }
249*9356374aSAndroid Build Coastguard Worker 
250*9356374aSAndroid Build Coastguard Worker template <typename T, typename Formatter,
251*9356374aSAndroid Build Coastguard Worker           typename = typename std::enable_if<
252*9356374aSAndroid Build Coastguard Worker               !std::is_convertible<T, absl::string_view>::value>::type>
StrJoin(std::initializer_list<T> il,absl::string_view separator,Formatter && fmt)253*9356374aSAndroid Build Coastguard Worker std::string StrJoin(std::initializer_list<T> il, absl::string_view separator,
254*9356374aSAndroid Build Coastguard Worker                     Formatter&& fmt) {
255*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinRange(il, separator, fmt);
256*9356374aSAndroid Build Coastguard Worker }
257*9356374aSAndroid Build Coastguard Worker 
258*9356374aSAndroid Build Coastguard Worker template <typename Formatter>
StrJoin(std::initializer_list<absl::string_view> il,absl::string_view separator,Formatter && fmt)259*9356374aSAndroid Build Coastguard Worker inline std::string StrJoin(std::initializer_list<absl::string_view> il,
260*9356374aSAndroid Build Coastguard Worker                            absl::string_view separator, Formatter&& fmt) {
261*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinRange(il, separator, fmt);
262*9356374aSAndroid Build Coastguard Worker }
263*9356374aSAndroid Build Coastguard Worker 
264*9356374aSAndroid Build Coastguard Worker template <typename... T, typename Formatter>
StrJoin(const std::tuple<T...> & value,absl::string_view separator,Formatter && fmt)265*9356374aSAndroid Build Coastguard Worker std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator,
266*9356374aSAndroid Build Coastguard Worker                     Formatter&& fmt) {
267*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinAlgorithm(value, separator, fmt);
268*9356374aSAndroid Build Coastguard Worker }
269*9356374aSAndroid Build Coastguard Worker 
270*9356374aSAndroid Build Coastguard Worker template <typename Iterator>
StrJoin(Iterator start,Iterator end,absl::string_view separator)271*9356374aSAndroid Build Coastguard Worker std::string StrJoin(Iterator start, Iterator end, absl::string_view separator) {
272*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinRange(start, end, separator);
273*9356374aSAndroid Build Coastguard Worker }
274*9356374aSAndroid Build Coastguard Worker 
275*9356374aSAndroid Build Coastguard Worker template <typename Range>
StrJoin(const Range & range,absl::string_view separator)276*9356374aSAndroid Build Coastguard Worker std::string StrJoin(const Range& range, absl::string_view separator) {
277*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinRange(range, separator);
278*9356374aSAndroid Build Coastguard Worker }
279*9356374aSAndroid Build Coastguard Worker 
280*9356374aSAndroid Build Coastguard Worker template <typename T, typename = typename std::enable_if<!std::is_convertible<
281*9356374aSAndroid Build Coastguard Worker                           T, absl::string_view>::value>::type>
StrJoin(std::initializer_list<T> il,absl::string_view separator)282*9356374aSAndroid Build Coastguard Worker std::string StrJoin(std::initializer_list<T> il, absl::string_view separator) {
283*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinRange(il, separator);
284*9356374aSAndroid Build Coastguard Worker }
285*9356374aSAndroid Build Coastguard Worker 
StrJoin(std::initializer_list<absl::string_view> il,absl::string_view separator)286*9356374aSAndroid Build Coastguard Worker inline std::string StrJoin(std::initializer_list<absl::string_view> il,
287*9356374aSAndroid Build Coastguard Worker                            absl::string_view separator) {
288*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinRange(il, separator);
289*9356374aSAndroid Build Coastguard Worker }
290*9356374aSAndroid Build Coastguard Worker 
291*9356374aSAndroid Build Coastguard Worker template <typename... T>
StrJoin(const std::tuple<T...> & value,absl::string_view separator)292*9356374aSAndroid Build Coastguard Worker std::string StrJoin(const std::tuple<T...>& value,
293*9356374aSAndroid Build Coastguard Worker                     absl::string_view separator) {
294*9356374aSAndroid Build Coastguard Worker   return strings_internal::JoinTuple(value, separator,
295*9356374aSAndroid Build Coastguard Worker                                      std::index_sequence_for<T...>{});
296*9356374aSAndroid Build Coastguard Worker }
297*9356374aSAndroid Build Coastguard Worker 
298*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
299*9356374aSAndroid Build Coastguard Worker }  // namespace absl
300*9356374aSAndroid Build Coastguard Worker 
301*9356374aSAndroid Build Coastguard Worker #endif  // ABSL_STRINGS_STR_JOIN_H_
302