Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- 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 /// \file
0010 /// This file defines the SmallString class.
0011 ///
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_ADT_SMALLSTRING_H
0015 #define LLVM_ADT_SMALLSTRING_H
0016 
0017 #include "llvm/ADT/SmallVector.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include <cstddef>
0020 
0021 namespace llvm {
0022 
0023 /// SmallString - A SmallString is just a SmallVector with methods and accessors
0024 /// that make it work better as a string (e.g. operator+ etc).
0025 template<unsigned InternalLen>
0026 class SmallString : public SmallVector<char, InternalLen> {
0027 public:
0028   /// Default ctor - Initialize to empty.
0029   SmallString() = default;
0030 
0031   /// Initialize from a StringRef.
0032   SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
0033 
0034   /// Initialize by concatenating a list of StringRefs.
0035   SmallString(std::initializer_list<StringRef> Refs)
0036       : SmallVector<char, InternalLen>() {
0037     this->append(Refs);
0038   }
0039 
0040   /// Initialize with a range.
0041   template<typename ItTy>
0042   SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
0043 
0044   /// @}
0045   /// @name String Assignment
0046   /// @{
0047 
0048   using SmallVector<char, InternalLen>::assign;
0049 
0050   /// Assign from a StringRef.
0051   void assign(StringRef RHS) {
0052     SmallVectorImpl<char>::assign(RHS.begin(), RHS.end());
0053   }
0054 
0055   /// Assign from a list of StringRefs.
0056   void assign(std::initializer_list<StringRef> Refs) {
0057     this->clear();
0058     append(Refs);
0059   }
0060 
0061   /// @}
0062   /// @name String Concatenation
0063   /// @{
0064 
0065   using SmallVector<char, InternalLen>::append;
0066 
0067   /// Append from a StringRef.
0068   void append(StringRef RHS) {
0069     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
0070   }
0071 
0072   /// Append from a list of StringRefs.
0073   void append(std::initializer_list<StringRef> Refs) {
0074     size_t CurrentSize = this->size();
0075     size_t SizeNeeded = CurrentSize;
0076     for (const StringRef &Ref : Refs)
0077       SizeNeeded += Ref.size();
0078     this->resize_for_overwrite(SizeNeeded);
0079     for (const StringRef &Ref : Refs) {
0080       std::copy(Ref.begin(), Ref.end(), this->begin() + CurrentSize);
0081       CurrentSize += Ref.size();
0082     }
0083     assert(CurrentSize == this->size());
0084   }
0085 
0086   /// @}
0087   /// @name String Comparison
0088   /// @{
0089 
0090   /// Check for string equality.  This is more efficient than compare() when
0091   /// the relative ordering of inequal strings isn't needed.
0092   [[nodiscard]] bool equals(StringRef RHS) const { return str() == RHS; }
0093 
0094   /// Check for string equality, ignoring case.
0095   [[nodiscard]] bool equals_insensitive(StringRef RHS) const {
0096     return str().equals_insensitive(RHS);
0097   }
0098 
0099   /// compare - Compare two strings; the result is negative, zero, or positive
0100   /// if this string is lexicographically less than, equal to, or greater than
0101   /// the \p RHS.
0102   [[nodiscard]] int compare(StringRef RHS) const { return str().compare(RHS); }
0103 
0104   /// compare_insensitive - Compare two strings, ignoring case.
0105   [[nodiscard]] int compare_insensitive(StringRef RHS) const {
0106     return str().compare_insensitive(RHS);
0107   }
0108 
0109   /// compare_numeric - Compare two strings, treating sequences of digits as
0110   /// numbers.
0111   [[nodiscard]] int compare_numeric(StringRef RHS) const {
0112     return str().compare_numeric(RHS);
0113   }
0114 
0115   /// @}
0116   /// @name String Predicates
0117   /// @{
0118 
0119   /// starts_with - Check if this string starts with the given \p Prefix.
0120   [[nodiscard]] bool starts_with(StringRef Prefix) const {
0121     return str().starts_with(Prefix);
0122   }
0123 
0124   /// ends_with - Check if this string ends with the given \p Suffix.
0125   [[nodiscard]] bool ends_with(StringRef Suffix) const {
0126     return str().ends_with(Suffix);
0127   }
0128 
0129   /// @}
0130   /// @name String Searching
0131   /// @{
0132 
0133   /// find - Search for the first character \p C in the string.
0134   ///
0135   /// \return - The index of the first occurrence of \p C, or npos if not
0136   /// found.
0137   [[nodiscard]] size_t find(char C, size_t From = 0) const {
0138     return str().find(C, From);
0139   }
0140 
0141   /// Search for the first string \p Str in the string.
0142   ///
0143   /// \returns The index of the first occurrence of \p Str, or npos if not
0144   /// found.
0145   [[nodiscard]] size_t find(StringRef Str, size_t From = 0) const {
0146     return str().find(Str, From);
0147   }
0148 
0149   /// Search for the last character \p C in the string.
0150   ///
0151   /// \returns The index of the last occurrence of \p C, or npos if not
0152   /// found.
0153   [[nodiscard]] size_t rfind(char C, size_t From = StringRef::npos) const {
0154     return str().rfind(C, From);
0155   }
0156 
0157   /// Search for the last string \p Str in the string.
0158   ///
0159   /// \returns The index of the last occurrence of \p Str, or npos if not
0160   /// found.
0161   [[nodiscard]] size_t rfind(StringRef Str) const { return str().rfind(Str); }
0162 
0163   /// Find the first character in the string that is \p C, or npos if not
0164   /// found. Same as find.
0165   [[nodiscard]] size_t find_first_of(char C, size_t From = 0) const {
0166     return str().find_first_of(C, From);
0167   }
0168 
0169   /// Find the first character in the string that is in \p Chars, or npos if
0170   /// not found.
0171   ///
0172   /// Complexity: O(size() + Chars.size())
0173   [[nodiscard]] size_t find_first_of(StringRef Chars, size_t From = 0) const {
0174     return str().find_first_of(Chars, From);
0175   }
0176 
0177   /// Find the first character in the string that is not \p C or npos if not
0178   /// found.
0179   [[nodiscard]] size_t find_first_not_of(char C, size_t From = 0) const {
0180     return str().find_first_not_of(C, From);
0181   }
0182 
0183   /// Find the first character in the string that is not in the string
0184   /// \p Chars, or npos if not found.
0185   ///
0186   /// Complexity: O(size() + Chars.size())
0187   [[nodiscard]] size_t find_first_not_of(StringRef Chars,
0188                                          size_t From = 0) const {
0189     return str().find_first_not_of(Chars, From);
0190   }
0191 
0192   /// Find the last character in the string that is \p C, or npos if not
0193   /// found.
0194   [[nodiscard]] size_t find_last_of(char C,
0195                                     size_t From = StringRef::npos) const {
0196     return str().find_last_of(C, From);
0197   }
0198 
0199   /// Find the last character in the string that is in \p C, or npos if not
0200   /// found.
0201   ///
0202   /// Complexity: O(size() + Chars.size())
0203   [[nodiscard]] size_t find_last_of(StringRef Chars,
0204                                     size_t From = StringRef::npos) const {
0205     return str().find_last_of(Chars, From);
0206   }
0207 
0208   /// @}
0209   /// @name Helpful Algorithms
0210   /// @{
0211 
0212   /// Return the number of occurrences of \p C in the string.
0213   [[nodiscard]] size_t count(char C) const { return str().count(C); }
0214 
0215   /// Return the number of non-overlapped occurrences of \p Str in the
0216   /// string.
0217   [[nodiscard]] size_t count(StringRef Str) const { return str().count(Str); }
0218 
0219   /// @}
0220   /// @name Substring Operations
0221   /// @{
0222 
0223   /// Return a reference to the substring from [Start, Start + N).
0224   ///
0225   /// \param Start The index of the starting character in the substring; if
0226   /// the index is npos or greater than the length of the string then the
0227   /// empty substring will be returned.
0228   ///
0229   /// \param N The number of characters to included in the substring. If \p N
0230   /// exceeds the number of characters remaining in the string, the string
0231   /// suffix (starting with \p Start) will be returned.
0232   [[nodiscard]] StringRef substr(size_t Start,
0233                                  size_t N = StringRef::npos) const {
0234     return str().substr(Start, N);
0235   }
0236 
0237   /// Return a reference to the substring from [Start, End).
0238   ///
0239   /// \param Start The index of the starting character in the substring; if
0240   /// the index is npos or greater than the length of the string then the
0241   /// empty substring will be returned.
0242   ///
0243   /// \param End The index following the last character to include in the
0244   /// substring. If this is npos, or less than \p Start, or exceeds the
0245   /// number of characters remaining in the string, the string suffix
0246   /// (starting with \p Start) will be returned.
0247   [[nodiscard]] StringRef slice(size_t Start, size_t End) const {
0248     return str().slice(Start, End);
0249   }
0250 
0251   // Extra methods.
0252 
0253   /// Explicit conversion to StringRef.
0254   [[nodiscard]] StringRef str() const {
0255     return StringRef(this->data(), this->size());
0256   }
0257 
0258   // TODO: Make this const, if it's safe...
0259   const char* c_str() {
0260     this->push_back(0);
0261     this->pop_back();
0262     return this->data();
0263   }
0264 
0265   /// Implicit conversion to StringRef.
0266   operator StringRef() const { return str(); }
0267 
0268   explicit operator std::string() const {
0269     return std::string(this->data(), this->size());
0270   }
0271 
0272   // Extra operators.
0273   SmallString &operator=(StringRef RHS) {
0274     this->assign(RHS);
0275     return *this;
0276   }
0277 
0278   SmallString &operator+=(StringRef RHS) {
0279     this->append(RHS.begin(), RHS.end());
0280     return *this;
0281   }
0282   SmallString &operator+=(char C) {
0283     this->push_back(C);
0284     return *this;
0285   }
0286 };
0287 
0288 } // end namespace llvm
0289 
0290 #endif // LLVM_ADT_SMALLSTRING_H