• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- StringView.h -------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // FIXME: Use std::string_view instead when we support C++17.
10 // There are two copies of this file in the source tree.  The one under
11 // libcxxabi is the original and the one under llvm is the copy.  Use
12 // cp-to-llvm.sh to update the copy.  See README.txt for more details.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef DEMANGLE_STRINGVIEW_H
17 #define DEMANGLE_STRINGVIEW_H
18 
19 #include "DemangleConfig.h"
20 
21 #include <__cxxabi_config.h>
22 #include <cassert>
23 #include <cstring>
24 
25 #ifdef _LIBCXXABI_COMPILER_CLANG
26 #pragma clang diagnostic push
27 #pragma clang diagnostic ignored "-Wunused-template"
28 #endif
29 
30 DEMANGLE_NAMESPACE_BEGIN
31 
32 class StringView {
33   const char *First;
34   const char *Last;
35 
36 public:
37   static const size_t npos = ~size_t(0);
38 
39   template <size_t N>
StringView(const char (& Str)[N])40   StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
StringView(const char * First_,const char * Last_)41   StringView(const char *First_, const char *Last_)
42       : First(First_), Last(Last_) {}
StringView(const char * First_,size_t Len)43   StringView(const char *First_, size_t Len)
44       : First(First_), Last(First_ + Len) {}
StringView(const char * Str)45   StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
StringView()46   StringView() : First(nullptr), Last(nullptr) {}
47 
48   StringView substr(size_t Pos, size_t Len = npos) const {
49     assert(Pos <= size());
50     if (Len > size() - Pos)
51       Len = size() - Pos;
52     return StringView(begin() + Pos, Len);
53   }
54 
55   size_t find(char C, size_t From = 0) const {
56     // Avoid calling memchr with nullptr.
57     if (From < size()) {
58       // Just forward to memchr, which is faster than a hand-rolled loop.
59       if (const void *P = ::memchr(First + From, C, size() - From))
60         return size_t(static_cast<const char *>(P) - First);
61     }
62     return npos;
63   }
64 
65   StringView dropFront(size_t N = 1) const {
66     if (N >= size())
67       N = size();
68     return StringView(First + N, Last);
69   }
70 
71   StringView dropBack(size_t N = 1) const {
72     if (N >= size())
73       N = size();
74     return StringView(First, Last - N);
75   }
76 
front()77   char front() const {
78     assert(!empty());
79     return *begin();
80   }
81 
back()82   char back() const {
83     assert(!empty());
84     return *(end() - 1);
85   }
86 
popFront()87   char popFront() {
88     assert(!empty());
89     return *First++;
90   }
91 
consumeFront(char C)92   bool consumeFront(char C) {
93     if (!startsWith(C))
94       return false;
95     *this = dropFront(1);
96     return true;
97   }
98 
consumeFront(StringView S)99   bool consumeFront(StringView S) {
100     if (!startsWith(S))
101       return false;
102     *this = dropFront(S.size());
103     return true;
104   }
105 
startsWith(char C)106   bool startsWith(char C) const { return !empty() && *begin() == C; }
107 
startsWith(StringView Str)108   bool startsWith(StringView Str) const {
109     if (Str.size() > size())
110       return false;
111     return std::strncmp(Str.begin(), begin(), Str.size()) == 0;
112   }
113 
114   const char &operator[](size_t Idx) const { return *(begin() + Idx); }
115 
begin()116   const char *begin() const { return First; }
end()117   const char *end() const { return Last; }
size()118   size_t size() const { return static_cast<size_t>(Last - First); }
empty()119   bool empty() const { return First == Last; }
120 };
121 
122 inline bool operator==(const StringView &LHS, const StringView &RHS) {
123   return LHS.size() == RHS.size() &&
124          std::strncmp(LHS.begin(), RHS.begin(), LHS.size()) == 0;
125 }
126 
127 DEMANGLE_NAMESPACE_END
128 
129 #ifdef _LIBCXXABI_COMPILER_CLANG
130 #pragma clang diagnostic pop
131 #endif
132 
133 #endif
134