Warning: This file is not a C or C++ file. It does not have highlighting.

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_STRING_VIEW_H
10#define LLVM_LIBC_SRC___SUPPORT_CPP_STRING_VIEW_H
11
12#include "limits.h"
13#include "src/__support/common.h"
14#include "src/__support/macros/config.h"
15
16#include <stddef.h>
17
18namespace LIBC_NAMESPACE_DECL {
19namespace cpp {
20
21// This is very simple alternate of the std::string_view class. There is no
22// bounds check performed in any of the methods. The callers are expected to
23// do the checks before invoking the methods.
24//
25// This class will be extended as needed in future.
26class string_view {
27private:
28 const char *Data;
29 size_t Len;
30
31 LIBC_INLINE static size_t min(size_t A, size_t B) { return A <= B ? A : B; }
32
33 LIBC_INLINE static int compareMemory(const char *Lhs, const char *Rhs,
34 size_t Length) {
35 for (size_t i = 0; i < Length; ++i)
36 if (int Diff = (int)Lhs[i] - (int)Rhs[i])
37 return Diff;
38 return 0;
39 }
40
41 LIBC_INLINE static constexpr size_t length(const char *Str) {
42 for (const char *End = Str;; ++End)
43 if (*End == '\0')
44 return static_cast<size_t>(End - Str);
45 }
46
47 LIBC_INLINE bool equals(string_view Other) const {
48 return (Len == Other.Len &&
49 compareMemory(Data, Other.Data, Other.Len) == 0);
50 }
51
52public:
53 using value_type = char;
54 using size_type = size_t;
55 using difference_type = ptrdiff_t;
56 using pointer = char *;
57 using const_pointer = const char *;
58 using reference = char &;
59 using const_reference = const char &;
60 using const_iterator = char *;
61 using iterator = const_iterator;
62
63 // special value equal to the maximum value representable by the type
64 // size_type.
65 LIBC_INLINE_VAR static constexpr size_t npos =
66 cpp::numeric_limits<size_t>::max();
67
68 LIBC_INLINE constexpr string_view() : Data(nullptr), Len(0) {}
69
70 // Assumes Str is a null-terminated string. The length of the string does
71 // not include the terminating null character.
72 // Preconditions: [Str, Str + ​length(Str)) is a valid range.
73 LIBC_INLINE constexpr string_view(const char *Str)
74 : Data(Str), Len(length(Str)) {}
75
76 // Preconditions: [Str, Str + N) is a valid range.
77 LIBC_INLINE constexpr string_view(const char *Str, size_t N)
78 : Data(Str), Len(N) {}
79
80 LIBC_INLINE constexpr const char *data() const { return Data; }
81
82 // Returns the size of the string_view.
83 LIBC_INLINE constexpr size_t size() const { return Len; }
84
85 // Returns whether the string_view is empty.
86 LIBC_INLINE constexpr bool empty() const { return Len == 0; }
87
88 // Returns an iterator to the first character of the view.
89 LIBC_INLINE const char *begin() const { return Data; }
90
91 // Returns an iterator to the character following the last character of the
92 // view.
93 LIBC_INLINE const char *end() const { return Data + Len; }
94
95 // Returns a const reference to the character at specified location pos.
96 // No bounds checking is performed: the behavior is undefined if pos >=
97 // size().
98 LIBC_INLINE constexpr const char &operator[](size_t Index) const {
99 return Data[Index];
100 }
101
102 /// compare - Compare two strings; the result is -1, 0, or 1 if this string
103 /// is lexicographically less than, equal to, or greater than the \p Other.
104 LIBC_INLINE int compare(string_view Other) const {
105 // Check the prefix for a mismatch.
106 if (int Res = compareMemory(Data, Other.Data, min(Len, Other.Len)))
107 return Res < 0 ? -1 : 1;
108 // Otherwise the prefixes match, so we only need to check the lengths.
109 if (Len == Other.Len)
110 return 0;
111 return Len < Other.Len ? -1 : 1;
112 }
113
114 LIBC_INLINE bool operator==(string_view Other) const { return equals(Other); }
115 LIBC_INLINE bool operator!=(string_view Other) const {
116 return !(*this == Other);
117 }
118 LIBC_INLINE bool operator<(string_view Other) const {
119 return compare(Other) == -1;
120 }
121 LIBC_INLINE bool operator<=(string_view Other) const {
122 return compare(Other) != 1;
123 }
124 LIBC_INLINE bool operator>(string_view Other) const {
125 return compare(Other) == 1;
126 }
127 LIBC_INLINE bool operator>=(string_view Other) const {
128 return compare(Other) != -1;
129 }
130
131 // Moves the start of the view forward by n characters.
132 // The behavior is undefined if n > size().
133 LIBC_INLINE void remove_prefix(size_t N) {
134 Len -= N;
135 Data += N;
136 }
137
138 // Moves the end of the view back by n characters.
139 // The behavior is undefined if n > size().
140 LIBC_INLINE void remove_suffix(size_t N) { Len -= N; }
141
142 // Check if this string starts with the given Prefix.
143 LIBC_INLINE bool starts_with(string_view Prefix) const {
144 return Len >= Prefix.Len &&
145 compareMemory(Data, Prefix.Data, Prefix.Len) == 0;
146 }
147
148 // Check if this string starts with the given Prefix.
149 LIBC_INLINE bool starts_with(const char Prefix) const {
150 return !empty() && front() == Prefix;
151 }
152
153 // Check if this string ends with the given Prefix.
154 LIBC_INLINE bool ends_with(const char Suffix) const {
155 return !empty() && back() == Suffix;
156 }
157
158 // Check if this string ends with the given Suffix.
159 LIBC_INLINE bool ends_with(string_view Suffix) const {
160 return Len >= Suffix.Len &&
161 compareMemory(end() - Suffix.Len, Suffix.Data, Suffix.Len) == 0;
162 }
163
164 // Return a reference to the substring from [Start, Start + N).
165 //
166 // Start The index of the starting character in the substring; if the index is
167 // npos or greater than the length of the string then the empty substring will
168 // be returned.
169 //
170 // N The number of characters to included in the substring. If N exceeds the
171 // number of characters remaining in the string, the string suffix (starting
172 // with Start) will be returned.
173 LIBC_INLINE string_view substr(size_t Start, size_t N = npos) const {
174 Start = min(Start, Len);
175 return string_view(Data + Start, min(N, Len - Start));
176 }
177
178 // front - Get the first character in the string.
179 LIBC_INLINE char front() const { return Data[0]; }
180
181 // back - Get the last character in the string.
182 LIBC_INLINE char back() const { return Data[Len - 1]; }
183
184 // Finds the first occurence of c in this view, starting at position From.
185 LIBC_INLINE constexpr size_t find_first_of(const char c,
186 size_t From = 0) const {
187 for (size_t Pos = From; Pos < size(); ++Pos)
188 if ((*this)[Pos] == c)
189 return Pos;
190 return npos;
191 }
192
193 // Finds the last occurence of c in this view, ending at position End.
194 LIBC_INLINE constexpr size_t find_last_of(const char c,
195 size_t End = npos) const {
196 End = End >= size() ? size() : End + 1;
197 for (; End > 0; --End)
198 if ((*this)[End - 1] == c)
199 return End - 1;
200 return npos;
201 }
202
203 // Finds the first character not equal to c in this view, starting at position
204 // From.
205 LIBC_INLINE constexpr size_t find_first_not_of(const char c,
206 size_t From = 0) const {
207 for (size_t Pos = From; Pos < size(); ++Pos)
208 if ((*this)[Pos] != c)
209 return Pos;
210 return npos;
211 }
212
213 // Check if this view contains the given character.
214 LIBC_INLINE constexpr bool contains(char c) const {
215 return find_first_of(c) != npos;
216 }
217};
218
219} // namespace cpp
220} // namespace LIBC_NAMESPACE_DECL
221
222#endif // LLVM_LIBC_SRC___SUPPORT_CPP_STRING_VIEW_H
223

Warning: This file is not a C or C++ file. It does not have highlighting.

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of libc/src/__support/CPP/string_view.h