LLVM: include/llvm/ADT/StringRef.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9#ifndef LLVM_ADT_STRINGREF_H
10#define LLVM_ADT_STRINGREF_H
11
16#include
17#include
18#include
19#include
20#include
21#include
22#include
23#include <string_view>
24#include <type_traits>
25#include
26
27namespace llvm {
28
29 class APInt;
30 class hash_code;
31 template class SmallVectorImpl;
32 class StringRef;
33
34
36 unsigned long long &Result);
37
38 bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
39
41 unsigned long long &Result);
43
44
45
46
47
48
49
50
52 public:
53 static constexpr size_t npos = ~size_t(0);
54
61
62 private:
63
64 const char *Data = nullptr;
65
66
68
69
70
71 static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
72 if (Length == 0) { return 0; }
73 return ::memcmp(Lhs,Rhs,Length);
74 }
75
76 public:
77
78
79
80
82
83
84
86
87
89 : Data(Str), Length(Str ?
90
91#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 8
92 __builtin_strlen(Str)
94 std::char_traits<char>::length(Str)
95#endif
96 : 0) {
97 }
98
99
101 size_t length)
102 : Data(data), Length(length) {}
103
104
105 StringRef(const std::string &Str)
106 : Data(Str.data()), Length(Str.length()) {}
107
108
109 constexpr StringRef(std::string_view Str)
110 : Data(Str.data()), Length(Str.size()) {}
111
112
113
114
115
117
119
121 return std::make_reverse_iterator(end());
122 }
123
125 return std::make_reverse_iterator(begin());
126 }
127
129 return reinterpret_cast<const unsigned char *>(begin());
130 }
132 return reinterpret_cast<const unsigned char *>(end());
133 }
135 return make_range(bytes_begin(), bytes_end());
136 }
137
138
139
140
141
142
143
144 [[nodiscard]] constexpr const char *data() const { return Data; }
145
146
147 [[nodiscard]] constexpr bool empty() const { return size() == 0; }
148
149
150 [[nodiscard]] constexpr size_t size() const { return Length; }
151
152
153 [[nodiscard]] char front() const {
155 return data()[0];
156 }
157
158
159 [[nodiscard]] char back() const {
161 return data()[size() - 1];
162 }
163
164
165 template
167
168 if (empty())
170 char *S = A.template Allocate(size());
171 std::copy(begin(), end(), S);
173 }
174
175
177 return size() == RHS.size() && compare_insensitive(RHS) == 0;
178 }
179
180
181
182
184
185 if (int Res =
186 compareMemory(data(), RHS.data(), std::min(size(), RHS.size())))
187 return Res < 0 ? -1 : 1;
188
189
191 return 0;
192 return size() < RHS.size() ? -1 : 1;
193 }
194
195
196 [[nodiscard]] int compare_insensitive(StringRef RHS) const;
197
198
199
200 [[nodiscard]] int compare_numeric(StringRef RHS) const;
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220 [[nodiscard]] unsigned edit_distance(StringRef Other,
221 bool AllowReplacements = true,
222 unsigned MaxEditDistance = 0) const;
223
224 [[nodiscard]] unsigned
225 edit_distance_insensitive(StringRef Other, bool AllowReplacements = true,
226 unsigned MaxEditDistance = 0) const;
227
228
229 [[nodiscard]] std::string str() const {
230 if (!data())
231 return std::string();
232 return std::string(data(), size());
233 }
234
235
236
237
238
241 return data()[Index];
242 }
243
244
245
246
247
248 template
249 std::enable_if_t<std::is_same<T, std::string>::value, StringRef> &
251
252
253
254
255
256 constexpr operator std::string_view() const {
257 return std::string_view(data(), size());
258 }
259
260
261
262
263
264
266 return size() >= Prefix.size() &&
267 compareMemory(data(), Prefix.data(), Prefix.size()) == 0;
268 }
270 return !empty() && front() == Prefix;
271 }
272
273
274 [[nodiscard]] bool starts_with_insensitive(StringRef Prefix) const;
275
276
278 return size() >= Suffix.size() &&
279 compareMemory(end() - Suffix.size(), Suffix.data(),
280 Suffix.size()) == 0;
281 }
282 [[nodiscard]] bool ends_with(char Suffix) const {
283 return !empty() && back() == Suffix;
284 }
285
286
287 [[nodiscard]] bool ends_with_insensitive(StringRef Suffix) const;
288
289
290
291
292
293
294
295
296
297 [[nodiscard]] size_t find(char C, size_t From = 0) const {
298 return std::string_view(*this).find(C, From);
299 }
300
301
302
303
304
305 [[nodiscard]] size_t find_insensitive(char C, size_t From = 0) const;
306
307
308
309
310
312 size_t From = 0) const {
314 while (!S.empty()) {
318 }
320 }
321
322
323
324
325
327 size_t From = 0) const {
328 return find_if([F](char c) { return (c); }, From);
329 }
330
331
332
333
334
336
337
338
339
340
341 [[nodiscard]] size_t find_insensitive(StringRef Str, size_t From = 0) const;
342
343
344
345
346
348 size_t I = std::min(From, size());
349 while (I) {
350 --I;
352 return I;
353 }
355 }
356
357
358
359
360
361 [[nodiscard]] size_t rfind_insensitive(char C, size_t From = npos) const;
362
363
364
365
366
367 [[nodiscard]] size_t rfind(StringRef Str) const;
368
369
370
371
372
373 [[nodiscard]] size_t rfind_insensitive(StringRef Str) const;
374
375
376
379 }
380
381
382
383
384
385 [[nodiscard]] size_t find_first_of(StringRef Chars, size_t From = 0) const;
386
387
388
389 [[nodiscard]] size_t find_first_not_of(char C, size_t From = 0) const;
390
391
392
393
394
395 [[nodiscard]] size_t find_first_not_of(StringRef Chars,
396 size_t From = 0) const;
397
398
399
402 }
403
404
405
406
407
408 [[nodiscard]] size_t find_last_of(StringRef Chars,
410
411
412
413 [[nodiscard]] size_t find_last_not_of(char C, size_t From = npos) const;
414
415
416
417
418
419 [[nodiscard]] size_t find_last_not_of(StringRef Chars,
421
422
423
426 }
427
428
429
431 return find_first_of(C) != npos;
432 }
433
434
435
437 return find_insensitive(Other) != npos;
438 }
439
440
441
443 return find_insensitive(C) != npos;
444 }
445
446
447
448
449
450
451 [[nodiscard]] size_t count(char C) const {
452 size_t Count = 0;
453 for (size_t I = 0; I != size(); ++I)
455 ++Count;
456 return Count;
457 }
458
459
460
462
463
464
465
466
467
468
469
470 template bool getAsInteger(unsigned Radix, T &Result) const {
471 if constexpr (std::numeric_limits::is_signed) {
472 long long LLVal;
474 static_cast<T>(LLVal) != LLVal)
475 return true;
476 Result = LLVal;
477 } else {
478 unsigned long long ULLVal;
479
480
481
483 static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
484 return true;
485 Result = ULLVal;
486 }
487 return false;
488 }
489
490
491
492
493
494
495
496
497
498
499 template bool consumeInteger(unsigned Radix, T &Result) {
500 if constexpr (std::numeric_limits::is_signed) {
501 long long LLVal;
503 static_cast<long long>(static_cast<T>(LLVal)) != LLVal)
504 return true;
505 Result = LLVal;
506 } else {
507 unsigned long long ULLVal;
509 static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
510 return true;
511 Result = ULLVal;
512 }
513 return false;
514 }
515
516
517
518
519
520
521
522
523
524
525
526 bool getAsInteger(unsigned Radix, APInt &Result) const;
527
528
529
530
531
532
533
534
535
536
537 bool consumeInteger(unsigned Radix, APInt &Result);
538
539
540
541
542
543
544
545
546 bool getAsDouble(double &Result, bool AllowInexact = true) const;
547
548
549
550
551
552
553 [[nodiscard]] std::string lower() const;
554
555
556 [[nodiscard]] std::string upper() const;
557
558
559
560
561
562
563
564
565
566
567
568
569
570
573 Start = std::min(Start, size());
574 return StringRef(data() + Start, std::min(N, size() - Start));
575 }
576
577
578
579
582 return *this;
583 return drop_back(size() - N);
584 }
585
586
587
588
591 return *this;
592 return drop_front(size() - N);
593 }
594
595
596
599 }
600
601
602
605 }
606
607
608
610 assert(size() >= N && "Dropping more elements than exist");
612 }
613
614
615
617 assert(size() >= N && "Dropping more elements than exist");
619 }
620
621
622
625 }
626
627
628
631 }
632
633
634
637 return false;
638
639 *this = substr(Prefix.size());
640 return true;
641 }
642
643
644
646 if (!starts_with_insensitive(Prefix))
647 return false;
648
649 *this = substr(Prefix.size());
650 return true;
651 }
652
653
654
656 if (!ends_with(Suffix))
657 return false;
658
660 return true;
661 }
662
663
664
666 if (!ends_with_insensitive(Suffix))
667 return false;
668
670 return true;
671 }
672
673
674
675
676
677
678
679
680
681
682
683
685 Start = std::min(Start, size());
686 End = std::clamp(End, Start, size());
687 return StringRef(data() + Start, End - Start);
688 }
689
690
691
692
693
694
695
696
697
698
699
700 [[nodiscard]] std::pair<StringRef, StringRef> split(char Separator) const {
701 return split(StringRef(&Separator, 1));
702 }
703
704
705
706
707
708
709
710
711
712
713
714 [[nodiscard]] std::pair<StringRef, StringRef>
716 size_t Idx = find(Separator);
718 return std::make_pair(*this, StringRef());
719 return std::make_pair(slice(0, Idx), substr(Idx + Separator.size()));
720 }
721
722
723
724
725
726
727
728
729
730
731
732 [[nodiscard]] std::pair<StringRef, StringRef>
734 size_t Idx = rfind(Separator);
736 return std::make_pair(*this, StringRef());
737 return std::make_pair(slice(0, Idx), substr(Idx + Separator.size()));
738 }
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
755 StringRef Separator, int MaxSplit = -1,
756 bool KeepEmpty = true) const;
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
773 bool KeepEmpty = true) const;
774
775
776
777
778
779
780
781
782
783
784
785 [[nodiscard]] std::pair<StringRef, StringRef> rsplit(char Separator) const {
786 return rsplit(StringRef(&Separator, 1));
787 }
788
789
790
792 return drop_front(std::min(size(), find_first_not_of(Char)));
793 }
794
795
796
798 return drop_front(std::min(size(), find_first_not_of(Chars)));
799 }
800
801
802
804 return drop_back(size() - std::min(size(), find_last_not_of(Char) + 1));
805 }
806
807
808
810 return drop_back(size() - std::min(size(), find_last_not_of(Chars) + 1));
811 }
812
813
814
816 return ltrim(Char).rtrim(Char);
817 }
818
819
820
822 return ltrim(Chars).rtrim(Chars);
823 }
824
825
826
827
828
829
830
832 size_t Pos = find('\r');
833 if (Pos == npos) {
834
835 return "\n";
836 }
837 if (Pos + 1 < size() && data()[Pos + 1] == '\n')
838 return "\r\n";
839 if (Pos > 0 && data()[Pos - 1] == '\n')
840 return "\n\r";
841 return "\r";
842 }
843
844 };
845
846
847
848
849
850
851
852
854 private:
856 }
857
858 public:
859 template <size_t N>
861#if defined(__clang__) && __has_attribute(enable_if)
862#pragma clang diagnostic push
863#pragma clang diagnostic ignored "-Wgcc-compat"
864 __attribute((enable_if(__builtin_strlen(Str) == N - 1,
865 "invalid string literal")))
866#pragma clang diagnostic pop
867#endif
869 }
870
871
872 template <size_t N>
875 }
876 };
877
878
879
880
882 if (LHS.size() != RHS.size())
883 return false;
884 if (LHS.empty())
885 return true;
886 return ::memcmp(LHS.data(), RHS.data(), LHS.size()) == 0;
887 }
888
890
892 return LHS.compare(RHS) < 0;
893 }
894
896 return LHS.compare(RHS) <= 0;
897 }
898
900 return LHS.compare(RHS) > 0;
901 }
902
904 return LHS.compare(RHS) >= 0;
905 }
906
908 return buffer.append(string.data(), string.size());
909 }
910
911
912
913
914 [[nodiscard]] hash_code hash_value(StringRef S);
915
916
920 reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)), 0);
921 }
922
925 reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)), 0);
926 }
927
929
931 if (RHS.data() == getEmptyKey().data())
932 return LHS.data() == getEmptyKey().data();
933 if (RHS.data() == getTombstoneKey().data())
934 return LHS.data() == getTombstoneKey().data();
936 }
937 };
938
939}
940
941#endif
BlockVerifier::State From
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define LLVM_LIFETIME_BOUND
#define LLVM_GSL_POINTER
LLVM_GSL_POINTER - Apply this to non-owning classes like StringRef to enable lifetime warnings.
static constexpr size_t npos
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines DenseMapInfo traits for DenseMap.
std::optional< std::vector< StOtherPiece > > Other
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static StringRef substr(StringRef Str, uint64_t Len)
Class for arbitrary precision integers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
constexpr StringLiteral(const char(&Str)[N])
static constexpr StringLiteral withInnerNUL(const char(&Str)[N])
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
StringRef trim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the left and right removed.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
iterator_range< const unsigned char * > bytes() const
std::string str() const
str - Get the contents as an std::string.
size_t find_if(function_ref< bool(char)> F, size_t From=0) const
Search for the first character satisfying the predicate F.
const unsigned char * bytes_end() const
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
std::reverse_iterator< const_iterator > const_reverse_iterator
bool contains_insensitive(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
StringRef take_while(function_ref< bool(char)> F) const
Return the longest prefix of 'this' such that every character in the prefix satisfies the given predi...
bool ends_with(char Suffix) const
char operator[](size_t Index) const
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
bool contains_insensitive(char C) const
Return true if the given character is contained in *this, and false otherwise.
std::pair< StringRef, StringRef > rsplit(char Separator) const
Split into two substrings around the last occurrence of a separator character.
StringRef drop_until(function_ref< bool(char)> F) const
Return a StringRef equal to 'this', but with all characters not satisfying the given predicate droppe...
char back() const
back - Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
reverse_iterator rbegin() const
constexpr StringRef(const char *data LLVM_LIFETIME_BOUND, size_t length)
Construct a string ref from a pointer and length.
std::reverse_iterator< iterator > reverse_iterator
bool starts_with(char Prefix) const
size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
StringRef detectEOL() const
Detect the line ending style of the string.
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
StringRef()=default
Construct an empty string ref.
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
constexpr StringRef(const char *Str LLVM_LIFETIME_BOUND)
Construct a string ref from a cstring.
bool contains(char C) const
Return true if the given character is contained in *this, and false otherwise.
StringRef(std::nullptr_t)=delete
Disable conversion from nullptr.
StringRef take_back(size_t N=1) const
Return a StringRef equal to 'this' but with only the last N elements remaining.
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
StringRef take_until(function_ref< bool(char)> F) const
Return the longest prefix of 'this' such that no character in the prefix satisfies the given predicat...
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
size_t count(char C) const
Return the number of occurrences of C in the string.
bool consume_back_insensitive(StringRef Suffix)
Returns true if this StringRef has the given suffix, ignoring case, and removes that suffix.
StringRef copy(Allocator &A) const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
std::pair< StringRef, StringRef > rsplit(StringRef Separator) const
Split into two substrings around the last occurrence of a separator string.
std::pair< StringRef, StringRef > split(StringRef Separator) const
Split into two substrings around the first occurrence of a separator string.
StringRef ltrim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the left removed.
std::enable_if_t< std::is_same< T, std::string >::value, StringRef > & operator=(T &&Str)=delete
Disallow accidental assignment from a temporary std::string.
StringRef rtrim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the right removed.
StringRef drop_while(function_ref< bool(char)> F) const
Return a StringRef equal to 'this', but with all characters satisfying the given predicate dropped fr...
const unsigned char * bytes_begin() const
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
bool consume_front_insensitive(StringRef Prefix)
Returns true if this StringRef has the given prefix, ignoring case, and removes that prefix.
StringRef(const std::string &Str)
Construct a string ref from an std::string.
reverse_iterator rend() const
constexpr StringRef(std::string_view Str)
Construct a string ref from an std::string_view.
size_t find_if_not(function_ref< bool(char)> F, size_t From=0) const
Search for the first character not satisfying the predicate F.
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result)
hash_code hash_value(const FixedPointSemantics &Val)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool operator!=(uint64_t V1, const APInt &V2)
bool operator>=(int64_t V1, const APSInt &V2)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
bool consumeUnsignedInteger(StringRef &Str, unsigned Radix, unsigned long long &Result)
bool operator>(int64_t V1, const APSInt &V2)
auto find_if_not(R &&Range, UnaryPredicate P)
bool consumeSignedInteger(StringRef &Str, unsigned Radix, long long &Result)
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
bool operator<=(int64_t V1, const APSInt &V2)
Implement std::hash so that hash_code can be used in STL containers.
static StringRef getEmptyKey()
static bool isEqual(StringRef LHS, StringRef RHS)
static unsigned getHashValue(StringRef Val)
static StringRef getTombstoneKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...