Coverage Report

Created: 2018-11-13 17:19

/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.31M
:
'A'46.9M
;
39
48.2M
  return X < 10 ? 
'0' + X44.4M
:
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.1k
inline std::vector<StringRef> toStringRefArray(const char *const *Strings) {
46
18.1k
  std::vector<StringRef> Result;
47
1.26M
  while (*Strings)
48
1.24M
    Result.push_back(*Strings++);
49
18.1k
  return Result;
50
18.1k
}
51
52
/// Construct a string ref from a boolean.
53
4.35M
inline StringRef toStringRef(bool B) { return StringRef(B ? 
"true"4.17k
:
"false"4.35M
); }
54
55
/// Construct a string ref from an array ref of unsigned chars.
56
6.22k
inline StringRef toStringRef(ArrayRef<uint8_t> Input) {
57
6.22k
  return StringRef(reinterpret_cast<const char *>(Input.begin()), Input.size());
58
6.22k
}
59
60
/// Construct a string ref from an array ref of unsigned chars.
61
11.5k
inline ArrayRef<uint8_t> arrayRefFromStringRef(StringRef Input) {
62
11.5k
  return {Input.bytes_begin(), Input.bytes_end()};
63
11.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.1M
inline unsigned hexDigitValue(char C) {
70
14.1M
  if (C >= '0' && 
C <= '9'14.1M
)
return C-'0'13.6M
;
71
493k
  if (C >= 'a' && 
C <= 'f'302k
)
return C-'a'+10U301k
;
72
191k
  if (C >= 'A' && 
C <= 'F'141k
)
return C-'A'+10U138k
;
73
52.7k
  return -1U;
74
52.7k
}
75
76
/// Checks if character \p C is one of the 10 decimal digits.
77
13.1M
inline bool isDigit(char C) { return C >= '0' && 
C <= '9'9.46M
; }
78
79
/// Checks if character \p C is a hexadecimal numeric character.
80
231k
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.4M
inline bool isAlpha(char C) {
84
41.4M
  return ('a' <= C && 
C <= 'z'33.3M
) ||
(8.17M
'A' <= C8.17M
&&
C <= 'Z'2.45M
);
85
41.4M
}
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
41.1M
inline bool isAlnum(char C) { return isAlpha(C) || 
isDigit(C)6.90M
; }
90
91
/// Checks whether character \p C is valid ASCII (high bit is zero).
92
169k
inline bool isASCII(char C) { return static_cast<unsigned char>(C) <= 127; }
93
94
/// Checks whether all characters in S are ASCII.
95
76.9k
inline bool isASCII(llvm::StringRef S) {
96
76.9k
  for (char C : S)
97
169k
    if (LLVM_UNLIKELY(!isASCII(C)))
98
169k
      
return false21
;
99
76.9k
  
return true76.8k
;
100
76.9k
}
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.3M
inline bool isPrint(char C) {
107
37.3M
  unsigned char UC = static_cast<unsigned char>(C);
108
37.3M
  return (0x20 <= UC) && 
(UC <= 0x7E)27.2M
;
109
37.3M
}
110
111
/// Returns the corresponding lowercase character if \p x is uppercase.
112
219M
inline char toLower(char x) {
113
219M
  if (x >= 'A' && 
x <= 'Z'165M
)
114
92.6M
    return x - 'A' + 'a';
115
126M
  return x;
116
126M
}
117
118
/// Returns the corresponding uppercase character if \p x is lowercase.
119
1.59M
inline char toUpper(char x) {
120
1.59M
  if (x >= 'a' && 
x <= 'z'1.10M
)
121
1.09M
    return x - 'a' + 'A';
122
496k
  return x;
123
496k
}
124
125
17.6k
inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
126
17.6k
  char Buffer[17];
127
17.6k
  char *BufPtr = std::end(Buffer);
128
17.6k
129
17.6k
  if (X == 0) 
*--BufPtr = '0'2.27k
;
130
17.6k
131
58.8k
  while (X) {
132
41.1k
    unsigned char Mod = static_cast<unsigned char>(X) & 15;
133
41.1k
    *--BufPtr = hexdigit(Mod, LowerCase);
134
41.1k
    X >>= 4;
135
41.1k
  }
136
17.6k
137
17.6k
  return std::string(BufPtr, std::end(Buffer));
138
17.6k
}
139
140
/// Convert buffer \p Input to its hexadecimal representation.
141
/// The returned string is double the size of \p Input.
142
489
inline std::string toHex(StringRef Input, bool LowerCase = false) {
143
489
  static const char *const LUT = "0123456789ABCDEF";
144
489
  const uint8_t Offset = LowerCase ? 
322
:
0487
;
145
489
  size_t Length = Input.size();
146
489
147
489
  std::string Output;
148
489
  Output.reserve(2 * Length);
149
8.37k
  for (size_t i = 0; i < Length; 
++i7.88k
) {
150
7.88k
    const unsigned char c = Input[i];
151
7.88k
    Output.push_back(LUT[c >> 4] | Offset);
152
7.88k
    Output.push_back(LUT[c & 15] | Offset);
153
7.88k
  }
154
489
  return Output;
155
489
}
156
157
372
inline std::string toHex(ArrayRef<uint8_t> Input, bool LowerCase = false) {
158
372
  return toHex(toStringRef(Input), LowerCase);
159
372
}
160
161
5.16k
inline uint8_t hexFromNibbles(char MSB, char LSB) {
162
5.16k
  unsigned U1 = hexDigitValue(MSB);
163
5.16k
  unsigned U2 = hexDigitValue(LSB);
164
5.16k
  assert(U1 != -1U && U2 != -1U);
165
5.16k
166
5.16k
  return static_cast<uint8_t>((U1 << 4) | U2);
167
5.16k
}
168
169
/// Convert hexadecimal string \p Input to its binary representation.
170
/// The return string is half the size of \p Input.
171
344
inline std::string fromHex(StringRef Input) {
172
344
  if (Input.empty())
173
20
    return std::string();
174
324
175
324
  std::string Output;
176
324
  Output.reserve((Input.size() + 1) / 2);
177
324
  if (Input.size() % 2 == 1) {
178
1
    Output.push_back(hexFromNibbles('0', Input.front()));
179
1
    Input = Input.drop_front();
180
1
  }
181
324
182
324
  assert(Input.size() % 2 == 0);
183
5.48k
  while (!Input.empty()) {
184
5.16k
    uint8_t Hex = hexFromNibbles(Input[0], Input[1]);
185
5.16k
    Output.push_back(Hex);
186
5.16k
    Input = Input.drop_front(2);
187
5.16k
  }
188
324
  return Output;
189
324
}
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.68k
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
2.68k
  return !S.getAsInteger(Base, Num);
196
2.68k
}
bool llvm::to_integer<unsigned int>(llvm::StringRef, unsigned int&, unsigned int)
Line
Count
Source
194
530
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
530
  return !S.getAsInteger(Base, Num);
196
530
}
bool llvm::to_integer<unsigned long long>(llvm::StringRef, unsigned long long&, unsigned int)
Line
Count
Source
194
2.05k
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
2.05k
  return !S.getAsInteger(Base, Num);
196
2.05k
}
bool llvm::to_integer<int>(llvm::StringRef, int&, unsigned int)
Line
Count
Source
194
86
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
195
86
  return !S.getAsInteger(Base, Num);
196
86
}
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
50
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
201
50
  SmallString<32> Storage;
202
50
  StringRef S = T.toNullTerminatedStringRef(Storage);
203
50
  char *End;
204
50
  N Temp = StrTo(S.data(), &End);
205
50
  if (*End != '\0')
206
4
    return false;
207
46
  Num = Temp;
208
46
  return true;
209
46
}
bool llvm::detail::to_float<double>(llvm::Twine const&, double&, double (*)(char const*, char**))
Line
Count
Source
200
39
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
201
39
  SmallString<32> Storage;
202
39
  StringRef S = T.toNullTerminatedStringRef(Storage);
203
39
  char *End;
204
39
  N Temp = StrTo(S.data(), &End);
205
39
  if (*End != '\0')
206
1
    return false;
207
38
  Num = Temp;
208
38
  return true;
209
38
}
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
39
inline bool to_float(const Twine &T, double &Num) {
217
39
  return detail::to_float(T, Num, strtod);
218
39
}
219
220
inline bool to_float(const Twine &T, long double &Num) {
221
  return detail::to_float(T, Num, strtold);
222
}
223
224
13.0M
inline std::string utostr(uint64_t X, bool isNeg = false) {
225
13.0M
  char Buffer[21];
226
13.0M
  char *BufPtr = std::end(Buffer);
227
13.0M
228
13.0M
  if (X == 0) 
*--BufPtr = '0'2.17M
; // Handle special case...
229
13.0M
230
39.4M
  while (X) {
231
26.4M
    *--BufPtr = '0' + char(X % 10);
232
26.4M
    X /= 10;
233
26.4M
  }
234
13.0M
235
13.0M
  if (isNeg) 
*--BufPtr = '-'92.5k
; // Add negative sign...
236
13.0M
  return std::string(BufPtr, std::end(Buffer));
237
13.0M
}
238
239
5.79M
inline std::string itostr(int64_t X) {
240
5.79M
  if (X < 0)
241
92.5k
    return utostr(static_cast<uint64_t>(-X), true);
242
5.70M
  else
243
5.70M
    return utostr(static_cast<uint64_t>(X));
244
5.79M
}
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.77k
inline StringRef getOrdinalSuffix(unsigned Val) {
268
5.77k
  // It is critically important that we do this perfectly for
269
5.77k
  // user-written sequences with over 100 elements.
270
5.77k
  switch (Val % 100) {
271
5.77k
  case 11:
272
0
  case 12:
273
0
  case 13:
274
0
    return "th";
275
5.77k
  default:
276
5.77k
    switch (Val % 10) {
277
5.77k
      
case 1: return "st"5.40k
;
278
5.77k
      
case 2: return "nd"255
;
279
5.77k
      
case 3: return "rd"100
;
280
5.77k
      
default: return "th"15
;
281
5.77k
    }
282
5.77k
  }
283
5.77k
}
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
855k
                             StringRef Separator, std::forward_iterator_tag) {
316
855k
  std::string S;
317
855k
  if (Begin == End)
318
24.5k
    return S;
319
831k
320
831k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
7.53M
  for (IteratorT I = Begin; I != End; 
++I6.70M
)
322
6.70M
    Len += (*Begin).size();
323
831k
  S.reserve(Len);
324
831k
  S += (*Begin);
325
6.70M
  while (++Begin != End) {
326
5.87M
    S += Separator;
327
5.87M
    S += (*Begin);
328
5.87M
  }
329
831k
  return S;
330
831k
}
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
793k
                             StringRef Separator, std::forward_iterator_tag) {
316
793k
  std::string S;
317
793k
  if (Begin == End)
318
5
    return S;
319
793k
320
793k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
7.32M
  for (IteratorT I = Begin; I != End; 
++I6.53M
)
322
6.53M
    Len += (*Begin).size();
323
793k
  S.reserve(Len);
324
793k
  S += (*Begin);
325
6.53M
  while (++Begin != End) {
326
5.73M
    S += Separator;
327
5.73M
    S += (*Begin);
328
5.73M
  }
329
793k
  return S;
330
793k
}
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
3.02k
                             StringRef Separator, std::forward_iterator_tag) {
316
3.02k
  std::string S;
317
3.02k
  if (Begin == End)
318
24
    return S;
319
3.00k
320
3.00k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
6.20k
  for (IteratorT I = Begin; I != End; 
++I3.20k
)
322
3.20k
    Len += (*Begin).size();
323
3.00k
  S.reserve(Len);
324
3.00k
  S += (*Begin);
325
3.20k
  while (++Begin != End) {
326
199
    S += Separator;
327
199
    S += (*Begin);
328
199
  }
329
3.00k
  return S;
330
3.00k
}
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.43k
                             StringRef Separator, std::forward_iterator_tag) {
316
3.43k
  std::string S;
317
3.43k
  if (Begin == End)
318
1.15k
    return S;
319
2.27k
320
2.27k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
8.74k
  for (IteratorT I = Begin; I != End; 
++I6.47k
)
322
6.47k
    Len += (*Begin).size();
323
2.27k
  S.reserve(Len);
324
2.27k
  S += (*Begin);
325
6.47k
  while (++Begin != End) {
326
4.20k
    S += Separator;
327
4.20k
    S += (*Begin);
328
4.20k
  }
329
2.27k
  return S;
330
2.27k
}
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
50.9k
                             StringRef Separator, std::forward_iterator_tag) {
316
50.9k
  std::string S;
317
50.9k
  if (Begin == End)
318
20.7k
    return S;
319
30.2k
320
30.2k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
187k
  for (IteratorT I = Begin; I != End; 
++I156k
)
322
156k
    Len += (*Begin).size();
323
30.2k
  S.reserve(Len);
324
30.2k
  S += (*Begin);
325
156k
  while (++Begin != End) {
326
126k
    S += Separator;
327
126k
    S += (*Begin);
328
126k
  }
329
30.2k
  return S;
330
30.2k
}
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
1.56k
                             StringRef Separator, std::forward_iterator_tag) {
316
1.56k
  std::string S;
317
1.56k
  if (Begin == End)
318
0
    return S;
319
1.56k
320
1.56k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
4.72k
  for (IteratorT I = Begin; I != End; 
++I3.15k
)
322
3.15k
    Len += (*Begin).size();
323
1.56k
  S.reserve(Len);
324
1.56k
  S += (*Begin);
325
3.15k
  while (++Begin != End) {
326
1.59k
    S += Separator;
327
1.59k
    S += (*Begin);
328
1.59k
  }
329
1.56k
  return S;
330
1.56k
}
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.21k
                             StringRef Separator, std::forward_iterator_tag) {
316
3.21k
  std::string S;
317
3.21k
  if (Begin == End)
318
2.59k
    return S;
319
622
320
622
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
3.61k
  for (IteratorT I = Begin; I != End; 
++I2.99k
)
322
2.99k
    Len += (*Begin).size();
323
622
  S.reserve(Len);
324
622
  S += (*Begin);
325
2.99k
  while (++Begin != End) {
326
2.36k
    S += Separator;
327
2.36k
    S += (*Begin);
328
2.36k
  }
329
622
  return S;
330
622
}
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
92
                             StringRef Separator, std::forward_iterator_tag) {
316
92
  std::string S;
317
92
  if (Begin == End)
318
0
    return S;
319
92
320
92
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
321
675
  for (IteratorT I = Begin; I != End; 
++I583
)
322
583
    Len += (*Begin).size();
323
92
  S.reserve(Len);
324
92
  S += (*Begin);
325
583
  while (++Begin != End) {
326
491
    S += Separator;
327
491
    S += (*Begin);
328
491
  }
329
92
  return S;
330
92
}
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
855k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
855k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
855k
  return detail::join_impl(Begin, End, Separator, tag());
374
855k
}
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
793k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
793k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
793k
  return detail::join_impl(Begin, End, Separator, tag());
374
793k
}
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
3.02k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
3.02k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
3.02k
  return detail::join_impl(Begin, End, Separator, tag());
374
3.02k
}
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.43k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
3.43k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
3.43k
  return detail::join_impl(Begin, End, Separator, tag());
374
3.43k
}
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
50.9k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
50.9k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
50.9k
  return detail::join_impl(Begin, End, Separator, tag());
374
50.9k
}
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
1.56k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
1.56k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
1.56k
  return detail::join_impl(Begin, End, Separator, tag());
374
1.56k
}
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.21k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
3.21k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
3.21k
  return detail::join_impl(Begin, End, Separator, tag());
374
3.21k
}
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
92
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
372
92
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
373
92
  return detail::join_impl(Begin, End, Separator, tag());
374
92
}
375
376
/// Joins the strings in the range [R.begin(), R.end()), adding Separator
377
/// between the elements.
378
template <typename Range>
379
793k
inline std::string join(Range &&R, StringRef Separator) {
380
793k
  return join(R.begin(), R.end(), Separator);
381
793k
}
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
793k
inline std::string join(Range &&R, StringRef Separator) {
380
793k
  return join(R.begin(), R.end(), Separator);
381
793k
}
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
92
inline std::string join(Range &&R, StringRef Separator) {
380
92
  return join(R.begin(), R.end(), Separator);
381
92
}
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