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