Coverage Report

Created: 2025-03-10 22:58

/root/doris/be/src/gutil/strings/strcat.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2008 and onwards Google, Inc.
2
//
3
// #status: RECOMMENDED
4
// #category: operations on strings
5
// #summary: Merges strings or numbers with no delimiter.
6
//
7
#pragma once
8
9
#include <string.h>
10
#include <string>
11
#include <utility>
12
13
using std::string;
14
15
#include "gutil/integral_types.h"
16
#include "gutil/strings/numbers.h"
17
#include "gutil/strings/stringpiece.h"
18
#include "gutil/stringprintf.h"
19
20
// The AlphaNum type was designed to be used as the parameter type for StrCat().
21
// I suppose that any routine accepting either a string or a number could accept
22
// it.  The basic idea is that by accepting a "const AlphaNum &" as an argument
23
// to your function, your callers will automagically convert bools, integers,
24
// and floating point values to strings for you.
25
//
26
// Conversion from 8-bit values is not accepted because if it were, then an
27
// attempt to pass ':' instead of ":" might result in a 58 ending up in your
28
// result.
29
//
30
// Bools convert to "0" or "1".
31
//
32
// Floating point values are converted to a string which, if passed to strtod(),
33
// would produce the exact same original double (except in case of NaN; all NaNs
34
// are considered the same value). We try to keep the string short but it's not
35
// guaranteed to be as short as possible.
36
//
37
// This class has implicit constructors.
38
// Style guide exception granted:
39
// http://goto/style-guide-exception-20978288
40
//
41
struct AlphaNum {
42
    StringPiece piece;
43
    char digits[kFastToBufferSize];
44
45
    // No bool ctor -- bools convert to an integral type.
46
    // A bool ctor would also convert incoming pointers (bletch).
47
48
    AlphaNum(int32 i32) // NOLINT(runtime/explicit)
49
0
            : piece(digits, FastInt32ToBufferLeft(i32, digits) - &digits[0]) {}
50
    AlphaNum(uint32 u32) // NOLINT(runtime/explicit)
51
0
            : piece(digits, FastUInt32ToBufferLeft(u32, digits) - &digits[0]) {}
52
    AlphaNum(int64 i64) // NOLINT(runtime/explicit)
53
299
            : piece(digits, FastInt64ToBufferLeft(i64, digits) - &digits[0]) {}
54
    AlphaNum(uint64 u64) // NOLINT(runtime/explicit)
55
0
            : piece(digits, FastUInt64ToBufferLeft(u64, digits) - &digits[0]) {}
56
57
#if defined(__APPLE__)
58
    AlphaNum(size_t size) // NOLINT(runtime/explicit)
59
            : piece(digits, FastUInt64ToBufferLeft(size, digits) - &digits[0]) {}
60
#endif
61
62
    AlphaNum(float f) // NOLINT(runtime/explicit)
63
0
            : piece(digits, strlen(FloatToBuffer(f, digits))) {}
64
    AlphaNum(double f) // NOLINT(runtime/explicit)
65
0
            : piece(digits, strlen(DoubleToBuffer(f, digits))) {}
66
67
1
    AlphaNum(const char* c_str) : piece(c_str) {}      // NOLINT(runtime/explicit)
68
0
    AlphaNum(StringPiece pc) : piece(std::move(pc)) {} // NOLINT(runtime/explicit)
69
299
    AlphaNum(const string& s) : piece(s) {}            // NOLINT(runtime/explicit)
70
71
1.79k
    StringPiece::size_type size() const { return piece.size(); }
72
598
    const char* data() const { return piece.data(); }
73
74
private:
75
    // Use ":" not ':'
76
    AlphaNum(char c); // NOLINT(runtime/explicit)
77
};
78
79
extern AlphaNum gEmptyAlphaNum;
80
81
// ----------------------------------------------------------------------
82
// StrCat()
83
//    This merges the given strings or numbers, with no delimiter.  This
84
//    is designed to be the fastest possible way to construct a string out
85
//    of a mix of raw C strings, StringPieces, strings, bool values,
86
//    and numeric values.
87
//
88
//    Don't use this for user-visible strings.  The localization process
89
//    works poorly on strings built up out of fragments.
90
//
91
//    For clarity and performance, don't use StrCat when appending to a
92
//    string.  In particular, avoid using any of these (anti-)patterns:
93
//      str.append(StrCat(...)
94
//      str += StrCat(...)
95
//      str = StrCat(str, ...)
96
//    where the last is the worse, with the potential to change a loop
97
//    from a linear time operation with O(1) dynamic allocations into a
98
//    quadratic time operation with O(n) dynamic allocations.  StrAppend
99
//    is a better choice than any of the above, subject to the restriction
100
//    of StrAppend(&str, a, b, c, ...) that none of the a, b, c, ... may
101
//    be a reference into str.
102
// ----------------------------------------------------------------------
103
104
string StrCat(const AlphaNum& a);
105
string StrCat(const AlphaNum& a, const AlphaNum& b);
106
string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c);
107
string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d);
108
string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
109
              const AlphaNum& e);
110
string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
111
              const AlphaNum& e, const AlphaNum& f);
112
string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
113
              const AlphaNum& e, const AlphaNum& f, const AlphaNum& g);
114
string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
115
              const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h);
116
117
namespace strings {
118
namespace internal {
119
120
// Do not call directly - this is not part of the public API.
121
string StrCatNineOrMore(const AlphaNum* a1, ...);
122
123
} // namespace internal
124
} // namespace strings
125
126
// Support 9 or more arguments
127
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
128
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
129
0
                     const AlphaNum& i) {
130
0
    const AlphaNum* null_alphanum = NULL;
131
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, null_alphanum);
132
0
}
133
134
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
135
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
136
0
                     const AlphaNum& i, const AlphaNum& j) {
137
0
    const AlphaNum* null_alphanum = NULL;
138
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j,
139
0
                                               null_alphanum);
140
0
}
141
142
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
143
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
144
0
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k) {
145
0
    const AlphaNum* null_alphanum = NULL;
146
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k,
147
0
                                               null_alphanum);
148
0
}
149
150
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
151
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
152
0
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l) {
153
0
    const AlphaNum* null_alphanum = NULL;
154
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l,
155
0
                                               null_alphanum);
156
0
}
157
158
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
159
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
160
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
161
0
                     const AlphaNum& m) {
162
0
    const AlphaNum* null_alphanum = NULL;
163
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
164
0
                                               null_alphanum);
165
0
}
166
167
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
168
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
169
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
170
0
                     const AlphaNum& m, const AlphaNum& n) {
171
0
    const AlphaNum* null_alphanum = NULL;
172
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
173
0
                                               &n, null_alphanum);
174
0
}
175
176
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
177
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
178
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
179
0
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o) {
180
0
    const AlphaNum* null_alphanum = NULL;
181
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
182
0
                                               &n, &o, null_alphanum);
183
0
}
184
185
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
186
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
187
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
188
0
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p) {
189
0
    const AlphaNum* null_alphanum = NULL;
190
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
191
0
                                               &n, &o, &p, null_alphanum);
192
0
}
193
194
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
195
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
196
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
197
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
198
0
                     const AlphaNum& q) {
199
0
    const AlphaNum* null_alphanum = NULL;
200
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
201
0
                                               &n, &o, &p, &q, null_alphanum);
202
0
}
203
204
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
205
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
206
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
207
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
208
0
                     const AlphaNum& q, const AlphaNum& r) {
209
0
    const AlphaNum* null_alphanum = NULL;
210
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
211
0
                                               &n, &o, &p, &q, &r, null_alphanum);
212
0
}
213
214
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
215
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
216
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
217
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
218
0
                     const AlphaNum& q, const AlphaNum& r, const AlphaNum& s) {
219
0
    const AlphaNum* null_alphanum = NULL;
220
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
221
0
                                               &n, &o, &p, &q, &r, &s, null_alphanum);
222
0
}
223
224
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
225
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
226
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
227
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
228
0
                     const AlphaNum& q, const AlphaNum& r, const AlphaNum& s, const AlphaNum& t) {
229
0
    const AlphaNum* null_alphanum = NULL;
230
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
231
0
                                               &n, &o, &p, &q, &r, &s, &t, null_alphanum);
232
0
}
233
234
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
235
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
236
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
237
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
238
                     const AlphaNum& q, const AlphaNum& r, const AlphaNum& s, const AlphaNum& t,
239
0
                     const AlphaNum& u) {
240
0
    const AlphaNum* null_alphanum = NULL;
241
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
242
0
                                               &n, &o, &p, &q, &r, &s, &t, &u, null_alphanum);
243
0
}
244
245
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
246
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
247
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
248
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
249
                     const AlphaNum& q, const AlphaNum& r, const AlphaNum& s, const AlphaNum& t,
250
0
                     const AlphaNum& u, const AlphaNum& v) {
251
0
    const AlphaNum* null_alphanum = NULL;
252
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
253
0
                                               &n, &o, &p, &q, &r, &s, &t, &u, &v, null_alphanum);
254
0
}
255
256
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
257
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
258
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
259
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
260
                     const AlphaNum& q, const AlphaNum& r, const AlphaNum& s, const AlphaNum& t,
261
0
                     const AlphaNum& u, const AlphaNum& v, const AlphaNum& w) {
262
0
    const AlphaNum* null_alphanum = NULL;
263
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
264
0
                                               &n, &o, &p, &q, &r, &s, &t, &u, &v, &w,
265
0
                                               null_alphanum);
266
0
}
267
268
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
269
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
270
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
271
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
272
                     const AlphaNum& q, const AlphaNum& r, const AlphaNum& s, const AlphaNum& t,
273
0
                     const AlphaNum& u, const AlphaNum& v, const AlphaNum& w, const AlphaNum& x) {
274
0
    const AlphaNum* null_alphanum = NULL;
275
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
276
0
                                               &n, &o, &p, &q, &r, &s, &t, &u, &v, &w, &x,
277
0
                                               null_alphanum);
278
0
}
279
280
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
281
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
282
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
283
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
284
                     const AlphaNum& q, const AlphaNum& r, const AlphaNum& s, const AlphaNum& t,
285
                     const AlphaNum& u, const AlphaNum& v, const AlphaNum& w, const AlphaNum& x,
286
0
                     const AlphaNum& y) {
287
0
    const AlphaNum* null_alphanum = NULL;
288
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
289
0
                                               &n, &o, &p, &q, &r, &s, &t, &u, &v, &w, &x, &y,
290
0
                                               null_alphanum);
291
0
}
292
293
inline string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
294
                     const AlphaNum& e, const AlphaNum& f, const AlphaNum& g, const AlphaNum& h,
295
                     const AlphaNum& i, const AlphaNum& j, const AlphaNum& k, const AlphaNum& l,
296
                     const AlphaNum& m, const AlphaNum& n, const AlphaNum& o, const AlphaNum& p,
297
                     const AlphaNum& q, const AlphaNum& r, const AlphaNum& s, const AlphaNum& t,
298
                     const AlphaNum& u, const AlphaNum& v, const AlphaNum& w, const AlphaNum& x,
299
0
                     const AlphaNum& y, const AlphaNum& z) {
300
0
    const AlphaNum* null_alphanum = NULL;
301
0
    return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m,
302
0
                                               &n, &o, &p, &q, &r, &s, &t, &u, &v, &w, &x, &y, &z,
303
0
                                               null_alphanum);
304
0
}
305
306
// ----------------------------------------------------------------------
307
// StrAppend()
308
//    Same as above, but adds the output to the given string.
309
//    WARNING: For speed, StrAppend does not try to check each of its input
310
//    arguments to be sure that they are not a subset of the string being
311
//    appended to.  That is, while this will work:
312
//
313
//    string s = "foo";
314
//    s += s;
315
//
316
//    This will not (necessarily) work:
317
//
318
//    string s = "foo";
319
//    StrAppend(&s, s);
320
//
321
//    Note: while StrCat supports appending up to 12 arguments, StrAppend
322
//    is currently limited to 9.  That's rarely an issue except when
323
//    automatically transforming StrCat to StrAppend, and can easily be
324
//    worked around as consecutive calls to StrAppend are quite efficient.
325
// ----------------------------------------------------------------------
326
327
void StrAppend(string* dest, const AlphaNum& a);
328
void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b);
329
void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c);
330
void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c,
331
               const AlphaNum& d);
332
333
// Support up to 9 params by using a default empty AlphaNum.
334
void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c,
335
               const AlphaNum& d, const AlphaNum& e, const AlphaNum& f = gEmptyAlphaNum,
336
               const AlphaNum& g = gEmptyAlphaNum, const AlphaNum& h = gEmptyAlphaNum,
337
               const AlphaNum& i = gEmptyAlphaNum);