Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:10

0001 //===- StringRef.h - Constant String Reference Wrapper ----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_ADT_STRINGREF_H
0010 #define LLVM_ADT_STRINGREF_H
0011 
0012 #include "llvm/ADT/DenseMapInfo.h"
0013 #include "llvm/ADT/STLFunctionalExtras.h"
0014 #include "llvm/ADT/iterator_range.h"
0015 #include "llvm/Support/Compiler.h"
0016 #include <algorithm>
0017 #include <cassert>
0018 #include <cstddef>
0019 #include <cstring>
0020 #include <iterator>
0021 #include <limits>
0022 #include <string>
0023 #include <string_view>
0024 #include <type_traits>
0025 #include <utility>
0026 
0027 namespace llvm {
0028 
0029   class APInt;
0030   class hash_code;
0031   template <typename T> class SmallVectorImpl;
0032   class StringRef;
0033 
0034   /// Helper functions for StringRef::getAsInteger.
0035   bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
0036                             unsigned long long &Result);
0037 
0038   bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
0039 
0040   bool consumeUnsignedInteger(StringRef &Str, unsigned Radix,
0041                               unsigned long long &Result);
0042   bool consumeSignedInteger(StringRef &Str, unsigned Radix, long long &Result);
0043 
0044   /// StringRef - Represent a constant reference to a string, i.e. a character
0045   /// array and a length, which need not be null terminated.
0046   ///
0047   /// This class does not own the string data, it is expected to be used in
0048   /// situations where the character data resides in some other buffer, whose
0049   /// lifetime extends past that of the StringRef. For this reason, it is not in
0050   /// general safe to store a StringRef.
0051   class LLVM_GSL_POINTER StringRef {
0052   public:
0053     static constexpr size_t npos = ~size_t(0);
0054 
0055     using iterator = const char *;
0056     using const_iterator = const char *;
0057     using size_type = size_t;
0058     using value_type = char;
0059     using reverse_iterator = std::reverse_iterator<iterator>;
0060     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0061 
0062   private:
0063     /// The start of the string, in an external buffer.
0064     const char *Data = nullptr;
0065 
0066     /// The length of the string.
0067     size_t Length = 0;
0068 
0069     // Workaround memcmp issue with null pointers (undefined behavior)
0070     // by providing a specialized version
0071     static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
0072       if (Length == 0) { return 0; }
0073       return ::memcmp(Lhs,Rhs,Length);
0074     }
0075 
0076   public:
0077     /// @name Constructors
0078     /// @{
0079 
0080     /// Construct an empty string ref.
0081     /*implicit*/ StringRef() = default;
0082 
0083     /// Disable conversion from nullptr.  This prevents things like
0084     /// if (S == nullptr)
0085     StringRef(std::nullptr_t) = delete;
0086 
0087     /// Construct a string ref from a cstring.
0088     /*implicit*/ constexpr StringRef(const char *Str LLVM_LIFETIME_BOUND)
0089         : Data(Str), Length(Str ?
0090     // GCC 7 doesn't have constexpr char_traits. Fall back to __builtin_strlen.
0091 #if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 8
0092                                 __builtin_strlen(Str)
0093 #else
0094                                 std::char_traits<char>::length(Str)
0095 #endif
0096                                 : 0) {
0097     }
0098 
0099     /// Construct a string ref from a pointer and length.
0100     /*implicit*/ constexpr StringRef(const char *data LLVM_LIFETIME_BOUND,
0101                                      size_t length)
0102         : Data(data), Length(length) {}
0103 
0104     /// Construct a string ref from an std::string.
0105     /*implicit*/ StringRef(const std::string &Str)
0106         : Data(Str.data()), Length(Str.length()) {}
0107 
0108     /// Construct a string ref from an std::string_view.
0109     /*implicit*/ constexpr StringRef(std::string_view Str)
0110         : Data(Str.data()), Length(Str.size()) {}
0111 
0112     /// @}
0113     /// @name Iterators
0114     /// @{
0115 
0116     iterator begin() const { return data(); }
0117 
0118     iterator end() const { return data() + size(); }
0119 
0120     reverse_iterator rbegin() const {
0121       return std::make_reverse_iterator(end());
0122     }
0123 
0124     reverse_iterator rend() const {
0125       return std::make_reverse_iterator(begin());
0126     }
0127 
0128     const unsigned char *bytes_begin() const {
0129       return reinterpret_cast<const unsigned char *>(begin());
0130     }
0131     const unsigned char *bytes_end() const {
0132       return reinterpret_cast<const unsigned char *>(end());
0133     }
0134     iterator_range<const unsigned char *> bytes() const {
0135       return make_range(bytes_begin(), bytes_end());
0136     }
0137 
0138     /// @}
0139     /// @name String Operations
0140     /// @{
0141 
0142     /// data - Get a pointer to the start of the string (which may not be null
0143     /// terminated).
0144     [[nodiscard]] constexpr const char *data() const { return Data; }
0145 
0146     /// empty - Check if the string is empty.
0147     [[nodiscard]] constexpr bool empty() const { return size() == 0; }
0148 
0149     /// size - Get the string size.
0150     [[nodiscard]] constexpr size_t size() const { return Length; }
0151 
0152     /// front - Get the first character in the string.
0153     [[nodiscard]] char front() const {
0154       assert(!empty());
0155       return data()[0];
0156     }
0157 
0158     /// back - Get the last character in the string.
0159     [[nodiscard]] char back() const {
0160       assert(!empty());
0161       return data()[size() - 1];
0162     }
0163 
0164     // copy - Allocate copy in Allocator and return StringRef to it.
0165     template <typename Allocator>
0166     [[nodiscard]] StringRef copy(Allocator &A) const {
0167       // Don't request a length 0 copy from the allocator.
0168       if (empty())
0169         return StringRef();
0170       char *S = A.template Allocate<char>(size());
0171       std::copy(begin(), end(), S);
0172       return StringRef(S, size());
0173     }
0174 
0175     /// Check for string equality, ignoring case.
0176     [[nodiscard]] bool equals_insensitive(StringRef RHS) const {
0177       return size() == RHS.size() && compare_insensitive(RHS) == 0;
0178     }
0179 
0180     /// compare - Compare two strings; the result is negative, zero, or positive
0181     /// if this string is lexicographically less than, equal to, or greater than
0182     /// the \p RHS.
0183     [[nodiscard]] int compare(StringRef RHS) const {
0184       // Check the prefix for a mismatch.
0185       if (int Res =
0186               compareMemory(data(), RHS.data(), std::min(size(), RHS.size())))
0187         return Res < 0 ? -1 : 1;
0188 
0189       // Otherwise the prefixes match, so we only need to check the lengths.
0190       if (size() == RHS.size())
0191         return 0;
0192       return size() < RHS.size() ? -1 : 1;
0193     }
0194 
0195     /// Compare two strings, ignoring case.
0196     [[nodiscard]] int compare_insensitive(StringRef RHS) const;
0197 
0198     /// compare_numeric - Compare two strings, treating sequences of digits as
0199     /// numbers.
0200     [[nodiscard]] int compare_numeric(StringRef RHS) const;
0201 
0202     /// Determine the edit distance between this string and another
0203     /// string.
0204     ///
0205     /// \param Other the string to compare this string against.
0206     ///
0207     /// \param AllowReplacements whether to allow character
0208     /// replacements (change one character into another) as a single
0209     /// operation, rather than as two operations (an insertion and a
0210     /// removal).
0211     ///
0212     /// \param MaxEditDistance If non-zero, the maximum edit distance that
0213     /// this routine is allowed to compute. If the edit distance will exceed
0214     /// that maximum, returns \c MaxEditDistance+1.
0215     ///
0216     /// \returns the minimum number of character insertions, removals,
0217     /// or (if \p AllowReplacements is \c true) replacements needed to
0218     /// transform one of the given strings into the other. If zero,
0219     /// the strings are identical.
0220     [[nodiscard]] unsigned edit_distance(StringRef Other,
0221                                          bool AllowReplacements = true,
0222                                          unsigned MaxEditDistance = 0) const;
0223 
0224     [[nodiscard]] unsigned
0225     edit_distance_insensitive(StringRef Other, bool AllowReplacements = true,
0226                               unsigned MaxEditDistance = 0) const;
0227 
0228     /// str - Get the contents as an std::string.
0229     [[nodiscard]] std::string str() const {
0230       if (!data())
0231         return std::string();
0232       return std::string(data(), size());
0233     }
0234 
0235     /// @}
0236     /// @name Operator Overloads
0237     /// @{
0238 
0239     [[nodiscard]] char operator[](size_t Index) const {
0240       assert(Index < size() && "Invalid index!");
0241       return data()[Index];
0242     }
0243 
0244     /// Disallow accidental assignment from a temporary std::string.
0245     ///
0246     /// The declaration here is extra complicated so that `stringRef = {}`
0247     /// and `stringRef = "abc"` continue to select the move assignment operator.
0248     template <typename T>
0249     std::enable_if_t<std::is_same<T, std::string>::value, StringRef> &
0250     operator=(T &&Str) = delete;
0251 
0252     /// @}
0253     /// @name Type Conversions
0254     /// @{
0255 
0256     constexpr operator std::string_view() const {
0257       return std::string_view(data(), size());
0258     }
0259 
0260     /// @}
0261     /// @name String Predicates
0262     /// @{
0263 
0264     /// Check if this string starts with the given \p Prefix.
0265     [[nodiscard]] bool starts_with(StringRef Prefix) const {
0266       return size() >= Prefix.size() &&
0267              compareMemory(data(), Prefix.data(), Prefix.size()) == 0;
0268     }
0269     [[nodiscard]] bool starts_with(char Prefix) const {
0270       return !empty() && front() == Prefix;
0271     }
0272 
0273     /// Check if this string starts with the given \p Prefix, ignoring case.
0274     [[nodiscard]] bool starts_with_insensitive(StringRef Prefix) const;
0275 
0276     /// Check if this string ends with the given \p Suffix.
0277     [[nodiscard]] bool ends_with(StringRef Suffix) const {
0278       return size() >= Suffix.size() &&
0279              compareMemory(end() - Suffix.size(), Suffix.data(),
0280                            Suffix.size()) == 0;
0281     }
0282     [[nodiscard]] bool ends_with(char Suffix) const {
0283       return !empty() && back() == Suffix;
0284     }
0285 
0286     /// Check if this string ends with the given \p Suffix, ignoring case.
0287     [[nodiscard]] bool ends_with_insensitive(StringRef Suffix) const;
0288 
0289     /// @}
0290     /// @name String Searching
0291     /// @{
0292 
0293     /// Search for the first character \p C in the string.
0294     ///
0295     /// \returns The index of the first occurrence of \p C, or npos if not
0296     /// found.
0297     [[nodiscard]] size_t find(char C, size_t From = 0) const {
0298       return std::string_view(*this).find(C, From);
0299     }
0300 
0301     /// Search for the first character \p C in the string, ignoring case.
0302     ///
0303     /// \returns The index of the first occurrence of \p C, or npos if not
0304     /// found.
0305     [[nodiscard]] size_t find_insensitive(char C, size_t From = 0) const;
0306 
0307     /// Search for the first character satisfying the predicate \p F
0308     ///
0309     /// \returns The index of the first character satisfying \p F starting from
0310     /// \p From, or npos if not found.
0311     [[nodiscard]] size_t find_if(function_ref<bool(char)> F,
0312                                  size_t From = 0) const {
0313       StringRef S = drop_front(From);
0314       while (!S.empty()) {
0315         if (F(S.front()))
0316           return size() - S.size();
0317         S = S.drop_front();
0318       }
0319       return npos;
0320     }
0321 
0322     /// Search for the first character not satisfying the predicate \p F
0323     ///
0324     /// \returns The index of the first character not satisfying \p F starting
0325     /// from \p From, or npos if not found.
0326     [[nodiscard]] size_t find_if_not(function_ref<bool(char)> F,
0327                                      size_t From = 0) const {
0328       return find_if([F](char c) { return !F(c); }, From);
0329     }
0330 
0331     /// Search for the first string \p Str in the string.
0332     ///
0333     /// \returns The index of the first occurrence of \p Str, or npos if not
0334     /// found.
0335     [[nodiscard]] size_t find(StringRef Str, size_t From = 0) const;
0336 
0337     /// Search for the first string \p Str in the string, ignoring case.
0338     ///
0339     /// \returns The index of the first occurrence of \p Str, or npos if not
0340     /// found.
0341     [[nodiscard]] size_t find_insensitive(StringRef Str, size_t From = 0) const;
0342 
0343     /// Search for the last character \p C in the string.
0344     ///
0345     /// \returns The index of the last occurrence of \p C, or npos if not
0346     /// found.
0347     [[nodiscard]] size_t rfind(char C, size_t From = npos) const {
0348       size_t I = std::min(From, size());
0349       while (I) {
0350         --I;
0351         if (data()[I] == C)
0352           return I;
0353       }
0354       return npos;
0355     }
0356 
0357     /// Search for the last character \p C in the string, ignoring case.
0358     ///
0359     /// \returns The index of the last occurrence of \p C, or npos if not
0360     /// found.
0361     [[nodiscard]] size_t rfind_insensitive(char C, size_t From = npos) const;
0362 
0363     /// Search for the last string \p Str in the string.
0364     ///
0365     /// \returns The index of the last occurrence of \p Str, or npos if not
0366     /// found.
0367     [[nodiscard]] size_t rfind(StringRef Str) const;
0368 
0369     /// Search for the last string \p Str in the string, ignoring case.
0370     ///
0371     /// \returns The index of the last occurrence of \p Str, or npos if not
0372     /// found.
0373     [[nodiscard]] size_t rfind_insensitive(StringRef Str) const;
0374 
0375     /// Find the first character in the string that is \p C, or npos if not
0376     /// found. Same as find.
0377     [[nodiscard]] size_t find_first_of(char C, size_t From = 0) const {
0378       return find(C, From);
0379     }
0380 
0381     /// Find the first character in the string that is in \p Chars, or npos if
0382     /// not found.
0383     ///
0384     /// Complexity: O(size() + Chars.size())
0385     [[nodiscard]] size_t find_first_of(StringRef Chars, size_t From = 0) const;
0386 
0387     /// Find the first character in the string that is not \p C or npos if not
0388     /// found.
0389     [[nodiscard]] size_t find_first_not_of(char C, size_t From = 0) const;
0390 
0391     /// Find the first character in the string that is not in the string
0392     /// \p Chars, or npos if not found.
0393     ///
0394     /// Complexity: O(size() + Chars.size())
0395     [[nodiscard]] size_t find_first_not_of(StringRef Chars,
0396                                            size_t From = 0) const;
0397 
0398     /// Find the last character in the string that is \p C, or npos if not
0399     /// found.
0400     [[nodiscard]] size_t find_last_of(char C, size_t From = npos) const {
0401       return rfind(C, From);
0402     }
0403 
0404     /// Find the last character in the string that is in \p C, or npos if not
0405     /// found.
0406     ///
0407     /// Complexity: O(size() + Chars.size())
0408     [[nodiscard]] size_t find_last_of(StringRef Chars,
0409                                       size_t From = npos) const;
0410 
0411     /// Find the last character in the string that is not \p C, or npos if not
0412     /// found.
0413     [[nodiscard]] size_t find_last_not_of(char C, size_t From = npos) const;
0414 
0415     /// Find the last character in the string that is not in \p Chars, or
0416     /// npos if not found.
0417     ///
0418     /// Complexity: O(size() + Chars.size())
0419     [[nodiscard]] size_t find_last_not_of(StringRef Chars,
0420                                           size_t From = npos) const;
0421 
0422     /// Return true if the given string is a substring of *this, and false
0423     /// otherwise.
0424     [[nodiscard]] bool contains(StringRef Other) const {
0425       return find(Other) != npos;
0426     }
0427 
0428     /// Return true if the given character is contained in *this, and false
0429     /// otherwise.
0430     [[nodiscard]] bool contains(char C) const {
0431       return find_first_of(C) != npos;
0432     }
0433 
0434     /// Return true if the given string is a substring of *this, and false
0435     /// otherwise.
0436     [[nodiscard]] bool contains_insensitive(StringRef Other) const {
0437       return find_insensitive(Other) != npos;
0438     }
0439 
0440     /// Return true if the given character is contained in *this, and false
0441     /// otherwise.
0442     [[nodiscard]] bool contains_insensitive(char C) const {
0443       return find_insensitive(C) != npos;
0444     }
0445 
0446     /// @}
0447     /// @name Helpful Algorithms
0448     /// @{
0449 
0450     /// Return the number of occurrences of \p C in the string.
0451     [[nodiscard]] size_t count(char C) const {
0452       size_t Count = 0;
0453       for (size_t I = 0; I != size(); ++I)
0454         if (data()[I] == C)
0455           ++Count;
0456       return Count;
0457     }
0458 
0459     /// Return the number of non-overlapped occurrences of \p Str in
0460     /// the string.
0461     size_t count(StringRef Str) const;
0462 
0463     /// Parse the current string as an integer of the specified radix.  If
0464     /// \p Radix is specified as zero, this does radix autosensing using
0465     /// extended C rules: 0 is octal, 0x is hex, 0b is binary.
0466     ///
0467     /// If the string is invalid or if only a subset of the string is valid,
0468     /// this returns true to signify the error.  The string is considered
0469     /// erroneous if empty or if it overflows T.
0470     template <typename T> bool getAsInteger(unsigned Radix, T &Result) const {
0471       if constexpr (std::numeric_limits<T>::is_signed) {
0472         long long LLVal;
0473         if (getAsSignedInteger(*this, Radix, LLVal) ||
0474             static_cast<T>(LLVal) != LLVal)
0475           return true;
0476         Result = LLVal;
0477       } else {
0478         unsigned long long ULLVal;
0479         // The additional cast to unsigned long long is required to avoid the
0480         // Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type
0481         // 'unsigned __int64' when instantiating getAsInteger with T = bool.
0482         if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
0483             static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
0484           return true;
0485         Result = ULLVal;
0486       }
0487       return false;
0488     }
0489 
0490     /// Parse the current string as an integer of the specified radix.  If
0491     /// \p Radix is specified as zero, this does radix autosensing using
0492     /// extended C rules: 0 is octal, 0x is hex, 0b is binary.
0493     ///
0494     /// If the string does not begin with a number of the specified radix,
0495     /// this returns true to signify the error. The string is considered
0496     /// erroneous if empty or if it overflows T.
0497     /// The portion of the string representing the discovered numeric value
0498     /// is removed from the beginning of the string.
0499     template <typename T> bool consumeInteger(unsigned Radix, T &Result) {
0500       if constexpr (std::numeric_limits<T>::is_signed) {
0501         long long LLVal;
0502         if (consumeSignedInteger(*this, Radix, LLVal) ||
0503             static_cast<long long>(static_cast<T>(LLVal)) != LLVal)
0504           return true;
0505         Result = LLVal;
0506       } else {
0507         unsigned long long ULLVal;
0508         if (consumeUnsignedInteger(*this, Radix, ULLVal) ||
0509             static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
0510           return true;
0511         Result = ULLVal;
0512       }
0513       return false;
0514     }
0515 
0516     /// Parse the current string as an integer of the specified \p Radix, or of
0517     /// an autosensed radix if the \p Radix given is 0.  The current value in
0518     /// \p Result is discarded, and the storage is changed to be wide enough to
0519     /// store the parsed integer.
0520     ///
0521     /// \returns true if the string does not solely consist of a valid
0522     /// non-empty number in the appropriate base.
0523     ///
0524     /// APInt::fromString is superficially similar but assumes the
0525     /// string is well-formed in the given radix.
0526     bool getAsInteger(unsigned Radix, APInt &Result) const;
0527 
0528     /// Parse the current string as an integer of the specified \p Radix.  If
0529     /// \p Radix is specified as zero, this does radix autosensing using
0530     /// extended C rules: 0 is octal, 0x is hex, 0b is binary.
0531     ///
0532     /// If the string does not begin with a number of the specified radix,
0533     /// this returns true to signify the error. The string is considered
0534     /// erroneous if empty.
0535     /// The portion of the string representing the discovered numeric value
0536     /// is removed from the beginning of the string.
0537     bool consumeInteger(unsigned Radix, APInt &Result);
0538 
0539     /// Parse the current string as an IEEE double-precision floating
0540     /// point value.  The string must be a well-formed double.
0541     ///
0542     /// If \p AllowInexact is false, the function will fail if the string
0543     /// cannot be represented exactly.  Otherwise, the function only fails
0544     /// in case of an overflow or underflow, or an invalid floating point
0545     /// representation.
0546     bool getAsDouble(double &Result, bool AllowInexact = true) const;
0547 
0548     /// @}
0549     /// @name String Operations
0550     /// @{
0551 
0552     // Convert the given ASCII string to lowercase.
0553     [[nodiscard]] std::string lower() const;
0554 
0555     /// Convert the given ASCII string to uppercase.
0556     [[nodiscard]] std::string upper() const;
0557 
0558     /// @}
0559     /// @name Substring Operations
0560     /// @{
0561 
0562     /// Return a reference to the substring from [Start, Start + N).
0563     ///
0564     /// \param Start The index of the starting character in the substring; if
0565     /// the index is npos or greater than the length of the string then the
0566     /// empty substring will be returned.
0567     ///
0568     /// \param N The number of characters to included in the substring. If N
0569     /// exceeds the number of characters remaining in the string, the string
0570     /// suffix (starting with \p Start) will be returned.
0571     [[nodiscard]] constexpr StringRef substr(size_t Start,
0572                                              size_t N = npos) const {
0573       Start = std::min(Start, size());
0574       return StringRef(data() + Start, std::min(N, size() - Start));
0575     }
0576 
0577     /// Return a StringRef equal to 'this' but with only the first \p N
0578     /// elements remaining.  If \p N is greater than the length of the
0579     /// string, the entire string is returned.
0580     [[nodiscard]] StringRef take_front(size_t N = 1) const {
0581       if (N >= size())
0582         return *this;
0583       return drop_back(size() - N);
0584     }
0585 
0586     /// Return a StringRef equal to 'this' but with only the last \p N
0587     /// elements remaining.  If \p N is greater than the length of the
0588     /// string, the entire string is returned.
0589     [[nodiscard]] StringRef take_back(size_t N = 1) const {
0590       if (N >= size())
0591         return *this;
0592       return drop_front(size() - N);
0593     }
0594 
0595     /// Return the longest prefix of 'this' such that every character
0596     /// in the prefix satisfies the given predicate.
0597     [[nodiscard]] StringRef take_while(function_ref<bool(char)> F) const {
0598       return substr(0, find_if_not(F));
0599     }
0600 
0601     /// Return the longest prefix of 'this' such that no character in
0602     /// the prefix satisfies the given predicate.
0603     [[nodiscard]] StringRef take_until(function_ref<bool(char)> F) const {
0604       return substr(0, find_if(F));
0605     }
0606 
0607     /// Return a StringRef equal to 'this' but with the first \p N elements
0608     /// dropped.
0609     [[nodiscard]] StringRef drop_front(size_t N = 1) const {
0610       assert(size() >= N && "Dropping more elements than exist");
0611       return substr(N);
0612     }
0613 
0614     /// Return a StringRef equal to 'this' but with the last \p N elements
0615     /// dropped.
0616     [[nodiscard]] StringRef drop_back(size_t N = 1) const {
0617       assert(size() >= N && "Dropping more elements than exist");
0618       return substr(0, size()-N);
0619     }
0620 
0621     /// Return a StringRef equal to 'this', but with all characters satisfying
0622     /// the given predicate dropped from the beginning of the string.
0623     [[nodiscard]] StringRef drop_while(function_ref<bool(char)> F) const {
0624       return substr(find_if_not(F));
0625     }
0626 
0627     /// Return a StringRef equal to 'this', but with all characters not
0628     /// satisfying the given predicate dropped from the beginning of the string.
0629     [[nodiscard]] StringRef drop_until(function_ref<bool(char)> F) const {
0630       return substr(find_if(F));
0631     }
0632 
0633     /// Returns true if this StringRef has the given prefix and removes that
0634     /// prefix.
0635     bool consume_front(StringRef Prefix) {
0636       if (!starts_with(Prefix))
0637         return false;
0638 
0639       *this = substr(Prefix.size());
0640       return true;
0641     }
0642 
0643     /// Returns true if this StringRef has the given prefix, ignoring case,
0644     /// and removes that prefix.
0645     bool consume_front_insensitive(StringRef Prefix) {
0646       if (!starts_with_insensitive(Prefix))
0647         return false;
0648 
0649       *this = substr(Prefix.size());
0650       return true;
0651     }
0652 
0653     /// Returns true if this StringRef has the given suffix and removes that
0654     /// suffix.
0655     bool consume_back(StringRef Suffix) {
0656       if (!ends_with(Suffix))
0657         return false;
0658 
0659       *this = substr(0, size() - Suffix.size());
0660       return true;
0661     }
0662 
0663     /// Returns true if this StringRef has the given suffix, ignoring case,
0664     /// and removes that suffix.
0665     bool consume_back_insensitive(StringRef Suffix) {
0666       if (!ends_with_insensitive(Suffix))
0667         return false;
0668 
0669       *this = substr(0, size() - Suffix.size());
0670       return true;
0671     }
0672 
0673     /// Return a reference to the substring from [Start, End).
0674     ///
0675     /// \param Start The index of the starting character in the substring; if
0676     /// the index is npos or greater than the length of the string then the
0677     /// empty substring will be returned.
0678     ///
0679     /// \param End The index following the last character to include in the
0680     /// substring. If this is npos or exceeds the number of characters
0681     /// remaining in the string, the string suffix (starting with \p Start)
0682     /// will be returned. If this is less than \p Start, an empty string will
0683     /// be returned.
0684     [[nodiscard]] StringRef slice(size_t Start, size_t End) const {
0685       Start = std::min(Start, size());
0686       End = std::clamp(End, Start, size());
0687       return StringRef(data() + Start, End - Start);
0688     }
0689 
0690     /// Split into two substrings around the first occurrence of a separator
0691     /// character.
0692     ///
0693     /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
0694     /// such that (*this == LHS + Separator + RHS) is true and RHS is
0695     /// maximal. If \p Separator is not in the string, then the result is a
0696     /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
0697     ///
0698     /// \param Separator The character to split on.
0699     /// \returns The split substrings.
0700     [[nodiscard]] std::pair<StringRef, StringRef> split(char Separator) const {
0701       return split(StringRef(&Separator, 1));
0702     }
0703 
0704     /// Split into two substrings around the first occurrence of a separator
0705     /// string.
0706     ///
0707     /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
0708     /// such that (*this == LHS + Separator + RHS) is true and RHS is
0709     /// maximal. If \p Separator is not in the string, then the result is a
0710     /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
0711     ///
0712     /// \param Separator - The string to split on.
0713     /// \return - The split substrings.
0714     [[nodiscard]] std::pair<StringRef, StringRef>
0715     split(StringRef Separator) const {
0716       size_t Idx = find(Separator);
0717       if (Idx == npos)
0718         return std::make_pair(*this, StringRef());
0719       return std::make_pair(slice(0, Idx), substr(Idx + Separator.size()));
0720     }
0721 
0722     /// Split into two substrings around the last occurrence of a separator
0723     /// string.
0724     ///
0725     /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
0726     /// such that (*this == LHS + Separator + RHS) is true and RHS is
0727     /// minimal. If \p Separator is not in the string, then the result is a
0728     /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
0729     ///
0730     /// \param Separator - The string to split on.
0731     /// \return - The split substrings.
0732     [[nodiscard]] std::pair<StringRef, StringRef>
0733     rsplit(StringRef Separator) const {
0734       size_t Idx = rfind(Separator);
0735       if (Idx == npos)
0736         return std::make_pair(*this, StringRef());
0737       return std::make_pair(slice(0, Idx), substr(Idx + Separator.size()));
0738     }
0739 
0740     /// Split into substrings around the occurrences of a separator string.
0741     ///
0742     /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
0743     /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1
0744     /// elements are added to A.
0745     /// If \p KeepEmpty is false, empty strings are not added to \p A. They
0746     /// still count when considering \p MaxSplit
0747     /// An useful invariant is that
0748     /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
0749     ///
0750     /// \param A - Where to put the substrings.
0751     /// \param Separator - The string to split on.
0752     /// \param MaxSplit - The maximum number of times the string is split.
0753     /// \param KeepEmpty - True if empty substring should be added.
0754     void split(SmallVectorImpl<StringRef> &A,
0755                StringRef Separator, int MaxSplit = -1,
0756                bool KeepEmpty = true) const;
0757 
0758     /// Split into substrings around the occurrences of a separator character.
0759     ///
0760     /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
0761     /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1
0762     /// elements are added to A.
0763     /// If \p KeepEmpty is false, empty strings are not added to \p A. They
0764     /// still count when considering \p MaxSplit
0765     /// An useful invariant is that
0766     /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
0767     ///
0768     /// \param A - Where to put the substrings.
0769     /// \param Separator - The string to split on.
0770     /// \param MaxSplit - The maximum number of times the string is split.
0771     /// \param KeepEmpty - True if empty substring should be added.
0772     void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1,
0773                bool KeepEmpty = true) const;
0774 
0775     /// Split into two substrings around the last occurrence of a separator
0776     /// character.
0777     ///
0778     /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
0779     /// such that (*this == LHS + Separator + RHS) is true and RHS is
0780     /// minimal. If \p Separator is not in the string, then the result is a
0781     /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
0782     ///
0783     /// \param Separator - The character to split on.
0784     /// \return - The split substrings.
0785     [[nodiscard]] std::pair<StringRef, StringRef> rsplit(char Separator) const {
0786       return rsplit(StringRef(&Separator, 1));
0787     }
0788 
0789     /// Return string with consecutive \p Char characters starting from the
0790     /// the left removed.
0791     [[nodiscard]] StringRef ltrim(char Char) const {
0792       return drop_front(std::min(size(), find_first_not_of(Char)));
0793     }
0794 
0795     /// Return string with consecutive characters in \p Chars starting from
0796     /// the left removed.
0797     [[nodiscard]] StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
0798       return drop_front(std::min(size(), find_first_not_of(Chars)));
0799     }
0800 
0801     /// Return string with consecutive \p Char characters starting from the
0802     /// right removed.
0803     [[nodiscard]] StringRef rtrim(char Char) const {
0804       return drop_back(size() - std::min(size(), find_last_not_of(Char) + 1));
0805     }
0806 
0807     /// Return string with consecutive characters in \p Chars starting from
0808     /// the right removed.
0809     [[nodiscard]] StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
0810       return drop_back(size() - std::min(size(), find_last_not_of(Chars) + 1));
0811     }
0812 
0813     /// Return string with consecutive \p Char characters starting from the
0814     /// left and right removed.
0815     [[nodiscard]] StringRef trim(char Char) const {
0816       return ltrim(Char).rtrim(Char);
0817     }
0818 
0819     /// Return string with consecutive characters in \p Chars starting from
0820     /// the left and right removed.
0821     [[nodiscard]] StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
0822       return ltrim(Chars).rtrim(Chars);
0823     }
0824 
0825     /// Detect the line ending style of the string.
0826     ///
0827     /// If the string contains a line ending, return the line ending character
0828     /// sequence that is detected. Otherwise return '\n' for unix line endings.
0829     ///
0830     /// \return - The line ending character sequence.
0831     [[nodiscard]] StringRef detectEOL() const {
0832       size_t Pos = find('\r');
0833       if (Pos == npos) {
0834         // If there is no carriage return, assume unix
0835         return "\n";
0836       }
0837       if (Pos + 1 < size() && data()[Pos + 1] == '\n')
0838         return "\r\n"; // Windows
0839       if (Pos > 0 && data()[Pos - 1] == '\n')
0840         return "\n\r"; // You monster!
0841       return "\r";     // Classic Mac
0842     }
0843     /// @}
0844   };
0845 
0846   /// A wrapper around a string literal that serves as a proxy for constructing
0847   /// global tables of StringRefs with the length computed at compile time.
0848   /// In order to avoid the invocation of a global constructor, StringLiteral
0849   /// should *only* be used in a constexpr context, as such:
0850   ///
0851   /// constexpr StringLiteral S("test");
0852   ///
0853   class StringLiteral : public StringRef {
0854   private:
0855     constexpr StringLiteral(const char *Str, size_t N) : StringRef(Str, N) {
0856     }
0857 
0858   public:
0859     template <size_t N>
0860     constexpr StringLiteral(const char (&Str)[N])
0861 #if defined(__clang__) && __has_attribute(enable_if)
0862 #pragma clang diagnostic push
0863 #pragma clang diagnostic ignored "-Wgcc-compat"
0864         __attribute((enable_if(__builtin_strlen(Str) == N - 1,
0865                                "invalid string literal")))
0866 #pragma clang diagnostic pop
0867 #endif
0868         : StringRef(Str, N - 1) {
0869     }
0870 
0871     // Explicit construction for strings like "foo\0bar".
0872     template <size_t N>
0873     static constexpr StringLiteral withInnerNUL(const char (&Str)[N]) {
0874       return StringLiteral(Str, N - 1);
0875     }
0876   };
0877 
0878   /// @name StringRef Comparison Operators
0879   /// @{
0880 
0881   inline bool operator==(StringRef LHS, StringRef RHS) {
0882     if (LHS.size() != RHS.size())
0883       return false;
0884     if (LHS.empty())
0885       return true;
0886     return ::memcmp(LHS.data(), RHS.data(), LHS.size()) == 0;
0887   }
0888 
0889   inline bool operator!=(StringRef LHS, StringRef RHS) { return !(LHS == RHS); }
0890 
0891   inline bool operator<(StringRef LHS, StringRef RHS) {
0892     return LHS.compare(RHS) < 0;
0893   }
0894 
0895   inline bool operator<=(StringRef LHS, StringRef RHS) {
0896     return LHS.compare(RHS) <= 0;
0897   }
0898 
0899   inline bool operator>(StringRef LHS, StringRef RHS) {
0900     return LHS.compare(RHS) > 0;
0901   }
0902 
0903   inline bool operator>=(StringRef LHS, StringRef RHS) {
0904     return LHS.compare(RHS) >= 0;
0905   }
0906 
0907   inline std::string &operator+=(std::string &buffer, StringRef string) {
0908     return buffer.append(string.data(), string.size());
0909   }
0910 
0911   /// @}
0912 
0913   /// Compute a hash_code for a StringRef.
0914   [[nodiscard]] hash_code hash_value(StringRef S);
0915 
0916   // Provide DenseMapInfo for StringRefs.
0917   template <> struct DenseMapInfo<StringRef, void> {
0918     static inline StringRef getEmptyKey() {
0919       return StringRef(
0920           reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)), 0);
0921     }
0922 
0923     static inline StringRef getTombstoneKey() {
0924       return StringRef(
0925           reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)), 0);
0926     }
0927 
0928     static unsigned getHashValue(StringRef Val);
0929 
0930     static bool isEqual(StringRef LHS, StringRef RHS) {
0931       if (RHS.data() == getEmptyKey().data())
0932         return LHS.data() == getEmptyKey().data();
0933       if (RHS.data() == getTombstoneKey().data())
0934         return LHS.data() == getTombstoneKey().data();
0935       return LHS == RHS;
0936     }
0937   };
0938 
0939 } // end namespace llvm
0940 
0941 #endif // LLVM_ADT_STRINGREF_H