StringRef.h revision b834a7b73ce0dcf8fbf8d8b0d62f69e4b78059ad
14cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar//===--- StringRef.h - Constant String Reference Wrapper --------*- C++ -*-===//
24cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar//
34cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar//                     The LLVM Compiler Infrastructure
44cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar//
54cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar// This file is distributed under the University of Illinois Open Source
64cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar// License. See LICENSE.TXT for details.
74cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar//
84cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar//===----------------------------------------------------------------------===//
94cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
104cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar#ifndef LLVM_ADT_STRINGREF_H
114cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar#define LLVM_ADT_STRINGREF_H
124cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
1385f49835c288b0107cb4020d4e59e491c146973dDaniel Dunbar#include <cassert>
144cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar#include <cstring>
154cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar#include <string>
164cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
174cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbarnamespace llvm {
18f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar
194cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  /// StringRef - Represent a constant reference to a string, i.e. a character
204cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  /// array and a length, which need not be null terminated.
214cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  ///
224cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  /// This class does not own the string data, it is expected to be used in
234cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  /// situations where the character data resides in some other buffer, whose
244cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  /// lifetime extends past that of the StringRef. For this reason, it is not in
254cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  /// general safe to store a StringRef.
264cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  class StringRef {
274cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  public:
284cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    typedef const char *iterator;
29b834a7b73ce0dcf8fbf8d8b0d62f69e4b78059adDaniel Dunbar    static const size_t npos = ~size_t(0);
304cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
314cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  private:
324cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// The start of the string, in an external buffer.
334cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    const char *Data;
344cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
354cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// The length of the string.
36f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    size_t Length;
374cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
384cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  public:
394cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @name Constructors
404cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @{
414cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
424cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// Construct an empty string ref.
434cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /*implicit*/ StringRef() : Data(0), Length(0) {}
444cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
454cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// Construct a string ref from a cstring.
464cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /*implicit*/ StringRef(const char *Str)
474cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      : Data(Str), Length(::strlen(Str)) {}
484cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
494cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// Construct a string ref from a pointer and length.
504cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /*implicit*/ StringRef(const char *_Data, unsigned _Length)
514cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      : Data(_Data), Length(_Length) {}
524cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
534cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// Construct a string ref from an std::string.
544cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /*implicit*/ StringRef(const std::string &Str)
554cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      : Data(Str.c_str()), Length(Str.length()) {}
564cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
574cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @}
584cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @name Iterators
594cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @{
604cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
614cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    iterator begin() const { return Data; }
624cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
634cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    iterator end() const { return Data + Length; }
644cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
654cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @}
664cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @name String Operations
674cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @{
684cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
694cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// data - Get a pointer to the start of the string (which may not be null
704cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// terminated).
714cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    const char *data() const { return Data; }
724cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
734cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// empty - Check if the string is empty.
744cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    bool empty() const { return Length == 0; }
754cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
764cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// size - Get the string size.
777cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    size_t size() const { return Length; }
787cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
797cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    /// equals - Check for string equality, this is more efficient than
807cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    /// compare() in when the relative ordering of inequal strings isn't needed.
817cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    bool equals(const StringRef &RHS) const {
827cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar      return (Length == RHS.Length &&
837cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar              memcmp(Data, RHS.Data, Length) == 0);
847cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    }
854cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
864cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// compare - Compare two strings; the result is -1, 0, or 1 if this string
874cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// is lexicographically less than, equal to, or greater than the \arg RHS.
884cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    int compare(const StringRef &RHS) const {
894cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      // Check the prefix for a mismatch.
904cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      if (int Res = memcmp(Data, RHS.Data, std::min(Length, RHS.Length)))
914cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar        return Res < 0 ? -1 : 1;
924cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
934cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      // Otherwise the prefixes match, so we only need to check the lengths.
944cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      if (Length == RHS.Length)
954cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar        return 0;
964cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      return Length < RHS.Length ? -1 : 1;
974cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    }
984cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
994cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// str - Get the contents as an std::string.
1004cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    std::string str() const { return std::string(Data, Length); }
1014cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
1024cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @}
1034cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @name Operator Overloads
1044cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @{
1054cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
1064cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    char operator[](size_t Index) const {
1074cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      assert(Index < Length && "Invalid index!");
1084cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      return Data[Index];
1094cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    }
1104cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
1114cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @}
1124cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @name Type Conversions
1134cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @{
1144cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
1154cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    operator std::string() const {
1164cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar      return str();
1174cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    }
1184cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
1194cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar    /// @}
120f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// @name Utility Functions
121f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// @{
122f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar
123f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// substr - Return a reference to a substring of this object.
124f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    ///
125f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// \param Start - The index of the starting character in the substring; if
126f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// the index is greater than the length of the string then the empty
127f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// substring will be returned.
128f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    ///
129f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// \param N - The number of characters to included in the substring. If N
130f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// exceeds the number of characters remaining in the string, the string
131f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// suffix (starting with \arg Start) will be returned.
132f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    StringRef substr(size_t Start, size_t N = npos) const {
133f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar      Start = std::min(Start, Length);
134f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar      return StringRef(Data + Start, std::min(N, Length - Start));
135f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    }
136f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar
137f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// startswith - Check if this string starts with the given \arg Prefix.
138f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    bool startswith(const StringRef &Prefix) const {
1397cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar      return substr(0, Prefix.Length).equals(Prefix);
140f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    }
141f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar
142f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar    /// @}
1434cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar  };
144f5fdf73238dfd923f33bcbbd397cff6752d9c41eDaniel Dunbar
1457cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  /// @name StringRef Comparison Operators
1467cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  /// @{
1477cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
1487cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  inline bool operator==(const StringRef &LHS, const StringRef &RHS) {
1497cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    return LHS.equals(RHS);
1507cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  }
1517cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
1527cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  inline bool operator!=(const StringRef &LHS, const StringRef &RHS) {
1537cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    return !(LHS == RHS);
1547cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  }
1557cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
1567cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  inline bool operator<(const StringRef &LHS, const StringRef &RHS) {
1577cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    return LHS.compare(RHS) == -1;
1587cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  }
1597cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
1607cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  inline bool operator<=(const StringRef &LHS, const StringRef &RHS) {
1617cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    return LHS.compare(RHS) != 1;
1627cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  }
1637cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
1647cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  inline bool operator>(const StringRef &LHS, const StringRef &RHS) {
1657cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    return LHS.compare(RHS) == 1;
1667cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  }
1677cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
1687cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  inline bool operator>=(const StringRef &LHS, const StringRef &RHS) {
1697cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar    return LHS.compare(RHS) != -1;
1707cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  }
1717cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
1727cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar  /// @}
1737cb6860185187c74a1205deebff9e0f09a0ddae4Daniel Dunbar
1744cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar}
1754cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar
1764cf95d75c65f37677d306952b0d2306bc6d20b1fDaniel Dunbar#endif
177