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