14#ifndef LLVM_ADT_STRINGEXTRAS_H 15#define LLVM_ADT_STRINGEXTRAS_H 37inlinechar hexdigit(
unsignedX,
bool LowerCase =
false) {
39staticconstcharLUT[] =
"0123456789ABCDEF";
47inline std::vector<StringRef> toStringRefArray(
constchar *
const *Strings) {
48 std::vector<StringRef>
Result;
50Result.push_back(*Strings++);
55inline StringRef
toStringRef(
boolB) {
return StringRef(
B ?
"true" :
"false"); }
58inline StringRef
toStringRef(ArrayRef<uint8_t> Input) {
59return StringRef(
reinterpret_cast<const char *
>(Input.begin()), Input.size());
62return StringRef(Input.begin(), Input.size());
66template <
class CharT = u
int8_t>
67inline ArrayRef<CharT> arrayRefFromStringRef(StringRef Input) {
68static_assert(std::is_same<CharT, char>::value ||
69 std::is_same<CharT, unsigned char>::value ||
70 std::is_same<CharT, signed char>::value,
72return ArrayRef<CharT>(
reinterpret_cast<const CharT *
>(Input.data()),
80inlineunsigned hexDigitValue(
charC) {
82staticconst int16_t
LUT[256] = {
83 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
84 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
85 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
86 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
87 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
88 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
89 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
90 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
91 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
92 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
93 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
94 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
95 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
96 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
97 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
98 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
101returnLUT[
static_cast<unsignedchar>(
C)];
105inlineboolisDigit(
charC) {
returnC >=
'0' &&
C <=
'9'; }
108inlineboolisHexDigit(
charC) {
return hexDigitValue(
C) != ~0
U; }
111inlineboolisLower(
charC) {
return'a' <=
C &&
C <=
'z'; }
114inlineboolisUpper(
charC) {
return'A' <=
C &&
C <=
'Z'; }
121inlinebool isAlnum(
charC) {
return isAlpha(
C) ||
isDigit(
C); }
124inlinebool isASCII(
charC) {
returnstatic_cast<unsignedchar>(
C) <= 127; }
139unsignedchar UC =
static_cast<unsignedchar>(
C);
140return (0x20 <= UC) && (UC <= 0x7E);
148inlinebool isPunct(
charC) {
150 R
"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)"; 151return Punctuations.contains(
C);
157inlinebool isSpace(
charC) {
158returnC ==
' ' ||
C ==
'\f' ||
C ==
'\n' ||
C ==
'\r' ||
C ==
'\t' ||
163inlinechar toLower(
char x) {
170inlinechar toUpper(
char x) {
176inline std::string utohexstr(
uint64_tX,
bool LowerCase =
false,
179char *BufPtr = std::end(Buffer);
181if (
X == 0) *--BufPtr =
'0';
183for (
unsigned i = 0; Width ? (i < Width) :
X; ++i) {
184unsignedcharMod =
static_cast<unsignedchar>(
X) & 15;
185 *--BufPtr = hexdigit(
Mod, LowerCase);
189return std::string(BufPtr, std::end(Buffer));
194inlinevoid toHex(ArrayRef<uint8_t> Input,
bool LowerCase,
195 SmallVectorImpl<char> &Output) {
196constsize_tLength = Input.size();
197 Output.resize_for_overwrite(
Length * 2);
199for (
size_t i = 0; i <
Length; i++) {
201 Output[i * 2 ] = hexdigit(c >> 4, LowerCase);
202 Output[i * 2 + 1] = hexdigit(c & 15, LowerCase);
206inline std::string toHex(ArrayRef<uint8_t> Input,
bool LowerCase =
false) {
207 SmallString<16> Output;
208 toHex(Input, LowerCase, Output);
209return std::string(Output);
212inline std::string toHex(StringRef Input,
bool LowerCase =
false) {
213return toHex(arrayRefFromStringRef(Input), LowerCase);
220inlinebool tryGetHexFromNibbles(
char MSB,
char LSB,
uint8_t &Hex) {
221unsigned U1 = hexDigitValue(MSB);
222unsigned U2 = hexDigitValue(LSB);
223if (U1 == ~0U || U2 == ~0U)
226 Hex =
static_cast<uint8_t>((U1 << 4) | U2);
232inlineuint8_t hexFromNibbles(
char MSB,
char LSB) {
234bool GotHex = tryGetHexFromNibbles(MSB, LSB, Hex);
236assert(GotHex &&
"MSB and/or LSB do not correspond to hex digits");
244inlinebool tryGetFromHex(StringRef Input, std::string &Output) {
250 Output.resize((Input.size() + 1) / 2);
251char *OutputPtr =
const_cast<char *
>(Output.data());
252if (Input.size() % 2 == 1) {
254if (!tryGetHexFromNibbles(
'0', Input.front(), Hex))
257 Input = Input.drop_front();
263size_t InputSize = Input.size();
264assert(InputSize % 2 == 0);
265constchar *InputPtr = Input.data();
266for (
size_t OutputIndex = 0; OutputIndex < InputSize / 2; ++OutputIndex) {
268if (!tryGetHexFromNibbles(InputPtr[OutputIndex * 2 + 0],
269 InputPtr[OutputIndex * 2 + 1],
272 OutputPtr[OutputIndex] = Hex;
279inline std::string fromHex(StringRef Input) {
281bool GotHex = tryGetFromHex(Input, Hex);
283assert(GotHex &&
"Input contains non hex digits");
290template <
typename N>
bool to_integer(StringRef S,
N &Num,
unsignedBase = 0) {
291return !S.getAsInteger(
Base, Num);
296inlinebool to_float(
const Twine &
T,
N &Num,
N (*StrTo)(
constchar *,
char **)) {
297 SmallString<32> Storage;
298 StringRef S =
T.toNullTerminatedStringRef(Storage);
300N Temp = StrTo(S.data(), &
End);
308inlinebool to_float(
const Twine &
T,
float &Num) {
309return detail::to_float(
T, Num, strtof);
312inlinebool to_float(
const Twine &
T,
double &Num) {
313return detail::to_float(
T, Num, strtod);
316inlinebool to_float(
const Twine &
T,
longdouble &Num) {
317return detail::to_float(
T, Num, strtold);
322char *BufPtr = std::end(Buffer);
324if (
X == 0) *--BufPtr =
'0';
327 *--BufPtr =
'0' +
char(
X % 10);
331if (
isNeg) *--BufPtr =
'-';
332return std::string(BufPtr, std::end(Buffer));
335inline std::string itostr(int64_t
X) {
343bool formatAsCLiteral =
false,
344bool UpperCase =
true,
345bool InsertSeparators =
false) {
347I.toString(S, Radix,
Signed, formatAsCLiteral, UpperCase, InsertSeparators);
348return std::string(S);
351inline std::string
toString(
const APSInt &
I,
unsigned Radix) {
366std::pair<StringRef, StringRef> getToken(StringRef Source,
367 StringRef Delimiters =
" \t\n\v\f\r");
371void SplitString(StringRef Source,
372 SmallVectorImpl<StringRef> &OutFragments,
373 StringRef Delimiters =
" \t\n\v\f\r");
376inline StringRef getOrdinalSuffix(
unsigned Val) {
396void printEscapedString(StringRef
Name, raw_ostream &Out);
400void printHTMLEscaped(StringRef
String, raw_ostream &Out);
403void printLowerCase(StringRef
String, raw_ostream &Out);
408std::string convertToSnakeFromCamelCase(StringRef input);
414std::string convertToCamelFromSnakeCase(StringRef input,
415bool capitalizeFirst =
false);
419template <
typename IteratorT>
420inline std::string join_impl(IteratorT Begin, IteratorT
End,
421 StringRef Separator, std::input_iterator_tag) {
427while (++Begin !=
End) {
434template <
typename IteratorT>
435inline std::string join_impl(IteratorT Begin, IteratorT
End,
436 StringRef Separator, std::forward_iterator_tag) {
441size_tLen = (std::distance(Begin,
End) - 1) * Separator.size();
442for (IteratorT
I = Begin;
I !=
End; ++
I)
443 Len += StringRef(*I).size();
445size_t PrevCapacity = S.capacity();
448while (++Begin !=
End) {
452assert(PrevCapacity == S.capacity() &&
"String grew during building");
456template <
typename Sep>
457inlinevoid join_items_impl(std::string &Result, Sep Separator) {}
459template <
typename Sep,
typename Arg>
460inlinevoid join_items_impl(std::string &Result, Sep Separator,
465template <
typename Sep,
typename Arg1,
typename...
Args>
466inlinevoid join_items_impl(std::string &Result, Sep Separator,
const Arg1 &A1,
470 join_items_impl(Result, Separator, std::forward<Args>(Items)...);
473inlinesize_t join_one_item_size(
char) {
return 1; }
474inlinesize_t join_one_item_size(
constchar *S) {
return S ? ::strlen(S) : 0; }
476template <
typename T>
inlinesize_t join_one_item_size(
constT &Str) {
480template <
typename...
Args>
inlinesize_t join_items_size(Args &&...Items) {
481return (0 + ... + join_one_item_size(std::forward<Args>(Items)));
488template <
typename IteratorT>
489inline std::string join(IteratorT Begin, IteratorT
End, StringRef Separator) {
490using tag =
typename std::iterator_traits<IteratorT>::iterator_category;
491return detail::join_impl(Begin,
End, Separator, tag());
496template <
typename Range>
497inline std::string join(
Range &&R, StringRef Separator) {
498return join(
R.begin(),
R.end(), Separator);
505template <
typename Sep,
typename...
Args>
506inline std::string join_items(Sep Separator, Args &&... Items) {
508if (
sizeof...(Items) == 0)
511size_t NS = detail::join_one_item_size(Separator);
512size_t NI = detail::join_items_size(std::forward<Args>(Items)...);
513Result.reserve(NI + (
sizeof...(Items) - 1) * NS + 1);
514 detail::join_items_impl(Result, Separator, std::forward<Args>(Items)...);
532 ListSeparator(StringRef Separator =
", ") : Separator(Separator) {}
533operator StringRef() {
543class SplittingIterator
544 :
public iterator_facade_base<SplittingIterator, std::forward_iterator_tag,
546char SeparatorStorage;
552 SplittingIterator(StringRef Str, StringRef Separator)
553 : Next(Str), Separator(Separator) {
557 SplittingIterator(StringRef Str,
char Separator)
558 : SeparatorStorage(Separator), Next(Str),
559 Separator(&SeparatorStorage, 1) {
563 SplittingIterator(
const SplittingIterator &R)
564 : SeparatorStorage(
R.SeparatorStorage), Current(
R.Current), Next(
R.Next),
565 Separator(
R.Separator) {
566if (
R.Separator.data() == &
R.SeparatorStorage)
567 Separator = StringRef(&SeparatorStorage, 1);
570 SplittingIterator &operator=(
const SplittingIterator &R) {
574 SeparatorStorage =
R.SeparatorStorage;
577 Separator =
R.Separator;
578if (
R.Separator.data() == &
R.SeparatorStorage)
579 Separator = StringRef(&SeparatorStorage, 1);
583booloperator==(
const SplittingIterator &R)
const {
584assert(Separator ==
R.Separator);
585return Current.data() ==
R.Current.data();
588const StringRef &
operator*()
const {
return Current; }
590 StringRef &
operator*() {
return Current; }
592 SplittingIterator &operator++() {
593 std::tie(Current, Next) = Next.split(Separator);
609inline iterator_range<SplittingIterator> split(StringRef Str, StringRef Separator) {
610return {SplittingIterator(Str, Separator),
611 SplittingIterator(StringRef(), Separator)};
614inline iterator_range<SplittingIterator> split(StringRef Str,
char Separator) {
615return {SplittingIterator(Str, Separator),
616 SplittingIterator(StringRef(), Separator)};
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_UNLIKELY(EXPR)
static bool isNeg(Value *V)
Returns true if the operation is a negation of V, and it works for both integers and floats.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static bool isDigit(const char C)
static bool isHexDigit(const char C)
static bool isLower(const char C)
static bool isUpper(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
StringRef - Represent a constant reference to a string, i.e.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
APInt operator*(APInt a, uint64_t RHS)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
@ Mod
The access may modify the value stored in memory.
const char * toString(DWARFSectionKind Kind)