YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/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
// The following only applies to changes made to this file as part of YugaByte development.
8
//
9
// Portions Copyright (c) YugaByte, Inc.
10
//
11
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
12
// in compliance with the License.  You may obtain a copy of the License at
13
//
14
// http://www.apache.org/licenses/LICENSE-2.0
15
//
16
// Unless required by applicable law or agreed to in writing, software distributed under the License
17
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
18
// or implied.  See the License for the specific language governing permissions and limitations
19
// under the License.
20
//
21
#ifndef YB_GUTIL_STRINGS_STRCAT_H
22
#define YB_GUTIL_STRINGS_STRCAT_H
23
24
#include <string>
25
using std::string;
26
27
#include "yb/gutil/integral_types.h"
28
#include "yb/gutil/strings/numbers.h"
29
#include "yb/gutil/strings/stringpiece.h"
30
31
// The AlphaNum type was designed to be used as the parameter type for StrCat().
32
// I suppose that any routine accepting either a string or a number could accept
33
// it.  The basic idea is that by accepting a "const AlphaNum &" as an argument
34
// to your function, your callers will automagically convert bools, integers,
35
// and floating point values to strings for you.
36
//
37
// Conversion from 8-bit values is not accepted because if it were, then an
38
// attempt to pass ':' instead of ":" might result in a 58 ending up in your
39
// result.
40
//
41
// Bools convert to "0" or "1".
42
//
43
// Floating point values are converted to a string which, if passed to strtod(),
44
// would produce the exact same original double (except in case of NaN; all NaNs
45
// are considered the same value). We try to keep the string short but it's not
46
// guaranteed to be as short as possible.
47
//
48
// This class has implicit constructors.
49
// Style guide exception granted:
50
// http://goto/style-guide-exception-20978288
51
//
52
struct AlphaNum {
53
  GStringPiece piece;
54
  char digits[kFastToBufferSize];
55
56
  // No bool ctor -- bools convert to an integral type.
57
  // A bool ctor would also convert incoming pointers (bletch).
58
  // It is OK that digits is not initialized.
59
60
  //-V:digits:730
61
  AlphaNum(int32 i32)  // NOLINT(runtime/explicit)
62
1.21k
      : piece(digits, FastInt32ToBufferLeft(i32, digits) - &digits[0]) {}
63
  //-V:digits_:730
64
  AlphaNum(uint32 u32)  // NOLINT(runtime/explicit)
65
0
      : piece(digits, FastUInt32ToBufferLeft(u32, digits) - &digits[0]) {}
66
  //-V:digits_:730
67
  AlphaNum(int64 i64)  // NOLINT(runtime/explicit)
68
0
      : piece(digits, FastInt64ToBufferLeft(i64, digits) - &digits[0]) {}
69
  //-V:digits_:730
70
  AlphaNum(uint64 u64)  // NOLINT(runtime/explicit)
71
0
      : piece(digits, FastUInt64ToBufferLeft(u64, digits) - &digits[0]) {}
72
73
#if defined(__APPLE__)
74
  //-V:digits_:730
75
  AlphaNum(size_t size)  // NOLINT(runtime/explicit)
76
1.03k
      : piece(digits, FastUInt64ToBufferLeft(size, digits) - &digits[0]) {}
77
#endif
78
79
  //-V:digits_:730
80
  AlphaNum(float f)  // NOLINT(runtime/explicit)
81
0
      : piece(digits, strlen(FloatToBuffer(f, digits))) {}
82
  //-V:digits_:730
83
  AlphaNum(double f)  // NOLINT(runtime/explicit)
84
0
      : piece(digits, strlen(DoubleToBuffer(f, digits))) {}
85
86
  //-V:digits_:730
87
319k
  AlphaNum(const char *c_str) : piece(c_str) {}  // NOLINT(runtime/explicit)
88
  //-V:digits_:730
89
75
  AlphaNum(GStringPiece pc) : piece(std::move(pc)) {}  // NOLINT(runtime/explicit)
90
  //-V:digits_:730
91
460k
  AlphaNum(const string &s) : piece(s) {}  // NOLINT(runtime/explicit)
92
93
2.26M
  GStringPiece::size_type size() const { return piece.size(); }
94
764k
  const char *data() const { return piece.data(); }
95
96
 private:
97
  // Use ":" not ':'
98
  AlphaNum(char c);  // NOLINT(runtime/explicit)
99
};
100
101
extern AlphaNum gEmptyAlphaNum;
102
103
// ----------------------------------------------------------------------
104
// StrCat()
105
//    This merges the given strings or numbers, with no delimiter.  This
106
//    is designed to be the fastest possible way to construct a string out
107
//    of a mix of raw C strings, GStringPieces, strings, bool values,
108
//    and numeric values.
109
//
110
//    Don't use this for user-visible strings.  The localization process
111
//    works poorly on strings built up out of fragments.
112
//
113
//    For clarity and performance, don't use StrCat when appending to a
114
//    string.  In particular, avoid using any of these (anti-)patterns:
115
//      str.append(StrCat(...)
116
//      str += StrCat(...)
117
//      str = StrCat(str, ...)
118
//    where the last is the worse, with the potential to change a loop
119
//    from a linear time operation with O(1) dynamic allocations into a
120
//    quadratic time operation with O(n) dynamic allocations.  StrAppend
121
//    is a better choice than any of the above, subject to the restriction
122
//    of StrAppend(&str, a, b, c, ...) that none of the a, b, c, ... may
123
//    be a reference into str.
124
// ----------------------------------------------------------------------
125
126
string StrCat(const AlphaNum &a);
127
string StrCat(const AlphaNum &a, const AlphaNum &b);
128
string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c);
129
string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
130
              const AlphaNum &d);
131
string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
132
              const AlphaNum &d, const AlphaNum &e);
133
string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
134
              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f);
135
string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
136
              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
137
              const AlphaNum &g);
138
string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
139
              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
140
              const AlphaNum &g, const AlphaNum &h);
141
142
namespace strings {
143
namespace internal {
144
145
// Do not call directly - this is not part of the public API.
146
string StrCatNineOrMore(const AlphaNum *a1, ...);
147
148
}  // namespace internal
149
}  // namespace strings
150
151
// Support 9 or more arguments
152
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
153
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
154
0
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) {
155
0
  const AlphaNum* null_alphanum = NULL;
156
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
157
0
                                             null_alphanum);
158
0
}
159
160
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
161
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
162
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
163
0
                     const AlphaNum &j) {
164
0
  const AlphaNum* null_alphanum = NULL;
165
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
166
0
                                             &j, null_alphanum);
167
0
}
168
169
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
170
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
171
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
172
0
                     const AlphaNum &j, const AlphaNum &k) {
173
0
  const AlphaNum* null_alphanum = NULL;
174
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
175
0
                                             &j, &k, null_alphanum);
176
0
}
177
178
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
179
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
180
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
181
0
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l) {
182
0
  const AlphaNum* null_alphanum = NULL;
183
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
184
0
                                             &j, &k, &l, null_alphanum);
185
0
}
186
187
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
188
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
189
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
190
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
191
0
                     const AlphaNum &m) {
192
0
  const AlphaNum* null_alphanum = NULL;
193
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
194
0
                                             &j, &k, &l, &m, null_alphanum);
195
0
}
196
197
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
198
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
199
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
200
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
201
0
                     const AlphaNum &m, const AlphaNum &n) {
202
0
  const AlphaNum* null_alphanum = NULL;
203
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
204
0
                                             &j, &k, &l, &m, &n, null_alphanum);
205
0
}
206
207
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
208
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
209
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
210
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
211
0
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o) {
212
0
  const AlphaNum* null_alphanum = NULL;
213
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
214
0
                                             &j, &k, &l, &m, &n, &o,
215
0
                                             null_alphanum);
216
0
}
217
218
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
219
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
220
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
221
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
222
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
223
0
                     const AlphaNum &p) {
224
0
  const AlphaNum* null_alphanum = NULL;
225
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
226
0
                                             &j, &k, &l, &m, &n, &o, &p,
227
0
                                             null_alphanum);
228
0
}
229
230
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
231
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
232
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
233
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
234
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
235
0
                     const AlphaNum &p, const AlphaNum &q) {
236
0
  const AlphaNum* null_alphanum = NULL;
237
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
238
0
                                             &j, &k, &l, &m, &n, &o, &p, &q,
239
0
                                             null_alphanum);
240
0
}
241
242
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
243
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
244
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
245
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
246
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
247
0
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r) {
248
0
  const AlphaNum* null_alphanum = NULL;
249
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
250
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
251
0
                                             null_alphanum);
252
0
}
253
254
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
255
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
256
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
257
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
258
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
259
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r,
260
0
                     const AlphaNum &s) {
261
0
  const AlphaNum* null_alphanum = NULL;
262
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
263
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
264
0
                                             &s, null_alphanum);
265
0
}
266
267
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
268
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
269
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
270
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
271
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
272
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r,
273
0
                     const AlphaNum &s, const AlphaNum &t) {
274
0
  const AlphaNum* null_alphanum = NULL;
275
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
276
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
277
0
                                             &s, &t, null_alphanum);
278
0
}
279
280
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
281
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
282
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
283
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
284
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
285
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r,
286
0
                     const AlphaNum &s, const AlphaNum &t, const AlphaNum &u) {
287
0
  const AlphaNum* null_alphanum = NULL;
288
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
289
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
290
0
                                             &s, &t, &u, null_alphanum);
291
0
}
292
293
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
294
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
295
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
296
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
297
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
298
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r,
299
                     const AlphaNum &s, const AlphaNum &t, const AlphaNum &u,
300
0
                     const AlphaNum &v) {
301
0
  const AlphaNum* null_alphanum = NULL;
302
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
303
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
304
0
                                             &s, &t, &u, &v, null_alphanum);
305
0
}
306
307
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
308
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
309
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
310
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
311
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
312
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r,
313
                     const AlphaNum &s, const AlphaNum &t, const AlphaNum &u,
314
0
                     const AlphaNum &v, const AlphaNum &w) {
315
0
  const AlphaNum* null_alphanum = NULL;
316
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
317
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
318
0
                                             &s, &t, &u, &v, &w, null_alphanum);
319
0
}
320
321
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
322
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
323
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
324
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
325
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
326
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r,
327
                     const AlphaNum &s, const AlphaNum &t, const AlphaNum &u,
328
0
                     const AlphaNum &v, const AlphaNum &w, const AlphaNum &x) {
329
0
  const AlphaNum* null_alphanum = NULL;
330
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
331
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
332
0
                                             &s, &t, &u, &v, &w, &x,
333
0
                                             null_alphanum);
334
0
}
335
336
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
337
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
338
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
339
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
340
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
341
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r,
342
                     const AlphaNum &s, const AlphaNum &t, const AlphaNum &u,
343
                     const AlphaNum &v, const AlphaNum &w, const AlphaNum &x,
344
0
                     const AlphaNum &y) {
345
0
  const AlphaNum* null_alphanum = NULL;
346
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
347
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
348
0
                                             &s, &t, &u, &v, &w, &x, &y,
349
0
                                             null_alphanum);
350
0
}
351
352
inline string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
353
                     const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
354
                     const AlphaNum &g, const AlphaNum &h, const AlphaNum &i,
355
                     const AlphaNum &j, const AlphaNum &k, const AlphaNum &l,
356
                     const AlphaNum &m, const AlphaNum &n, const AlphaNum &o,
357
                     const AlphaNum &p, const AlphaNum &q, const AlphaNum &r,
358
                     const AlphaNum &s, const AlphaNum &t, const AlphaNum &u,
359
                     const AlphaNum &v, const AlphaNum &w, const AlphaNum &x,
360
0
                     const AlphaNum &y, const AlphaNum &z) {
361
0
  const AlphaNum* null_alphanum = NULL;
362
0
  return strings::internal::StrCatNineOrMore(&a, &b, &c, &d, &e, &f, &g, &h, &i,
363
0
                                             &j, &k, &l, &m, &n, &o, &p, &q, &r,
364
0
                                             &s, &t, &u, &v, &w, &x, &y, &z,
365
0
                                             null_alphanum);
366
0
}
367
368
// ----------------------------------------------------------------------
369
// StrAppend()
370
//    Same as above, but adds the output to the given string.
371
//    WARNING: For speed, StrAppend does not try to check each of its input
372
//    arguments to be sure that they are not a subset of the string being
373
//    appended to.  That is, while this will work:
374
//
375
//    string s = "foo";
376
//    s += s;
377
//
378
//    This will not (necessarily) work:
379
//
380
//    string s = "foo";
381
//    StrAppend(&s, s);
382
//
383
//    Note: while StrCat supports appending up to 12 arguments, StrAppend
384
//    is currently limited to 9.  That's rarely an issue except when
385
//    automatically transforming StrCat to StrAppend, and can easily be
386
//    worked around as consecutive calls to StrAppend are quite efficient.
387
// ----------------------------------------------------------------------
388
389
void StrAppend(string *dest,      const AlphaNum &a);
390
void StrAppend(string *dest,      const AlphaNum &a, const AlphaNum &b);
391
void StrAppend(string *dest,      const AlphaNum &a, const AlphaNum &b,
392
               const AlphaNum &c);
393
void StrAppend(string *dest,      const AlphaNum &a, const AlphaNum &b,
394
               const AlphaNum &c, const AlphaNum &d);
395
396
// Support up to 9 params by using a default empty AlphaNum.
397
void StrAppend(string *dest,      const AlphaNum &a, const AlphaNum &b,
398
               const AlphaNum &c, const AlphaNum &d, const AlphaNum &e,
399
               const AlphaNum &f = gEmptyAlphaNum,
400
               const AlphaNum &g = gEmptyAlphaNum,
401
               const AlphaNum &h = gEmptyAlphaNum,
402
               const AlphaNum &i = gEmptyAlphaNum);
403
404
#endif  // YB_GUTIL_STRINGS_STRCAT_H