fennec
Loading...
Searching...
No Matches
wcstring.h
1// =====================================================================================================================
2// fennec, a free and open source game engine
3// Copyright © 2025 Medusa Slockbower
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17// =====================================================================================================================
18
19#ifndef FENNEC_STRING_wcstring_H
20#define FENNEC_STRING_wcstring_H
21
22#include <fennec/string/detail/_ctype.h>
23#include <fennec/memory/detail/_string.h>
24
25#include <fennec/lang/assert.h>
26
27#include <fennec/math/common.h>
28
29namespace fennec
30{
31
32// TODO: Document
33
34using ::iswalnum;
35using ::iswalpha;
36using ::iswlower;
37using ::iswupper;
38using ::iswdigit;
39using ::iswxdigit;
40using ::iswcntrl;
41using ::iswgraph;
42using ::iswspace;
43using ::iswblank;
44using ::iswprint;
45using ::iswpunct;
46
47using ::towlower;
48using ::towupper;
49
50using ::towctrans;
51using ::wctrans;
52
60{
61public:
62 static constexpr size_t npos = -1;
63 using char_t = wchar_t;
64
65// Constructors ========================================================================================================
66
69 constexpr wcstring()
70 : _str(nullptr), _size(0), _const(true) {
71 }
72
76 : _str(nullptr), _size(0), _const(true) {
77 }
78
83 constexpr wcstring(wchar_t* str, size_t n)
84 : _str(str)
85 , _size(n - 1)
86 , _const(false) {
87 assert(_str[n - 1] == '\0', "Invalid NTBS.");
88 }
89
94 template<size_t n>
95 constexpr wcstring(wchar_t (&str)[n])
96 : _str(str)
97 , _size(n - 1)
98 , _const(false) {
99 assert(_str[n - 1] == '\0', "Invalid NTBS.");
100 }
101
106 constexpr wcstring(const wchar_t* str, size_t n)
107 : _cstr(str)
108 , _size(n - 1)
109 , _const(true) {
110 assert(_cstr[n - 1] == '\0', "Invalid NTBS.");
111 }
112
117 template<size_t n>
118 constexpr wcstring(const wchar_t (&str)[n])
119 : _cstr(str)
120 , _size(n - 1)
121 , _const(true) {
122 assert(_cstr[n - 1] == '\0', "Invalid NTBS.");
123 }
124
128 constexpr wcstring(wcstring&& str) noexcept
129 : _cstr(str._cstr)
130 , _size(str._size)
131 , _const(str._const) {
132 str._cstr = nullptr;
133 str._size = 0;
134 str._const = true;
135 }
136
137 // TODO: Document
138 constexpr wcstring(const wcstring&) = delete;
139 constexpr ~wcstring() = default;
140
141 constexpr wcstring& operator=(nullptr_t) {
142 _str = nullptr, _size = 0, _const = true;
143 return *this;
144 }
145
146 // TODO: Document
147 template<size_t n>
148 constexpr wcstring& operator=(wchar_t(&str)[n]) {
149 assert(_str[n - 1] == '\0', "Invalid NTBS.");
150 _str = str, _size = n - 1, _const = false;
151 return *this;
152 }
153
154 // TODO: Document
155 template<size_t n>
156 constexpr wcstring& operator=(const wchar_t(&str)[n]) {
157 assert(str[n - 1] == '\0', "Invalid NTBS.");
158 _cstr = str; _size = n - 1; _const = true;
159 return *this;
160 }
161
162 // TODO: Document
163 constexpr wcstring& operator=(wcstring&& str) noexcept {
164 _cstr = str._cstr; str._cstr = nullptr;
165 _size = str._size; str._size = 0;
166 _const = str._const; str._const = true;
167 return *this;
168 }
169
170
171// Properties ==========================================================================================================
172
175 constexpr size_t size() const { return _size; }
176
179 constexpr size_t capacity() const { return _size + 1; }
180
181 constexpr bool empty() const {
182 return _cstr == nullptr || _size == 0;
183 }
184
185
186// Access ==============================================================================================================
187
192 constexpr wchar_t& operator[](size_t i) {
193 assertd(not _const, "Attempted to Access Const-Qualified Memory as Non-Const");
194 assertd(i < size(), "Array Out of Bounds");
195 return _str[i];
196 }
197
202 constexpr const wchar_t& operator[](size_t i) const {
203 assertd(i < size(), "Array Out of Bounds");
204 return _cstr[i];
205 }
206
210 constexpr wchar_t* data() {
211 return _str;
212 }
213
217 constexpr const wchar_t* data() const {
218 return _cstr;
219 }
220
223 constexpr operator const wchar_t*() const {
224 return _cstr;
225 }
226
227
228// Examination =========================================================================================================
229
232 constexpr size_t length() const {
233 return find('\0');
234 }
235
243 constexpr int compare(const wcstring& str, size_t i = 0, size_t n = npos) const {
244 if (i >= _size) {
245 return -1;
246 }
247
248 n = min(n, max(_size, str._size) + 1);
249 return ::wcsncmp(_cstr + i, str, n);
250 }
251
256 template<size_t n>
257 constexpr bool operator==(const wchar_t (&str)[n]) const {
258 return compare(wcstring(str)) == 0;
259 }
260
265 constexpr bool operator==(const wcstring& str) const {
266 return compare(str) == 0;
267 }
268
274 constexpr size_t find(wchar_t c, size_t i = 0) const {
275 if (i >= _size) { // bounds check
276 return _size;
277 }
278
279 const wchar_t* loc = ::wcschr(_cstr + i, c); // get location using strchr
280 return loc ? loc - _cstr : _size; // return size if not found
281 }
282
288 constexpr size_t find(const wcstring& str, size_t i = 0) const {
289 if (i + str._size > _size) { // bounds check
290 return _size;
291 }
292
293 const wchar_t* loc = ::wcsstr(_cstr + i, str); // get location using strstr
294 return loc ? loc - _cstr : _size; // return size if not found
295 }
296
302 constexpr size_t rfind(char c, size_t i = npos) const {
303 if (_size == 0) {
304 return _size;
305 }
306
307 i = min(i, _size - 1); // clamp i to bounds
308 do {
309 if (_cstr[i] == c) return i; // loop backwards looking for c
310 } while (i--);
311 return _size; // base case
312 }
313
319 constexpr size_t rfind(const wcstring& str, size_t i = npos) const {
320 if (_size == 0) {
321 return _size;
322 }
323
324 const char first = str[0];
325 i = min(i, _size - str._size);
326 do {
327 if(_cstr[i] == first) {
328 if (compare(str, i, str._size - 1) == 0) {
329 return i;
330 }
331 } // loop backwards looking for str
332 } while (i--);
333 return _size; // base case
334 }
335
336private:
337 union { // hack to allow both const qualified and non-const strings
338 wchar_t* _str;
339 const wchar_t* _cstr;
340 };
341 size_t _size;
342 bool _const;
343};
344
345template<>
346struct hash<wcstring> : hash<byte_array> {
347 constexpr size_t operator()(const wcstring& str) const {
348 return hash<byte_array>::operator()(byte_array(str, str.size()));
349 }
350};
351
352}
353
354#endif // FENNEC_STRING_wcstring_H
Assertions
Common
constexpr genType min(genType x, genType y)
Returns if otherwise it returns .
Definition common.h:688
constexpr genType max(genType x, genType y)
Returns if , otherwise it returns .
Definition common.h:705
This struct wraps c-style strings.
Definition wcstring.h:60
constexpr size_t rfind(const wcstring &str, size_t i=npos) const
Finds the index of the last occurrence of str in the string.
Definition wcstring.h:319
constexpr wcstring(wchar_t *str, size_t n)
Buffer Constructor, wraps the provided C-Style string.
Definition wcstring.h:83
constexpr bool operator==(const wchar_t(&str)[n]) const
String Equality.
Definition wcstring.h:257
constexpr size_t capacity() const
Definition wcstring.h:179
constexpr wcstring()
Default Constructor, initializes with nullptr.
Definition wcstring.h:69
constexpr wcstring(const wchar_t *str, size_t n)
Const Buffer Constructor, wraps the provided C-Style string.
Definition wcstring.h:106
constexpr bool operator==(const wcstring &str) const
String Equality.
Definition wcstring.h:265
constexpr const wchar_t * data() const
Data Access.
Definition wcstring.h:217
constexpr wcstring(const wchar_t(&str)[n])
Buffer Constructor, wraps the provided C-Style string.
Definition wcstring.h:118
constexpr size_t find(wchar_t c, size_t i=0) const
Finds the index of the first occurrence of c in the string.
Definition wcstring.h:274
constexpr wcstring(wchar_t(&str)[n])
Buffer Constructor, wraps the provided C-Style string.
Definition wcstring.h:95
constexpr size_t find(const wcstring &str, size_t i=0) const
Finds the index of the first occurrence of str in the string.
Definition wcstring.h:288
constexpr wcstring(wcstring &&str) noexcept
Move Constructor.
Definition wcstring.h:128
constexpr size_t size() const
Definition wcstring.h:175
constexpr wchar_t * data()
Data Access.
Definition wcstring.h:210
constexpr int compare(const wcstring &str, size_t i=0, size_t n=npos) const
String Comparison.
Definition wcstring.h:243
constexpr const wchar_t & operator[](size_t i) const
Const-Array Access Operator.
Definition wcstring.h:202
constexpr wcstring(nullptr_t)
Default Constructor, initializes with nullptr.
Definition wcstring.h:75
constexpr size_t length() const
Definition wcstring.h:232
constexpr wchar_t & operator[](size_t i)
Array Access Operator.
Definition wcstring.h:192
constexpr size_t rfind(char c, size_t i=npos) const
Finds the index of the last occurrence of c in the string.
Definition wcstring.h:302
decltype(nullptr) nullptr_t
Null Pointer Type.
Definition types.h:245