• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- StringView.h -------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //
9 // This file contains a limited version of LLVM's StringView class.  It is
10 // copied here so that LLVMDemangle need not take a dependency on LLVMSupport.
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_DEMANGLE_STRINGVIEW_H
14 #define LLVM_DEMANGLE_STRINGVIEW_H
15 
16 #include <algorithm>
17 #include <cassert>
18 #include <cstring>
19 
20 class StringView {
21   const char *First;
22   const char *Last;
23 
24 public:
25   static const size_t npos = ~size_t(0);
26 
27   template <size_t N>
StringView(const char (& Str)[N])28   StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
StringView(const char * First_,const char * Last_)29   StringView(const char *First_, const char *Last_)
30       : First(First_), Last(Last_) {}
StringView(const char * First_,size_t Len)31   StringView(const char *First_, size_t Len)
32       : First(First_), Last(First_ + Len) {}
StringView(const char * Str)33   StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
StringView()34   StringView() : First(nullptr), Last(nullptr) {}
35 
substr(size_t From)36   StringView substr(size_t From) const {
37     return StringView(begin() + From, size() - From);
38   }
39 
40   size_t find(char C, size_t From = 0) const {
41     size_t FindBegin = std::min(From, size());
42     // Avoid calling memchr with nullptr.
43     if (FindBegin < size()) {
44       // Just forward to memchr, which is faster than a hand-rolled loop.
45       if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
46         return static_cast<const char *>(P) - First;
47     }
48     return npos;
49   }
50 
substr(size_t From,size_t To)51   StringView substr(size_t From, size_t To) const {
52     if (To >= size())
53       To = size() - 1;
54     if (From >= size())
55       From = size() - 1;
56     return StringView(First + From, First + To);
57   }
58 
59   StringView dropFront(size_t N = 1) const {
60     if (N >= size())
61       N = size();
62     return StringView(First + N, Last);
63   }
64 
65   StringView dropBack(size_t N = 1) const {
66     if (N >= size())
67       N = size();
68     return StringView(First, Last - N);
69   }
70 
front()71   char front() const {
72     assert(!empty());
73     return *begin();
74   }
75 
back()76   char back() const {
77     assert(!empty());
78     return *(end() - 1);
79   }
80 
popFront()81   char popFront() {
82     assert(!empty());
83     return *First++;
84   }
85 
consumeFront(char C)86   bool consumeFront(char C) {
87     if (!startsWith(C))
88       return false;
89     *this = dropFront(1);
90     return true;
91   }
92 
consumeFront(StringView S)93   bool consumeFront(StringView S) {
94     if (!startsWith(S))
95       return false;
96     *this = dropFront(S.size());
97     return true;
98   }
99 
startsWith(char C)100   bool startsWith(char C) const { return !empty() && *begin() == C; }
101 
startsWith(StringView Str)102   bool startsWith(StringView Str) const {
103     if (Str.size() > size())
104       return false;
105     return std::equal(Str.begin(), Str.end(), begin());
106   }
107 
108   const char &operator[](size_t Idx) const { return *(begin() + Idx); }
109 
begin()110   const char *begin() const { return First; }
end()111   const char *end() const { return Last; }
size()112   size_t size() const { return static_cast<size_t>(Last - First); }
empty()113   bool empty() const { return First == Last; }
114 };
115 
116 inline bool operator==(const StringView &LHS, const StringView &RHS) {
117   return LHS.size() == RHS.size() &&
118          std::equal(LHS.begin(), LHS.end(), RHS.begin());
119 }
120 
121 #endif
122