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