xref: /openbsd-src/gnu/llvm/libcxxabi/src/demangle/StringView.h (revision 8f1d572453a8bab44a2fe956e25efc4124e87e82)
179c2e3e6Spatrick //===--- StringView.h -------------------------------------------*- C++ -*-===//
279c2e3e6Spatrick //
379c2e3e6Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
479c2e3e6Spatrick // See https://llvm.org/LICENSE.txt for license information.
579c2e3e6Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
679c2e3e6Spatrick //
779c2e3e6Spatrick //===----------------------------------------------------------------------===//
879c2e3e6Spatrick //
979c2e3e6Spatrick // FIXME: Use std::string_view instead when we support C++17.
10*8f1d5724Srobert // There are two copies of this file in the source tree.  The one under
11*8f1d5724Srobert // libcxxabi is the original and the one under llvm is the copy.  Use
12*8f1d5724Srobert // cp-to-llvm.sh to update the copy.  See README.txt for more details.
1379c2e3e6Spatrick //
1479c2e3e6Spatrick //===----------------------------------------------------------------------===//
1579c2e3e6Spatrick 
1679c2e3e6Spatrick #ifndef DEMANGLE_STRINGVIEW_H
1779c2e3e6Spatrick #define DEMANGLE_STRINGVIEW_H
1879c2e3e6Spatrick 
1979c2e3e6Spatrick #include "DemangleConfig.h"
2079c2e3e6Spatrick #include <cassert>
2179c2e3e6Spatrick #include <cstring>
2279c2e3e6Spatrick 
2379c2e3e6Spatrick DEMANGLE_NAMESPACE_BEGIN
2479c2e3e6Spatrick 
2579c2e3e6Spatrick class StringView {
2679c2e3e6Spatrick   const char *First;
2779c2e3e6Spatrick   const char *Last;
2879c2e3e6Spatrick 
2979c2e3e6Spatrick public:
3079c2e3e6Spatrick   static const size_t npos = ~size_t(0);
3179c2e3e6Spatrick 
3279c2e3e6Spatrick   template <size_t N>
StringView(const char (& Str)[N])3379c2e3e6Spatrick   StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
StringView(const char * First_,const char * Last_)3479c2e3e6Spatrick   StringView(const char *First_, const char *Last_)
3579c2e3e6Spatrick       : First(First_), Last(Last_) {}
StringView(const char * First_,size_t Len)3679c2e3e6Spatrick   StringView(const char *First_, size_t Len)
3779c2e3e6Spatrick       : First(First_), Last(First_ + Len) {}
StringView(const char * Str)3879c2e3e6Spatrick   StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
StringView()3979c2e3e6Spatrick   StringView() : First(nullptr), Last(nullptr) {}
4079c2e3e6Spatrick 
414e0cc08cSpatrick   StringView substr(size_t Pos, size_t Len = npos) const {
424e0cc08cSpatrick     assert(Pos <= size());
43*8f1d5724Srobert     if (Len > size() - Pos)
44*8f1d5724Srobert       Len = size() - Pos;
45*8f1d5724Srobert     return StringView(begin() + Pos, Len);
4679c2e3e6Spatrick   }
4779c2e3e6Spatrick 
4879c2e3e6Spatrick   size_t find(char C, size_t From = 0) const {
4979c2e3e6Spatrick     // Avoid calling memchr with nullptr.
50*8f1d5724Srobert     if (From < size()) {
5179c2e3e6Spatrick       // Just forward to memchr, which is faster than a hand-rolled loop.
52*8f1d5724Srobert       if (const void *P = ::memchr(First + From, C, size() - From))
5379c2e3e6Spatrick         return size_t(static_cast<const char *>(P) - First);
5479c2e3e6Spatrick     }
5579c2e3e6Spatrick     return npos;
5679c2e3e6Spatrick   }
5779c2e3e6Spatrick 
5879c2e3e6Spatrick   StringView dropFront(size_t N = 1) const {
5979c2e3e6Spatrick     if (N >= size())
6079c2e3e6Spatrick       N = size();
6179c2e3e6Spatrick     return StringView(First + N, Last);
6279c2e3e6Spatrick   }
6379c2e3e6Spatrick 
6479c2e3e6Spatrick   StringView dropBack(size_t N = 1) const {
6579c2e3e6Spatrick     if (N >= size())
6679c2e3e6Spatrick       N = size();
6779c2e3e6Spatrick     return StringView(First, Last - N);
6879c2e3e6Spatrick   }
6979c2e3e6Spatrick 
front()7079c2e3e6Spatrick   char front() const {
7179c2e3e6Spatrick     assert(!empty());
7279c2e3e6Spatrick     return *begin();
7379c2e3e6Spatrick   }
7479c2e3e6Spatrick 
back()7579c2e3e6Spatrick   char back() const {
7679c2e3e6Spatrick     assert(!empty());
7779c2e3e6Spatrick     return *(end() - 1);
7879c2e3e6Spatrick   }
7979c2e3e6Spatrick 
popFront()8079c2e3e6Spatrick   char popFront() {
8179c2e3e6Spatrick     assert(!empty());
8279c2e3e6Spatrick     return *First++;
8379c2e3e6Spatrick   }
8479c2e3e6Spatrick 
consumeFront(char C)8579c2e3e6Spatrick   bool consumeFront(char C) {
8679c2e3e6Spatrick     if (!startsWith(C))
8779c2e3e6Spatrick       return false;
8879c2e3e6Spatrick     *this = dropFront(1);
8979c2e3e6Spatrick     return true;
9079c2e3e6Spatrick   }
9179c2e3e6Spatrick 
consumeFront(StringView S)9279c2e3e6Spatrick   bool consumeFront(StringView S) {
9379c2e3e6Spatrick     if (!startsWith(S))
9479c2e3e6Spatrick       return false;
9579c2e3e6Spatrick     *this = dropFront(S.size());
9679c2e3e6Spatrick     return true;
9779c2e3e6Spatrick   }
9879c2e3e6Spatrick 
startsWith(char C)9979c2e3e6Spatrick   bool startsWith(char C) const { return !empty() && *begin() == C; }
10079c2e3e6Spatrick 
startsWith(StringView Str)10179c2e3e6Spatrick   bool startsWith(StringView Str) const {
10279c2e3e6Spatrick     if (Str.size() > size())
10379c2e3e6Spatrick       return false;
104*8f1d5724Srobert     return std::strncmp(Str.begin(), begin(), Str.size()) == 0;
10579c2e3e6Spatrick   }
10679c2e3e6Spatrick 
10779c2e3e6Spatrick   const char &operator[](size_t Idx) const { return *(begin() + Idx); }
10879c2e3e6Spatrick 
begin()10979c2e3e6Spatrick   const char *begin() const { return First; }
end()11079c2e3e6Spatrick   const char *end() const { return Last; }
size()11179c2e3e6Spatrick   size_t size() const { return static_cast<size_t>(Last - First); }
empty()11279c2e3e6Spatrick   bool empty() const { return First == Last; }
11379c2e3e6Spatrick };
11479c2e3e6Spatrick 
11579c2e3e6Spatrick inline bool operator==(const StringView &LHS, const StringView &RHS) {
11679c2e3e6Spatrick   return LHS.size() == RHS.size() &&
117*8f1d5724Srobert          std::strncmp(LHS.begin(), RHS.begin(), LHS.size()) == 0;
11879c2e3e6Spatrick }
11979c2e3e6Spatrick 
12079c2e3e6Spatrick DEMANGLE_NAMESPACE_END
12179c2e3e6Spatrick 
12279c2e3e6Spatrick #endif
123