xref: /netbsd-src/external/apache2/llvm/dist/llvm/include/llvm/Demangle/StringView.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
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 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_DEMANGLE_STRINGVIEW_H
14 #define LLVM_DEMANGLE_STRINGVIEW_H
15 
16 #include "DemangleConfig.h"
17 #include <algorithm>
18 #include <cassert>
19 #include <cstring>
20 
21 DEMANGLE_NAMESPACE_BEGIN
22 
23 class StringView {
24   const char *First;
25   const char *Last;
26 
27 public:
28   static const size_t npos = ~size_t(0);
29 
30   template <size_t N>
StringView(const char (& Str)[N])31   StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
StringView(const char * First_,const char * Last_)32   StringView(const char *First_, const char *Last_)
33       : First(First_), Last(Last_) {}
StringView(const char * First_,size_t Len)34   StringView(const char *First_, size_t Len)
35       : First(First_), Last(First_ + Len) {}
StringView(const char * Str)36   StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
StringView()37   StringView() : First(nullptr), Last(nullptr) {}
38 
39   StringView substr(size_t Pos, size_t Len = npos) const {
40     assert(Pos <= size());
41     return StringView(begin() + Pos, std::min(Len, size() - Pos));
42   }
43 
44   size_t find(char C, size_t From = 0) const {
45     size_t FindBegin = std::min(From, size());
46     // Avoid calling memchr with nullptr.
47     if (FindBegin < size()) {
48       // Just forward to memchr, which is faster than a hand-rolled loop.
49       if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
50         return size_t(static_cast<const char *>(P) - First);
51     }
52     return npos;
53   }
54 
55   StringView dropFront(size_t N = 1) const {
56     if (N >= size())
57       N = size();
58     return StringView(First + N, Last);
59   }
60 
61   StringView dropBack(size_t N = 1) const {
62     if (N >= size())
63       N = size();
64     return StringView(First, Last - N);
65   }
66 
front()67   char front() const {
68     assert(!empty());
69     return *begin();
70   }
71 
back()72   char back() const {
73     assert(!empty());
74     return *(end() - 1);
75   }
76 
popFront()77   char popFront() {
78     assert(!empty());
79     return *First++;
80   }
81 
consumeFront(char C)82   bool consumeFront(char C) {
83     if (!startsWith(C))
84       return false;
85     *this = dropFront(1);
86     return true;
87   }
88 
consumeFront(StringView S)89   bool consumeFront(StringView S) {
90     if (!startsWith(S))
91       return false;
92     *this = dropFront(S.size());
93     return true;
94   }
95 
startsWith(char C)96   bool startsWith(char C) const { return !empty() && *begin() == C; }
97 
startsWith(StringView Str)98   bool startsWith(StringView Str) const {
99     if (Str.size() > size())
100       return false;
101     return std::equal(Str.begin(), Str.end(), begin());
102   }
103 
104   const char &operator[](size_t Idx) const { return *(begin() + Idx); }
105 
begin()106   const char *begin() const { return First; }
end()107   const char *end() const { return Last; }
size()108   size_t size() const { return static_cast<size_t>(Last - First); }
empty()109   bool empty() const { return First == Last; }
110 };
111 
112 inline bool operator==(const StringView &LHS, const StringView &RHS) {
113   return LHS.size() == RHS.size() &&
114          std::equal(LHS.begin(), LHS.end(), RHS.begin());
115 }
116 
117 DEMANGLE_NAMESPACE_END
118 
119 #endif
120