Coverage Report

Created: 2019-02-20 07:29

/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
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file contains some functions that are useful when dealing with strings.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_ADT_STRINGEXTRAS_H
14
#define LLVM_ADT_STRINGEXTRAS_H
15
16
#include "llvm/ADT/ArrayRef.h"
17
#include "llvm/ADT/SmallString.h"
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/ADT/Twine.h"
20
#include <cassert>
21
#include <cstddef>
22
#include <cstdint>
23
#include <cstdlib>
24
#include <cstring>
25
#include <iterator>
26
#include <string>
27
#include <utility>
28
29
namespace llvm {
30
31
template<typename T> class SmallVectorImpl;
32
class raw_ostream;
33
34
/// hexdigit - Return the hexadecimal character for the
35
/// given number \p X (which should be less than 16).
36
48.3M
inline char hexdigit(unsigned X, bool LowerCase = false) {
37
48.3M
  const char HexChar = LowerCase ? 
'a'1.40M
:
'A'46.9M
;
38
48.3M
  return X < 10 ? 
'0' + X44.5M
:
HexChar + X - 103.86M
;
39
48.3M
}
40
41
/// Given an array of c-style strings terminated by a null pointer, construct
42
/// a vector of StringRefs representing the same strings without the terminating
43
/// null string.
44
17.8k
inline std::vector<StringRef> toStringRefArray(const char *const *Strings) {
45
17.8k
  std::vector<StringRef> Result;
46
1.26M
  while (*Strings)
47
1.24M
    Result.push_back(*Strings++);
48
17.8k
  return Result;
49
17.8k
}
50
51
/// Construct a string ref from a boolean.
52
4.41M
inline StringRef toStringRef(bool B) { return StringRef(B ? 
"true"4.15k
:
"false"4.40M
); }
53
54
/// Construct a string ref from an array ref of unsigned chars.
55
7.07k
inline StringRef toStringRef(ArrayRef<uint8_t> Input) {
56
7.07k
  return StringRef(reinterpret_cast<const char *>(Input.begin()), Input.size());
57
7.07k
}
58
59
/// Construct a string ref from an array ref of unsigned chars.
60
11.8k
inline ArrayRef<uint8_t> arrayRefFromStringRef(StringRef Input) {
61
11.8k
  return {Input.bytes_begin(), Input.bytes_end()};
62
11.8k
}
63
64
/// Interpret the given character \p C as a hexadecimal digit and return its
65
/// value.
66
///
67
/// If \p C is not a valid hex digit, -1U is returned.
68
15.0M
inline unsigned hexDigitValue(char C) {
69
15.0M
  if (C >= '0' && 
C <= '9'14.9M
)
return C-'0'14.5M
;
70
524k
  if (C >= 'a' && 
C <= 'f'299k
)
return C-'a'+10U298k
;
71
226k
  if (C >= 'A' && 
C <= 'F'175k
)
return C-'A'+10U173k
;
72
53.1k
  return -1U;
73
53.1k
}
74
75
/// Checks if character \p C is one of the 10 decimal digits.
76
13.4M
inline bool isDigit(char C) { return C >= '0' && 
C <= '9'9.74M
; }
77
78
/// Checks if character \p C is a hexadecimal numeric character.
79
423k
inline bool isHexDigit(char C) { return hexDigitValue(C) != -1U; }
80
81
/// Checks if character \p C is a valid letter as classified by "C" locale.
82
42.1M
inline bool isAlpha(char C) {
83
42.1M
  return ('a' <= C && 
C <= 'z'33.7M
) ||
(8.42M
'A' <= C8.42M
&&
C <= 'Z'2.56M
);
84
42.1M
}
85
86
/// Checks whether character \p C is either a decimal digit or an uppercase or
87
/// lowercase letter as classified by "C" locale.
88
41.8M
inline bool isAlnum(char C) { return isAlpha(C) || 
isDigit(C)7.09M
; }
89
90
/// Checks whether character \p C is valid ASCII (high bit is zero).
91
10.4M
inline bool isASCII(char C) { return static_cast<unsigned char>(C) <= 127; }
92
93
/// Checks whether all characters in S are ASCII.
94
943k
inline bool isASCII(llvm::StringRef S) {
95
943k
  for (char C : S)
96
10.4M
    if (LLVM_UNLIKELY(!isASCII(C)))
97
10.4M
      
return false21
;
98
943k
  
return true943k
;
99
943k
}
100
101
/// Checks whether character \p C is printable.
102
///
103
/// Locale-independent version of the C standard library isprint whose results
104
/// may differ on different platforms.
105
37.6M
inline bool isPrint(char C) {
106
37.6M
  unsigned char UC = static_cast<unsigned char>(C);
107
37.6M
  return (0x20 <= UC) && 
(UC <= 0x7E)27.4M
;
108
37.6M
}
109
110
/// Returns the corresponding lowercase character if \p x is uppercase.
111
347M
inline char toLower(char x) {
112
347M
  if (x >= 'A' && 
x <= 'Z'249M
)
113
161M
    return x - 'A' + 'a';
114
185M
  return x;
115
185M
}
116
117
/// Returns the corresponding uppercase character if \p x is lowercase.
118
1.60M
inline char toUpper(char x) {
119
1.60M
  if (x >= 'a' && 
x <= 'z'1.11M
)
120
1.10M
    return x - 'a' + 'A';
121
500k
  return x;
122
500k
}
123
124
22.9k
inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
125
22.9k
  char Buffer[17];
126
22.9k
  char *BufPtr = std::end(Buffer);
127
22.9k
128
22.9k
  if (X == 0) 
*--BufPtr = '0'3.14k
;
129
22.9k
130
69.3k
  while (X) {
131
46.4k
    unsigned char Mod = static_cast<unsigned char>(X) & 15;
132
46.4k
    *--BufPtr = hexdigit(Mod, LowerCase);
133
46.4k
    X >>= 4;
134
46.4k
  }
135
22.9k
136
22.9k
  return std::string(BufPtr, std::end(Buffer));
137
22.9k
}
138
139
/// Convert buffer \p Input to its hexadecimal representation.
140
/// The returned string is double the size of \p Input.
141
512
inline std::string toHex(StringRef Input, bool LowerCase = false) {
142
512
  static const char *const LUT = "0123456789ABCDEF";
143
512
  const uint8_t Offset = LowerCase ? 
3216
:
0496
;
144
512
  size_t Length = Input.size();
145
512
146
512
  std::string Output;
147
512
  Output.reserve(2 * Length);
148
8.80k
  for (size_t i = 0; i < Length; 
++i8.28k
) {
149
8.28k
    const unsigned char c = Input[i];
150
8.28k
    Output.push_back(LUT[c >> 4] | Offset);
151
8.28k
    Output.push_back(LUT[c & 15] | Offset);
152
8.28k
  }
153
512
  return Output;
154
512
}
155
156
386
inline std::string toHex(ArrayRef<uint8_t> Input, bool LowerCase = false) {
157
386
  return toHex(toStringRef(Input), LowerCase);
158
386
}
159
160
5.56k
inline uint8_t hexFromNibbles(char MSB, char LSB) {
161
5.56k
  unsigned U1 = hexDigitValue(MSB);
162
5.56k
  unsigned U2 = hexDigitValue(LSB);
163
5.56k
  assert(U1 != -1U && U2 != -1U);
164
5.56k
165
5.56k
  return static_cast<uint8_t>((U1 << 4) | U2);
166
5.56k
}
167
168
/// Convert hexadecimal string \p Input to its binary representation.
169
/// The return string is half the size of \p Input.
170
369
inline std::string fromHex(StringRef Input) {
171
369
  if (Input.empty())
172
20
    return std::string();
173
349
174
349
  std::string Output;
175
349
  Output.reserve((Input.size() + 1) / 2);
176
349
  if (Input.size() % 2 == 1) {
177
1
    Output.push_back(hexFromNibbles('0', Input.front()));
178
1
    Input = Input.drop_front();
179
1
  }
180
349
181
349
  assert(Input.size() % 2 == 0);
182
5.91k
  while (!Input.empty()) {
183
5.56k
    uint8_t Hex = hexFromNibbles(Input[0], Input[1]);
184
5.56k
    Output.push_back(Hex);
185
5.56k
    Input = Input.drop_front(2);
186
5.56k
  }
187
349
  return Output;
188
349
}
189
190
/// Convert the string \p S to an integer of the specified type using
191
/// the radix \p Base.  If \p Base is 0, auto-detects the radix.
192
/// Returns true if the number was successfully converted, false otherwise.
193
2.91k
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
194
2.91k
  return !S.getAsInteger(Base, Num);
195
2.91k
}
bool llvm::to_integer<unsigned int>(llvm::StringRef, unsigned int&, unsigned int)
Line
Count
Source
193
686
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
194
686
  return !S.getAsInteger(Base, Num);
195
686
}
bool llvm::to_integer<unsigned long long>(llvm::StringRef, unsigned long long&, unsigned int)
Line
Count
Source
193
2.12k
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
194
2.12k
  return !S.getAsInteger(Base, Num);
195
2.12k
}
bool llvm::to_integer<int>(llvm::StringRef, int&, unsigned int)
Line
Count
Source
193
88
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
194
88
  return !S.getAsInteger(Base, Num);
195
88
}
bool llvm::to_integer<unsigned char>(llvm::StringRef, unsigned char&, unsigned int)
Line
Count
Source
193
12
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
194
12
  return !S.getAsInteger(Base, Num);
195
12
}
196
197
namespace detail {
198
template <typename N>
199
52
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
200
52
  SmallString<32> Storage;
201
52
  StringRef S = T.toNullTerminatedStringRef(Storage);
202
52
  char *End;
203
52
  N Temp = StrTo(S.data(), &End);
204
52
  if (*End != '\0')
205
4
    return false;
206
48
  Num = Temp;
207
48
  return true;
208
48
}
bool llvm::detail::to_float<double>(llvm::Twine const&, double&, double (*)(char const*, char**))
Line
Count
Source
199
41
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
200
41
  SmallString<32> Storage;
201
41
  StringRef S = T.toNullTerminatedStringRef(Storage);
202
41
  char *End;
203
41
  N Temp = StrTo(S.data(), &End);
204
41
  if (*End != '\0')
205
1
    return false;
206
40
  Num = Temp;
207
40
  return true;
208
40
}
bool llvm::detail::to_float<float>(llvm::Twine const&, float&, float (*)(char const*, char**))
Line
Count
Source
199
11
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
200
11
  SmallString<32> Storage;
201
11
  StringRef S = T.toNullTerminatedStringRef(Storage);
202
11
  char *End;
203
11
  N Temp = StrTo(S.data(), &End);
204
11
  if (*End != '\0')
205
3
    return false;
206
8
  Num = Temp;
207
8
  return true;
208
8
}
209
}
210
211
11
inline bool to_float(const Twine &T, float &Num) {
212
11
  return detail::to_float(T, Num, strtof);
213
11
}
214
215
41
inline bool to_float(const Twine &T, double &Num) {
216
41
  return detail::to_float(T, Num, strtod);
217
41
}
218
219
inline bool to_float(const Twine &T, long double &Num) {
220
  return detail::to_float(T, Num, strtold);
221
}
222
223
13.2M
inline std::string utostr(uint64_t X, bool isNeg = false) {
224
13.2M
  char Buffer[21];
225
13.2M
  char *BufPtr = std::end(Buffer);
226
13.2M
227
13.2M
  if (X == 0) 
*--BufPtr = '0'2.17M
; // Handle special case...
228
13.2M
229
39.9M
  while (X) {
230
26.7M
    *--BufPtr = '0' + char(X % 10);
231
26.7M
    X /= 10;
232
26.7M
  }
233
13.2M
234
13.2M
  if (isNeg) 
*--BufPtr = '-'96.3k
; // Add negative sign...
235
13.2M
  return std::string(BufPtr, std::end(Buffer));
236
13.2M
}
237
238
5.79M
inline std::string itostr(int64_t X) {
239
5.79M
  if (X < 0)
240
96.3k
    return utostr(static_cast<uint64_t>(-X), true);
241
5.70M
  else
242
5.70M
    return utostr(static_cast<uint64_t>(X));
243
5.79M
}
244
245
/// StrInStrNoCase - Portable version of strcasestr.  Locates the first
246
/// occurrence of string 's1' in string 's2', ignoring case.  Returns
247
/// the offset of s2 in s1 or npos if s2 cannot be found.
248
StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
249
250
/// getToken - This function extracts one token from source, ignoring any
251
/// leading characters that appear in the Delimiters string, and ending the
252
/// token at any of the characters that appear in the Delimiters string.  If
253
/// there are no tokens in the source string, an empty string is returned.
254
/// The function returns a pair containing the extracted token and the
255
/// remaining tail string.
256
std::pair<StringRef, StringRef> getToken(StringRef Source,
257
                                         StringRef Delimiters = " \t\n\v\f\r");
258
259
/// SplitString - Split up the specified string according to the specified
260
/// delimiters, appending the result fragments to the output list.
261
void SplitString(StringRef Source,
262
                 SmallVectorImpl<StringRef> &OutFragments,
263
                 StringRef Delimiters = " \t\n\v\f\r");
264
265
/// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
266
5.83k
inline StringRef getOrdinalSuffix(unsigned Val) {
267
5.83k
  // It is critically important that we do this perfectly for
268
5.83k
  // user-written sequences with over 100 elements.
269
5.83k
  switch (Val % 100) {
270
5.83k
  case 11:
271
0
  case 12:
272
0
  case 13:
273
0
    return "th";
274
5.83k
  default:
275
5.83k
    switch (Val % 10) {
276
5.83k
      
case 1: return "st"5.45k
;
277
5.83k
      
case 2: return "nd"258
;
278
5.83k
      
case 3: return "rd"102
;
279
5.83k
      
default: return "th"15
;
280
5.83k
    }
281
5.83k
  }
282
5.83k
}
283
284
/// Print each character of the specified string, escaping it if it is not
285
/// printable or if it is an escape char.
286
void printEscapedString(StringRef Name, raw_ostream &Out);
287
288
/// Print each character of the specified string, escaping HTML special
289
/// characters.
290
void printHTMLEscaped(StringRef String, raw_ostream &Out);
291
292
/// printLowerCase - Print each character as lowercase if it is uppercase.
293
void printLowerCase(StringRef String, raw_ostream &Out);
294
295
namespace detail {
296
297
template <typename IteratorT>
298
inline std::string join_impl(IteratorT Begin, IteratorT End,
299
                             StringRef Separator, std::input_iterator_tag) {
300
  std::string S;
301
  if (Begin == End)
302
    return S;
303
304
  S += (*Begin);
305
  while (++Begin != End) {
306
    S += Separator;
307
    S += (*Begin);
308
  }
309
  return S;
310
}
311
312
template <typename IteratorT>
313
inline std::string join_impl(IteratorT Begin, IteratorT End,
314
869k
                             StringRef Separator, std::forward_iterator_tag) {
315
869k
  std::string S;
316
869k
  if (Begin == End)
317
25.7k
    return S;
318
843k
319
843k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
320
7.71M
  for (IteratorT I = Begin; I != End; 
++I6.87M
)
321
6.87M
    Len += (*Begin).size();
322
843k
  S.reserve(Len);
323
843k
  S += (*Begin);
324
6.87M
  while (++Begin != End) {
325
6.03M
    S += Separator;
326
6.03M
    S += (*Begin);
327
6.03M
  }
328
843k
  return S;
329
843k
}
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
314
805k
                             StringRef Separator, std::forward_iterator_tag) {
315
805k
  std::string S;
316
805k
  if (Begin == End)
317
5
    return S;
318
805k
319
805k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
320
7.50M
  for (IteratorT I = Begin; I != End; 
++I6.70M
)
321
6.70M
    Len += (*Begin).size();
322
805k
  S.reserve(Len);
323
805k
  S += (*Begin);
324
6.70M
  while (++Begin != End) {
325
5.89M
    S += Separator;
326
5.89M
    S += (*Begin);
327
5.89M
  }
328
805k
  return S;
329
805k
}
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
314
3.13k
                             StringRef Separator, std::forward_iterator_tag) {
315
3.13k
  std::string S;
316
3.13k
  if (Begin == End)
317
24
    return S;
318
3.11k
319
3.11k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
320
6.42k
  for (IteratorT I = Begin; I != End; 
++I3.31k
)
321
3.31k
    Len += (*Begin).size();
322
3.11k
  S.reserve(Len);
323
3.11k
  S += (*Begin);
324
3.31k
  while (++Begin != End) {
325
199
    S += Separator;
326
199
    S += (*Begin);
327
199
  }
328
3.11k
  return S;
329
3.11k
}
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
314
3.38k
                             StringRef Separator, std::forward_iterator_tag) {
315
3.38k
  std::string S;
316
3.38k
  if (Begin == End)
317
1.16k
    return S;
318
2.22k
319
2.22k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
320
8.61k
  for (IteratorT I = Begin; I != End; 
++I6.39k
)
321
6.39k
    Len += (*Begin).size();
322
2.22k
  S.reserve(Len);
323
2.22k
  S += (*Begin);
324
6.39k
  while (++Begin != End) {
325
4.17k
    S += Separator;
326
4.17k
    S += (*Begin);
327
4.17k
  }
328
2.22k
  return S;
329
2.22k
}
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
314
52.7k
                             StringRef Separator, std::forward_iterator_tag) {
315
52.7k
  std::string S;
316
52.7k
  if (Begin == End)
317
21.8k
    return S;
318
30.9k
319
30.9k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
320
187k
  for (IteratorT I = Begin; I != End; 
++I156k
)
321
156k
    Len += (*Begin).size();
322
30.9k
  S.reserve(Len);
323
30.9k
  S += (*Begin);
324
156k
  while (++Begin != End) {
325
125k
    S += Separator;
326
125k
    S += (*Begin);
327
125k
  }
328
30.9k
  return S;
329
30.9k
}
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
314
1.58k
                             StringRef Separator, std::forward_iterator_tag) {
315
1.58k
  std::string S;
316
1.58k
  if (Begin == End)
317
0
    return S;
318
1.58k
319
1.58k
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
320
4.76k
  for (IteratorT I = Begin; I != End; 
++I3.18k
)
321
3.18k
    Len += (*Begin).size();
322
1.58k
  S.reserve(Len);
323
1.58k
  S += (*Begin);
324
3.18k
  while (++Begin != End) {
325
1.59k
    S += Separator;
326
1.59k
    S += (*Begin);
327
1.59k
  }
328
1.58k
  return S;
329
1.58k
}
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
314
3.33k
                             StringRef Separator, std::forward_iterator_tag) {
315
3.33k
  std::string S;
316
3.33k
  if (Begin == End)
317
2.71k
    return S;
318
629
319
629
  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
320
3.65k
  for (IteratorT I = Begin; I != End; 
++I3.02k
)
321
3.02k
    Len += (*Begin).size();
322
629
  S.reserve(Len);
323
629
  S += (*Begin);
324
3.02k
  while (++Begin != End) {
325
2.39k
    S += Separator;
326
2.39k
    S += (*Begin);
327
2.39k
  }
328
629
  return S;
329
629
}
330
331
template <typename Sep>
332
inline void join_items_impl(std::string &Result, Sep Separator) {}
333
334
template <typename Sep, typename Arg>
335
inline void join_items_impl(std::string &Result, Sep Separator,
336
                            const Arg &Item) {
337
  Result += Item;
338
}
339
340
template <typename Sep, typename Arg1, typename... Args>
341
inline void join_items_impl(std::string &Result, Sep Separator, const Arg1 &A1,
342
                            Args &&... Items) {
343
  Result += A1;
344
  Result += Separator;
345
  join_items_impl(Result, Separator, std::forward<Args>(Items)...);
346
}
347
348
inline size_t join_one_item_size(char C) { return 1; }
349
inline size_t join_one_item_size(const char *S) { return S ? ::strlen(S) : 0; }
350
351
template <typename T> inline size_t join_one_item_size(const T &Str) {
352
  return Str.size();
353
}
354
355
inline size_t join_items_size() { return 0; }
356
357
template <typename A1> inline size_t join_items_size(const A1 &A) {
358
  return join_one_item_size(A);
359
}
360
template <typename A1, typename... Args>
361
inline size_t join_items_size(const A1 &A, Args &&... Items) {
362
  return join_one_item_size(A) + join_items_size(std::forward<Args>(Items)...);
363
}
364
365
} // end namespace detail
366
367
/// Joins the strings in the range [Begin, End), adding Separator between
368
/// the elements.
369
template <typename IteratorT>
370
869k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
371
869k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
372
869k
  return detail::join_impl(Begin, End, Separator, tag());
373
869k
}
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
370
805k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
371
805k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
372
805k
  return detail::join_impl(Begin, End, Separator, tag());
373
805k
}
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
370
3.13k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
371
3.13k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
372
3.13k
  return detail::join_impl(Begin, End, Separator, tag());
373
3.13k
}
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
370
3.38k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
371
3.38k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
372
3.38k
  return detail::join_impl(Begin, End, Separator, tag());
373
3.38k
}
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
370
52.7k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
371
52.7k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
372
52.7k
  return detail::join_impl(Begin, End, Separator, tag());
373
52.7k
}
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
370
1.58k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
371
1.58k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
372
1.58k
  return detail::join_impl(Begin, End, Separator, tag());
373
1.58k
}
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
370
3.33k
inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
371
3.33k
  using tag = typename std::iterator_traits<IteratorT>::iterator_category;
372
3.33k
  return detail::join_impl(Begin, End, Separator, tag());
373
3.33k
}
374
375
/// Joins the strings in the range [R.begin(), R.end()), adding Separator
376
/// between the elements.
377
template <typename Range>
378
805k
inline std::string join(Range &&R, StringRef Separator) {
379
805k
  return join(R.begin(), R.end(), Separator);
380
805k
}
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
378
56
inline std::string join(Range &&R, StringRef Separator) {
379
56
  return join(R.begin(), R.end(), Separator);
380
56
}
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
378
1
inline std::string join(Range &&R, StringRef Separator) {
379
1
  return join(R.begin(), R.end(), Separator);
380
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
378
805k
inline std::string join(Range &&R, StringRef Separator) {
379
805k
  return join(R.begin(), R.end(), Separator);
380
805k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > llvm::join<llvm::SmallVector<llvm::StringRef, 4u>&>(llvm::SmallVector<llvm::StringRef, 4u>&&&, llvm::StringRef)
Line
Count
Source
378
1
inline std::string join(Range &&R, StringRef Separator) {
379
1
  return join(R.begin(), R.end(), Separator);
380
1
}
381
382
/// Joins the strings in the parameter pack \p Items, adding \p Separator
383
/// between the elements.  All arguments must be implicitly convertible to
384
/// std::string, or there should be an overload of std::string::operator+=()
385
/// that accepts the argument explicitly.
386
template <typename Sep, typename... Args>
387
inline std::string join_items(Sep Separator, Args &&... Items) {
388
  std::string Result;
389
  if (sizeof...(Items) == 0)
390
    return Result;
391
392
  size_t NS = detail::join_one_item_size(Separator);
393
  size_t NI = detail::join_items_size(std::forward<Args>(Items)...);
394
  Result.reserve(NI + (sizeof...(Items) - 1) * NS + 1);
395
  detail::join_items_impl(Result, Separator, std::forward<Args>(Items)...);
396
  return Result;
397
}
398
399
} // end namespace llvm
400
401
#endif // LLVM_ADT_STRINGEXTRAS_H