Coverage Report

Created: 2018-09-17 19:50

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/ADT/StringExtras.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/ADT/StringExtras.h - Useful string functions --------*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file contains some functions that are useful when dealing with strings.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_ADT_STRINGEXTRAS_H
15
#define LLVM_ADT_STRINGEXTRAS_H
16
17
#include "llvm/ADT/ArrayRef.h"
18
#include "llvm/ADT/SmallString.h"
19
#include "llvm/ADT/StringRef.h"
20
#include "llvm/ADT/Twine.h"
21
#include <cassert>
22
#include <cstddef>
23
#include <cstdint>
24
#include <cstdlib>
25
#include <cstring>
26
#include <iterator>
27
#include <string>
28
#include <utility>
29
30
namespace llvm {
31
32
template<typename T> class SmallVectorImpl;
33
class raw_ostream;
34
35
/// hexdigit - Return the hexadecimal character for the
36
/// given number \p X (which should be less than 16).
37
48.2M
inline char hexdigit(unsigned X, bool LowerCase = false) {
38
48.2M
  const char HexChar = LowerCase ? 
'a'1.29M
:
'A'46.9M
;
39
48.2M
  return X < 10 ? 
'0' + X44.3M
:
HexChar + X - 103.84M
;
40
48.2M
}
41
42
/// Given an array of c-style strings terminated by a null pointer, construct
43
/// a vector of StringRefs representing the same strings without the terminating
44
/// null string.
45
18.0k
inline std::vector<StringRef> toStringRefArray(const char *const *Strings) {
46
18.0k
  std::vector<StringRef> Result;
47
1.23M
  while (*Strings)
48
1.21M
    Result.push_back(*Strings++);
49
18.0k
  return Result;
50
18.0k
}
51
52
/// Construct a string ref from a boolean.
53
4.32M
inline StringRef toStringRef(bool B) { return StringRef(B ? 
"true"4.05k
:
"false"4.32M
); }
54
55
/// Construct a string ref from an array ref of unsigned chars.
56
5.95k
inline StringRef toStringRef(ArrayRef<uint8_t> Input) {
57
5.95k
  return StringRef(reinterpret_cast<const char *>(Input.begin()), Input.size());
58
5.95k
}
59
60
/// Construct a string ref from an array ref of unsigned chars.
61
10.5k
inline ArrayRef<uint8_t> arrayRefFromStringRef(StringRef Input) {
62
10.5k
  return {Input.bytes_begin(), Input.bytes_end()};
63
10.5k
}
64
65
/// Interpret the given character \p C as a hexadecimal digit and return its
66
/// value.
67
///
68
/// If \p C is not a valid hex digit, -1U is returned.
69
14.6M
inline unsigned hexDigitValue(char C) {
70
14.6M
  if (C >= '0' && 
C <= '9'14.2M
)
return C-'0'13.5M
;
71
1.11M
  if (C >= 'a' && 
C <= 'f'312k
)
return C-'a'+10U298k
;
72
817k
  if (C >= 'A' && 
C <= 'F'288k
)
return C-'A'+10U138k
;
73
678k
  return -1U;
74
678k
}
75
76
/// Checks if character \p C is one of the 10 decimal digits.
77
12.8M
inline bool isDigit(char C) { return C >= '0' && 
C <= '9'9.26M
; }
78
79
/// Checks if character \p C is a hexadecimal numeric character.
80
853k
inline bool isHexDigit(char C) { return hexDigitValue(C) != -1U; }
81
82
/// Checks if character \p C is a valid letter as classified by "C" locale.
83
41.2M
inline bool isAlpha(char C) {
84
41.2M
  return ('a' <= C && 
C <= 'z'33.2M
) ||
(8.03M
'A' <= C8.03M
&&
C <= 'Z'2.38M
);
85
41.2M
}
86
87
/// Checks whether character \p C is either a decimal digit or an uppercase or
88
/// lowercase letter as classified by "C" locale.
89
40.9M
inline bool isAlnum(char C) { return isAlpha(C) || 
isDigit(C)6.82M
; }
90
91
/// Checks whether character \p C is valid ASCII (high bit is zero).
92
164k
inline bool isASCII(char C) { return static_cast<unsigned char>(C) <= 127; }
93
94
/// Checks whether all characters in S are ASCII.
95
67.0k
inline bool isASCII(llvm::StringRef S) {
96
67.0k
  for (char C : S)
97
164k
    if (LLVM_UNLIKELY(!isASCII(C)))
98
164k
      
return false21
;
99
67.0k
  
return true67.0k
;
100
67.0k
}
101
102
/// Checks whether character \p C is printable.
103
///
104
/// Locale-independent version of the C standard library isprint whose results
105
/// may differ on different platforms.
106
37.1M
inline bool isPrint(char C) {
107
37.1M
  unsigned char UC = static_cast<unsigned char>(C);
108
37.1M
  return (0x20 <= UC) && 
(UC <= 0x7E)27.0M
;
109
37.1M
}
110
111
/// Returns the corresponding lowercase character if \p x is uppercase.
112
208M
inline char toLower(char x) {
113
208M
  if (x >= 'A' && 
x <= 'Z'158M
)
114
87.1M
    return x - 'A' + 'a';
115
121M
  return x;
116
121M
}
117
118
/// Returns the corresponding uppercase character if \p x is lowercase.
119
1.58M
inline char toUpper(char x) {
120
1.58M
  if (x >= 'a' && 
x <= 'z'1.09M
)
121
1.09M
    return x - 'a' + 'A';
122
490k
  return x;
123
490k
}
124
125
8.71k
inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
126
8.71k
  char Buffer[17];
127
8.71k
  char *BufPtr = std::end(Buffer);
128
8.71k
129
8.71k
  if (X == 0) 
*--BufPtr = '0'289
;
130
8.71k
131
38.7k
  while (X) {
132
29.9k
    unsigned char Mod = static_cast<unsigned char>(X) & 15;
133
29.9k
    *--BufPtr = hexdigit(Mod, LowerCase);
134
29.9k
    X >>= 4;
135
29.9k
  }
136
8.71k
137
8.71k
  return std::string(BufPtr, std::end(Buffer));
138
8.71k
}
139
140
/// Convert buffer \p Input to its hexadecimal representation.
141
/// The returned string is double the size of \p Input.
142
467
inline std::string toHex(StringRef Input, bool LowerCase = false) {
143
467
  static const char *const LUT = "0123456789ABCDEF";
144
467
  const uint8_t Offset = LowerCase ? 
322
:
0465
;
145
467
  size_t Length = Input.size();
146
467
147
467
  std::string Output;
148
467
  Output.reserve(2 * Length);
149
8.11k
  for (size_t i = 0; i < Length; 
++i7.64k
) {
150
7.64k
    const unsigned char c = Input[i];
151
7.64k
    Output.push_back(LUT[c >> 4] | Offset);
152
7.64k
    Output.push_back(LUT[c & 15] | Offset);
153
7.64k
  }
154
467
  return Output;
155
467
}
156
157
361
inline std::string toHex(ArrayRef<uint8_t> Input, bool LowerCase = false) {
158
361
  return toHex(toStringRef(Input), LowerCase);
159
361
}
160
161
3.35k
inline uint8_t hexFromNibbles(char MSB, char LSB) {
162
3.35k
  unsigned U1 = hexDigitValue(MSB);
163
3.35k
  unsigned U2 = hexDigitValue(LSB);
164
3.35k
  assert(U1 != -1U && U2 != -1U);
165
3.35k
166
3.35k
  return static_cast<uint8_t>((U1 << 4) | U2);
167
3.35k
}
168
169
/// Convert hexadecimal string \p Input to its binary representation.
170
/// The return string is half the size of \p Input.
171
231
inline std::string fromHex(StringRef Input) {
172
231
  if (Input.empty())
173
20
    return std::string();
174
211
175
211
  std::string Output;
176
211
  Output.reserve((Input.size() + 1) / 2);
177
211
  if (Input.size() % 2 == 1) {
178
1
    Output.push_back(hexFromNibbles('0', Input.front()));
179
1
    Input = Input.drop_front();
180
1
  }
181
211
182
211
  assert(Input.size() % 2 == 0);
183
3.56k
  while (!Input.empty()) {
184
3.35k
    uint8_t Hex = hexFromNibbles(Input[0], Input[1]);
185
3.35k
    Output.push_back(Hex);
186
3.35k
    Input = Input.drop_front(2);
187
3.35k
  }
188
211
  return Output;
189
211
}
190
191
/// Convert the string \p S to an integer of the specified type using
192
/// the radix \p Base.  If \p Base is 0, auto-detects the radix.
193
/// Returns true if the number was successfully converted, false otherwise.
194
2.54k
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
2.54k
  return !S.getAsInteger(Base, Num);
196
2.54k
}
bool llvm::to_integer<unsigned int>(llvm::StringRef, unsigned int&, unsigned int)
Line
Count
Source
194
534
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
534
  return !S.getAsInteger(Base, Num);
196
534
}
bool llvm::to_integer<unsigned long long>(llvm::StringRef, unsigned long long&, unsigned int)
Line
Count
Source
194
1.93k
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
1.93k
  return !S.getAsInteger(Base, Num);
196
1.93k
}
bool llvm::to_integer<int>(llvm::StringRef, int&, unsigned int)
Line
Count
Source
194
57
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
57
  return !S.getAsInteger(Base, Num);
196
57
}
bool llvm::to_integer<unsigned char>(llvm::StringRef, unsigned char&, unsigned int)
Line
Count
Source
194
12
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
12
  return !S.getAsInteger(Base, Num);
196
12
}
197
198
namespace detail {
199
template <typename N>
200
46
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
201
46
  SmallString<32> Storage;
202
46
  StringRef S = T.toNullTerminatedStringRef(Storage);
203
46
  char *End;
204
46
  N Temp = StrTo(S.data(), &End);
205
46
  if (*End != '\0')
206
4
    return false;
207
42
  Num = Temp;
208
42
  return true;
209
42
}
bool llvm::detail::to_float<double>(llvm::Twine const&, double&, double (*)(char const*, char**))
Line
Count
Source
200
35
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
201
35
  SmallString<32> Storage;
202
35
  StringRef S = T.toNullTerminatedStringRef(Storage);
203
35
  char *End;
204
35
  N Temp = StrTo(S.data(), &End);
205
35
  if (*End != '\0')
206
1
    return false;
207
34
  Num = Temp;
208
34
  return true;
209
34
}
bool llvm::detail::to_float<float>(llvm::Twine const&, float&, float (*)(char const*, char**))
Line
Count
Source
200
11
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
201
11
  SmallString<32> Storage;
202
11
  StringRef S = T.toNullTerminatedStringRef(Storage);
203
11
  char *End;
204
11
  N Temp = StrTo(S.data(), &End);
205
11
  if (*End != '\0')
206
3
    return false;
207
8
  Num = Temp;
208
8
  return true;
209
8
}
210
}
211
212
11
inline bool to_float(const Twine &T, float &Num) {
213
11
  return detail::to_float(T, Num, strtof);
214
11
}
215
216
35
inline bool to_float(const Twine &T, double &Num) {
217
35
  return detail::to_float(T, Num, strtod);
218
35
}
219
220
inline bool to_float(const Twine &T, long double &Num) {
221
  return detail::to_float(T, Num, strtold);
222
}
223
224
11.0M
inline std::string utostr(uint64_t X, bool isNeg = false) {
225
11.0M
  char Buffer[21];
226
11.0M
  char *BufPtr = std::end(Buffer);
227
11.0M
228
11.0M
  if (X == 0) 
*--BufPtr = '0'1.64M
; // Handle special case...
229
11.0M
230
34.8M
  while (X) {
231
23.8M
    *--BufPtr = '0' + char(X % 10);
232
23.8M
    X /= 10;
233
23.8M
  }
234
11.0M
235
11.0M
  if (isNeg) 
*--BufPtr = '-'92.9k
; // Add negative sign...
236
11.0M
  return std::string(BufPtr, std::end(Buffer));
237
11.0M
}
238
239
4.28M
inline std::string itostr(int64_t X) {
240
4.28M
  if (X < 0)
241
92.9k
    return utostr(static_cast<uint64_t>(-X), true);
242
4.18M
  else
243
4.18M
    return utostr(static_cast<uint64_t>(X));
244
4.28M
}
245
246
/// StrInStrNoCase - Portable version of strcasestr.  Locates the first
247
/// occurrence of string 's1' in string 's2', ignoring case.  Returns
248
/// the offset of s2 in s1 or npos if s2 cannot be found.
249
StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
250
251
/// getToken - This function extracts one token from source, ignoring any
252
/// leading characters that appear in the Delimiters string, and ending the
253
/// token at any of the characters that appear in the Delimiters string.  If
254
/// there are no tokens in the source string, an empty string is returned.
255
/// The function returns a pair containing the extracted token and the
256
/// remaining tail string.
257
std::pair<StringRef, StringRef> getToken(StringRef Source,
258
                                         StringRef Delimiters = " \t\n\v\f\r");
259
260
/// SplitString - Split up the specified string according to the specified
261
/// delimiters, appending the result fragments to the output list.
262
void SplitString(StringRef Source,
263
                 SmallVectorImpl<StringRef> &OutFragments,
264
                 StringRef Delimiters = " \t\n\v\f\r");
265
266
/// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
267
5.75k
inline StringRef getOrdinalSuffix(unsigned Val) {
268
5.75k
  // It is critically important that we do this perfectly for
269
5.75k
  // user-written sequences with over 100 elements.
270
5.75k
  switch (Val % 100) {
271
5.75k
  case 11:
272
0
  case 12:
273
0
  case 13:
274
0
    return "th";
275
5.75k
  default:
276
5.75k
    switch (Val % 10) {
277
5.75k
      
case 1: return "st"5.38k
;
278
5.75k
      
case 2: return "nd"255
;
279
5.75k
      
case 3: return "rd"101
;
280
5.75k
      
default: return "th"15
;
281
5.75k
    }
282
5.75k
  }
283
5.75k
}
284
285
/// Print each character of the specified string, escaping it if it is not
286
/// printable or if it is an escape char.
287
void printEscapedString(StringRef Name, raw_ostream &Out);
288
289
/// Print each character of the specified string, escaping HTML special
290
/// characters.
291
void printHTMLEscaped(StringRef String, raw_ostream &Out);
292
293
/// printLowerCase - Print each character as lowercase if it is uppercase.
294
void printLowerCase(StringRef String, raw_ostream &Out);
295
296
namespace detail {
297
298
template <typename IteratorT>
299
inline std::string join_impl(IteratorT Begin, IteratorT End,
300
                             StringRef Separator, std::input_iterator_tag) {
301
  std::string S;
302
  if (Begin == End)
303
    return S;
304
305
  S += (*Begin);
306
  while (++Begin != End) {
307
    S += Separator;
308
    S += (*Begin);
309
  }
310
  return S;
311
}
312
313
template <typename IteratorT>
314
inline std::string join_impl(IteratorT Begin, IteratorT End,
315
845k
                             StringRef Separator, std::forward_iterator_tag) {
316
845k
  std::string S;
317
845k
  if (Begin == End)
318
23.5k
    return S;
319
821k
320
821k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
6.79M
  for (IteratorT I = Begin; I != End; 
++I5.97M
)
322
5.97M
    Len += (*Begin).size();
323
821k
  S.reserve(Len);
324
821k
  S += (*Begin);
325
5.97M
  while (++Begin != End) {
326
5.15M
    S += Separator;
327
5.15M
    S += (*Begin);
328
5.15M
  }
329
821k
  return S;
330
821k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::detail::join_impl<std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*> >(std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*>, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*>, llvm::StringRef, std::__1::forward_iterator_tag)
Line
Count
Source
315
785k
                             StringRef Separator, std::forward_iterator_tag) {
316
785k
  std::string S;
317
785k
  if (Begin == End)
318
4
    return S;
319
785k
320
785k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
6.60M
  for (IteratorT I = Begin; I != End; 
++I5.82M
)
322
5.82M
    Len += (*Begin).size();
323
785k
  S.reserve(Len);
324
785k
  S += (*Begin);
325
5.82M
  while (++Begin != End) {
326
5.03M
    S += Separator;
327
5.03M
    S += (*Begin);
328
5.03M
  }
329
785k
  return S;
330
785k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::detail::join_impl<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, llvm::StringRef, std::__1::forward_iterator_tag)
Line
Count
Source
315
2.62k
                             StringRef Separator, std::forward_iterator_tag) {
316
2.62k
  std::string S;
317
2.62k
  if (Begin == End)
318
24
    return S;
319
2.60k
320
2.60k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
5.39k
  for (IteratorT I = Begin; I != End; 
++I2.79k
)
322
2.79k
    Len += (*Begin).size();
323
2.60k
  S.reserve(Len);
324
2.60k
  S += (*Begin);
325
2.79k
  while (++Begin != End) {
326
199
    S += Separator;
327
199
    S += (*Begin);
328
199
  }
329
2.60k
  return S;
330
2.60k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::detail::join_impl<llvm::StringRef*>(llvm::StringRef*, llvm::StringRef*, llvm::StringRef, std::__1::forward_iterator_tag)
Line
Count
Source
315
3.40k
                             StringRef Separator, std::forward_iterator_tag) {
316
3.40k
  std::string S;
317
3.40k
  if (Begin == End)
318
1.14k
    return S;
319
2.26k
320
2.26k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
8.72k
  for (IteratorT I = Begin; I != End; 
++I6.46k
)
322
6.46k
    Len += (*Begin).size();
323
2.26k
  S.reserve(Len);
324
2.26k
  S += (*Begin);
325
6.46k
  while (++Begin != End) {
326
4.19k
    S += Separator;
327
4.19k
    S += (*Begin);
328
4.19k
  }
329
2.26k
  return S;
330
2.26k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::detail::join_impl<std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> >(std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>, llvm::StringRef, std::__1::forward_iterator_tag)
Line
Count
Source
315
49.4k
                             StringRef Separator, std::forward_iterator_tag) {
316
49.4k
  std::string S;
317
49.4k
  if (Begin == End)
318
19.9k
    return S;
319
29.5k
320
29.5k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
170k
  for (IteratorT I = Begin; I != End; 
++I140k
)
322
140k
    Len += (*Begin).size();
323
29.5k
  S.reserve(Len);
324
29.5k
  S += (*Begin);
325
140k
  while (++Begin != End) {
326
111k
    S += Separator;
327
111k
    S += (*Begin);
328
111k
  }
329
29.5k
  return S;
330
29.5k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::detail::join_impl<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*, llvm::StringRef, std::__1::forward_iterator_tag)
Line
Count
Source
315
804
                             StringRef Separator, std::forward_iterator_tag) {
316
804
  std::string S;
317
804
  if (Begin == End)
318
0
    return S;
319
804
320
804
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
2.42k
  for (IteratorT I = Begin; I != End; 
++I1.62k
)
322
1.62k
    Len += (*Begin).size();
323
804
  S.reserve(Len);
324
804
  S += (*Begin);
325
1.62k
  while (++Begin != End) {
326
821
    S += Separator;
327
821
    S += (*Begin);
328
821
  }
329
804
  return S;
330
804
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::detail::join_impl<std::__1::__wrap_iter<llvm::StringRef*> >(std::__1::__wrap_iter<llvm::StringRef*>, std::__1::__wrap_iter<llvm::StringRef*>, llvm::StringRef, std::__1::forward_iterator_tag)
Line
Count
Source
315
3.11k
                             StringRef Separator, std::forward_iterator_tag) {
316
3.11k
  std::string S;
317
3.11k
  if (Begin == End)
318
2.49k
    return S;
319
616
320
616
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
3.59k
  for (IteratorT I = Begin; I != End; 
++I2.97k
)
322
2.97k
    Len += (*Begin).size();
323
616
  S.reserve(Len);
324
616
  S += (*Begin);
325
2.97k
  while (++Begin != End) {
326
2.35k
    S += Separator;
327
2.35k
    S += (*Begin);
328
2.35k
  }
329
616
  return S;
330
616
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::detail::join_impl<llvm::StringRef const*>(llvm::StringRef const*, llvm::StringRef const*, llvm::StringRef, std::__1::forward_iterator_tag)
Line
Count
Source
315
78
                             StringRef Separator, std::forward_iterator_tag) {
316
78
  std::string S;
317
78
  if (Begin == End)
318
0
    return S;
319
78
320
78
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
571
  for (IteratorT I = Begin; I != End; 
++I493
)
322
493
    Len += (*Begin).size();
323
78
  S.reserve(Len);
324
78
  S += (*Begin);
325
493
  while (++Begin != End) {
326
415
    S += Separator;
327
415
    S += (*Begin);
328
415
  }
329
78
  return S;
330
78
}
331
332
template <typename Sep>
333
inline void join_items_impl(std::string &Result, Sep Separator) {}
334
335
template <typename Sep, typename Arg>
336
inline void join_items_impl(std::string &Result, Sep Separator,
337
                            const Arg &Item) {
338
  Result += Item;
339
}
340
341
template <typename Sep, typename Arg1, typename... Args>
342
inline void join_items_impl(std::string &Result, Sep Separator, const Arg1 &A1,
343
                            Args &&... Items) {
344
  Result += A1;
345
  Result += Separator;
346
  join_items_impl(Result, Separator, std::forward<Args>(Items)...);
347
}
348
349
inline size_t join_one_item_size(char C) { return 1; }
350
inline size_t join_one_item_size(const char *S) { return S ? ::strlen(S) : 0; }
351
352
template <typename T> inline size_t join_one_item_size(const T &Str) {
353
  return Str.size();
354
}
355
356
inline size_t join_items_size() { return 0; }
357
358
template <typename A1> inline size_t join_items_size(const A1 &A) {
359
  return join_one_item_size(A);
360
}
361
template <typename A1, typename... Args>
362
inline size_t join_items_size(const A1 &A, Args &&... Items) {
363
  return join_one_item_size(A) + join_items_size(std::forward<Args>(Items)...);
364
}
365
366
} // end namespace detail
367
368
/// Joins the strings in the range [Begin, End), adding Separator between
369
/// the elements.
370
template <typename IteratorT>
371
845k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
845k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
845k
  return detail::join_impl(Begin, End, Separator, tag());
374
845k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*> >(std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*>, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*>, llvm::StringRef)
Line
Count
Source
371
785k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
785k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
785k
  return detail::join_impl(Begin, End, Separator, tag());
374
785k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, llvm::StringRef)
Line
Count
Source
371
2.62k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
2.62k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
2.62k
  return detail::join_impl(Begin, End, Separator, tag());
374
2.62k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<llvm::StringRef*>(llvm::StringRef*, llvm::StringRef*, llvm::StringRef)
Line
Count
Source
371
3.40k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
3.40k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
3.40k
  return detail::join_impl(Begin, End, Separator, tag());
374
3.40k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*> >(std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>, std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>, llvm::StringRef)
Line
Count
Source
371
49.4k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
49.4k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
49.4k
  return detail::join_impl(Begin, End, Separator, tag());
374
49.4k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*, llvm::StringRef)
Line
Count
Source
371
804
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
804
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
804
  return detail::join_impl(Begin, End, Separator, tag());
374
804
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<std::__1::__wrap_iter<llvm::StringRef*> >(std::__1::__wrap_iter<llvm::StringRef*>, std::__1::__wrap_iter<llvm::StringRef*>, llvm::StringRef)
Line
Count
Source
371
3.11k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
3.11k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
3.11k
  return detail::join_impl(Begin, End, Separator, tag());
374
3.11k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<llvm::StringRef const*>(llvm::StringRef const*, llvm::StringRef const*, llvm::StringRef)
Line
Count
Source
371
78
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
78
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
78
  return detail::join_impl(Begin, End, Separator, tag());
374
78
}
375
376
/// Joins the strings in the range [R.begin(), R.end()), adding Separator
377
/// between the elements.
378
template <typename Range>
379
785k
inline std::string join(Range &&R, StringRef Separator) {
380
785k
  return join(R.begin(), R.end(), Separator);
381
785k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<llvm::SmallVector<llvm::StringRef, 32u>&>(llvm::SmallVector<llvm::StringRef, 32u>&&&, llvm::StringRef)
Line
Count
Source
379
57
inline std::string join(Range &&R, StringRef Separator) {
380
57
  return join(R.begin(), R.end(), Separator);
381
57
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&&&, llvm::StringRef)
Line
Count
Source
379
1
inline std::string join(Range &&R, StringRef Separator) {
380
1
  return join(R.begin(), R.end(), Separator);
381
1
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&&&, llvm::StringRef)
Line
Count
Source
379
785k
inline std::string join(Range &&R, StringRef Separator) {
380
785k
  return join(R.begin(), R.end(), Separator);
381
785k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<llvm::ArrayRef<llvm::StringRef>&>(llvm::ArrayRef<llvm::StringRef>&&&, llvm::StringRef)
Line
Count
Source
379
78
inline std::string join(Range &&R, StringRef Separator) {
380
78
  return join(R.begin(), R.end(), Separator);
381
78
}
382
383
/// Joins the strings in the parameter pack \p Items, adding \p Separator
384
/// between the elements.  All arguments must be implicitly convertible to
385
/// std::string, or there should be an overload of std::string::operator+=()
386
/// that accepts the argument explicitly.
387
template <typename Sep, typename... Args>
388
inline std::string join_items(Sep Separator, Args &&... Items) {
389
  std::string Result;
390
  if (sizeof...(Items) == 0)
391
    return Result;
392
393
  size_t NS = detail::join_one_item_size(Separator);
394
  size_t NI = detail::join_items_size(std::forward<Args>(Items)...);
395
  Result.reserve(NI + (sizeof...(Items) - 1) * NS + 1);
396
  detail::join_items_impl(Result, Separator, std::forward<Args>(Items)...);
397
  return Result;
398
}
399
400
} // end namespace llvm
401
402
#endif // LLVM_ADT_STRINGEXTRAS_H