1 //===-- Standalone implementation std::string_view --------------*- 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 #ifndef LLVM_LIBC_SRC_SUPPORT_CPP_STRINGVIEW_H 10 #define LLVM_LIBC_SRC_SUPPORT_CPP_STRINGVIEW_H 11 12 #include <stddef.h> 13 14 namespace __llvm_libc { 15 namespace cpp { 16 17 // This is very simple alternate of the std::string_view class. There is no 18 // bounds check performed in any of the methods. The callers are expected to 19 // do the checks before invoking the methods. 20 // 21 // This class will be extended as needed in future. 22 class StringView { 23 private: 24 const char *Data; 25 size_t Len; 26 27 public: 28 StringView() : Data(nullptr), Len(0) {} 29 30 // Assumes Str is a null-terminated string. The length of the string does 31 // not include the terminating null character. 32 explicit StringView(const char *Str) : Data(Str), Len(0) { 33 if (Str == nullptr) 34 return; 35 for (const char *D = Data; *D != '\0'; ++D, ++Len) 36 ; 37 if (Len == 0) 38 Data = nullptr; 39 } 40 41 explicit StringView(const char *Str, size_t N) 42 : Data(N ? Str : nullptr), Len(Str == nullptr ? 0 : N) {} 43 44 const char *data() const { return Data; } 45 46 size_t size() { return Len; } 47 48 const char &operator[](size_t Index) const { return Data[Index]; } 49 50 StringView remove_prefix(size_t N) const { 51 if (N >= Len) 52 return StringView(); 53 return StringView(Data + N, Len - N); 54 } 55 56 StringView remove_suffix(size_t N) const { 57 if (N >= Len) 58 return StringView(); 59 return StringView(Data, Len - N); 60 } 61 62 // An equivalent method is not available in std::string_view. 63 StringView trim(char C) const { 64 if (Len == 0) 65 return StringView(); 66 67 const char *NewStart = Data; 68 size_t PrefixLen = 0; 69 for (; PrefixLen < Len; ++NewStart, ++PrefixLen) { 70 if (*NewStart != C) 71 break; 72 } 73 74 size_t SuffixLen = 0; 75 const char *NewEnd = Data + Len - 1; 76 for (; SuffixLen < Len; --NewEnd, ++SuffixLen) { 77 if (*NewEnd != C) 78 break; 79 } 80 81 return remove_prefix(PrefixLen).remove_suffix(SuffixLen); 82 } 83 84 // Check if this string starts with the given \p Prefix. 85 bool starts_with(StringView Prefix) const { 86 if (Len < Prefix.Len) 87 return false; 88 for (size_t I = 0; I < Prefix.Len; ++I) { 89 if (Data[I] != Prefix.Data[I]) 90 return false; 91 } 92 return true; 93 } 94 95 // An equivalent method is not available in std::string_view. 96 bool equals(StringView Other) const { 97 if (Len != Other.Len) 98 return false; 99 for (size_t I = 0; I < Len; ++I) { 100 if (Data[I] != Other.Data[I]) 101 return false; 102 } 103 return true; 104 } 105 }; 106 107 } // namespace cpp 108 } // namespace __llvm_libc 109 110 #endif // LLVM_LIBC_SRC_SUPPORT_CPP_STRINGVIEW_H 111