1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_STRINGS_STRCAT_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_STRINGS_STRCAT_H_
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Worker #include <initializer_list>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
13*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
16*6777b538SAndroid Build Coastguard Worker // Guard against conflict with Win32 API StrCat macro:
17*6777b538SAndroid Build Coastguard Worker // check StrCat wasn't and will not be redefined.
18*6777b538SAndroid Build Coastguard Worker #define StrCat StrCat
19*6777b538SAndroid Build Coastguard Worker #endif
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker namespace base {
22*6777b538SAndroid Build Coastguard Worker
23*6777b538SAndroid Build Coastguard Worker // StrCat ----------------------------------------------------------------------
24*6777b538SAndroid Build Coastguard Worker //
25*6777b538SAndroid Build Coastguard Worker // StrCat is a function to perform concatenation on a sequence of strings.
26*6777b538SAndroid Build Coastguard Worker // It is preferrable to a sequence of "a + b + c" because it is both faster and
27*6777b538SAndroid Build Coastguard Worker // generates less code.
28*6777b538SAndroid Build Coastguard Worker //
29*6777b538SAndroid Build Coastguard Worker // std::string result = base::StrCat({"foo ", result, "\nfoo ", bar});
30*6777b538SAndroid Build Coastguard Worker //
31*6777b538SAndroid Build Coastguard Worker // To join an array of strings with a separator, see base::JoinString in
32*6777b538SAndroid Build Coastguard Worker // base/strings/string_util.h.
33*6777b538SAndroid Build Coastguard Worker //
34*6777b538SAndroid Build Coastguard Worker // MORE INFO
35*6777b538SAndroid Build Coastguard Worker //
36*6777b538SAndroid Build Coastguard Worker // StrCat can see all arguments at once, so it can allocate one return buffer
37*6777b538SAndroid Build Coastguard Worker // of exactly the right size and copy once, as opposed to a sequence of
38*6777b538SAndroid Build Coastguard Worker // operator+ which generates a series of temporary strings, copying as it goes.
39*6777b538SAndroid Build Coastguard Worker // And by using StringPiece arguments, StrCat can avoid creating temporary
40*6777b538SAndroid Build Coastguard Worker // string objects for char* constants.
41*6777b538SAndroid Build Coastguard Worker //
42*6777b538SAndroid Build Coastguard Worker // ALTERNATIVES
43*6777b538SAndroid Build Coastguard Worker //
44*6777b538SAndroid Build Coastguard Worker // Internal Google / Abseil has a similar StrCat function. That version takes
45*6777b538SAndroid Build Coastguard Worker // an overloaded number of arguments instead of initializer list (overflowing
46*6777b538SAndroid Build Coastguard Worker // to initializer list for many arguments). We don't have any legacy
47*6777b538SAndroid Build Coastguard Worker // requirements and using only initializer_list is simpler and generates
48*6777b538SAndroid Build Coastguard Worker // roughly the same amount of code at the call sites.
49*6777b538SAndroid Build Coastguard Worker //
50*6777b538SAndroid Build Coastguard Worker // Abseil's StrCat also allows numbers by using an intermediate class that can
51*6777b538SAndroid Build Coastguard Worker // be implicitly constructed from either a string or various number types. This
52*6777b538SAndroid Build Coastguard Worker // class formats the numbers into a static buffer for increased performance,
53*6777b538SAndroid Build Coastguard Worker // and the call sites look nice.
54*6777b538SAndroid Build Coastguard Worker //
55*6777b538SAndroid Build Coastguard Worker // As-written Abseil's helper class for numbers generates slightly more code
56*6777b538SAndroid Build Coastguard Worker // than the raw StringPiece version. We can de-inline the helper class'
57*6777b538SAndroid Build Coastguard Worker // constructors which will cause the StringPiece constructors to be de-inlined
58*6777b538SAndroid Build Coastguard Worker // for this call and generate slightly less code. This is something we can
59*6777b538SAndroid Build Coastguard Worker // explore more in the future.
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard Worker [[nodiscard]] BASE_EXPORT std::string StrCat(span<const StringPiece> pieces);
62*6777b538SAndroid Build Coastguard Worker [[nodiscard]] BASE_EXPORT std::u16string StrCat(
63*6777b538SAndroid Build Coastguard Worker span<const StringPiece16> pieces);
64*6777b538SAndroid Build Coastguard Worker [[nodiscard]] BASE_EXPORT std::string StrCat(span<const std::string> pieces);
65*6777b538SAndroid Build Coastguard Worker [[nodiscard]] BASE_EXPORT std::u16string StrCat(
66*6777b538SAndroid Build Coastguard Worker span<const std::u16string> pieces);
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker // Initializer list forwards to the array version.
StrCat(std::initializer_list<StringPiece> pieces)69*6777b538SAndroid Build Coastguard Worker inline std::string StrCat(std::initializer_list<StringPiece> pieces) {
70*6777b538SAndroid Build Coastguard Worker return StrCat(make_span(pieces));
71*6777b538SAndroid Build Coastguard Worker }
72*6777b538SAndroid Build Coastguard Worker
StrCat(std::initializer_list<StringPiece16> pieces)73*6777b538SAndroid Build Coastguard Worker inline std::u16string StrCat(std::initializer_list<StringPiece16> pieces) {
74*6777b538SAndroid Build Coastguard Worker return StrCat(make_span(pieces));
75*6777b538SAndroid Build Coastguard Worker }
76*6777b538SAndroid Build Coastguard Worker
77*6777b538SAndroid Build Coastguard Worker // StrAppend -------------------------------------------------------------------
78*6777b538SAndroid Build Coastguard Worker //
79*6777b538SAndroid Build Coastguard Worker // Appends a sequence of strings to a destination. Prefer:
80*6777b538SAndroid Build Coastguard Worker // StrAppend(&foo, ...);
81*6777b538SAndroid Build Coastguard Worker // over:
82*6777b538SAndroid Build Coastguard Worker // foo += StrCat(...);
83*6777b538SAndroid Build Coastguard Worker // because it avoids a temporary string allocation and copy.
84*6777b538SAndroid Build Coastguard Worker
85*6777b538SAndroid Build Coastguard Worker BASE_EXPORT void StrAppend(std::string* dest, span<const StringPiece> pieces);
86*6777b538SAndroid Build Coastguard Worker BASE_EXPORT void StrAppend(std::u16string* dest,
87*6777b538SAndroid Build Coastguard Worker span<const StringPiece16> pieces);
88*6777b538SAndroid Build Coastguard Worker BASE_EXPORT void StrAppend(std::string* dest, span<const std::string> pieces);
89*6777b538SAndroid Build Coastguard Worker BASE_EXPORT void StrAppend(std::u16string* dest,
90*6777b538SAndroid Build Coastguard Worker span<const std::u16string> pieces);
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker // Initializer list forwards to the array version.
StrAppend(std::string * dest,std::initializer_list<StringPiece> pieces)93*6777b538SAndroid Build Coastguard Worker inline void StrAppend(std::string* dest,
94*6777b538SAndroid Build Coastguard Worker std::initializer_list<StringPiece> pieces) {
95*6777b538SAndroid Build Coastguard Worker StrAppend(dest, make_span(pieces));
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker
StrAppend(std::u16string * dest,std::initializer_list<StringPiece16> pieces)98*6777b538SAndroid Build Coastguard Worker inline void StrAppend(std::u16string* dest,
99*6777b538SAndroid Build Coastguard Worker std::initializer_list<StringPiece16> pieces) {
100*6777b538SAndroid Build Coastguard Worker StrAppend(dest, make_span(pieces));
101*6777b538SAndroid Build Coastguard Worker }
102*6777b538SAndroid Build Coastguard Worker
103*6777b538SAndroid Build Coastguard Worker } // namespace base
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
106*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat_win.h"
107*6777b538SAndroid Build Coastguard Worker #endif
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker #endif // BASE_STRINGS_STRCAT_H_
110