Home | History | Annotate | Download | only in Demangle
      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>
     28   StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
     29   StringView(const char *First_, const char *Last_)
     30       : First(First_), Last(Last_) {}
     31   StringView(const char *First_, size_t Len)
     32       : First(First_), Last(First_ + Len) {}
     33   StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
     34   StringView() : First(nullptr), Last(nullptr) {}
     35 
     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 
     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 
     71   char front() const {
     72     assert(!empty());
     73     return *begin();
     74   }
     75 
     76   char back() const {
     77     assert(!empty());
     78     return *(end() - 1);
     79   }
     80 
     81   char popFront() {
     82     assert(!empty());
     83     return *First++;
     84   }
     85 
     86   bool consumeFront(char C) {
     87     if (!startsWith(C))
     88       return false;
     89     *this = dropFront(1);
     90     return true;
     91   }
     92 
     93   bool consumeFront(StringView S) {
     94     if (!startsWith(S))
     95       return false;
     96     *this = dropFront(S.size());
     97     return true;
     98   }
     99 
    100   bool startsWith(char C) const { return !empty() && *begin() == C; }
    101 
    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 
    110   const char *begin() const { return First; }
    111   const char *end() const { return Last; }
    112   size_t size() const { return static_cast<size_t>(Last - First); }
    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