Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
str.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <cstdint>
5#include <cstring>
6
7#include "gaia/cnt/darray.h"
8#include "gaia/core/span.h"
9
10namespace gaia {
11 namespace util {
13 struct str_view {
15 const char* m_data = nullptr;
17 uint32_t m_size = 0;
18
19 str_view() = default;
20
24 constexpr str_view(const char* data, uint32_t size): m_data(data), m_size(size) {}
25
29 template <size_t N>
30 constexpr str_view(const char (&lit)[N]): m_data(lit), m_size((uint32_t)(N - 1)) {
31 static_assert(N > 0);
32 }
33
36 GAIA_NODISCARD constexpr const char* data() const {
37 return m_data;
38 }
39
42 GAIA_NODISCARD constexpr uint32_t size() const {
43 return m_size;
44 }
45
48 GAIA_NODISCARD constexpr bool empty() const {
49 return m_size == 0;
50 }
51
56 GAIA_NODISCARD constexpr uint32_t find(str_view value, uint32_t pos = 0) const {
57 return find(value.data(), value.size(), pos);
58 }
59
65 GAIA_NODISCARD constexpr uint32_t find(const char* value, uint32_t len, uint32_t pos) const {
66 if (pos > m_size)
67 return BadIndex;
68 if (len == 0)
69 return pos;
70 if (len > m_size - pos)
71 return BadIndex;
72
73 for (uint32_t i = pos; i + len <= m_size; ++i) {
74 if (equal_bytes(m_data + i, value, len))
75 return i;
76 }
77 return BadIndex;
78 }
79
85 template <size_t N>
86 GAIA_NODISCARD constexpr uint32_t find(const char (&lit)[N], uint32_t pos = 0) const {
87 static_assert(N > 0);
88 return find(str_view(lit), pos);
89 }
90
95 GAIA_NODISCARD constexpr uint32_t find(char ch, uint32_t pos = 0) const {
96 if (pos >= m_size)
97 return BadIndex;
98 for (uint32_t i = pos; i < m_size; ++i) {
99 if (m_data[i] == ch)
100 return i;
101 }
102 return BadIndex;
103 }
104
109 GAIA_NODISCARD constexpr uint32_t find_first_of(str_view chars, uint32_t pos = 0) const {
110 if (pos >= m_size || chars.empty())
111 return BadIndex;
112 for (uint32_t i = pos; i < m_size; ++i) {
113 if (contains(chars, m_data[i]))
114 return i;
115 }
116 return BadIndex;
117 }
118
123 GAIA_NODISCARD constexpr uint32_t find_first_of(char ch, uint32_t pos = 0) const {
124 return find(ch, pos);
125 }
126
132 template <size_t N>
133 GAIA_NODISCARD constexpr uint32_t find_first_of(const char (&lit)[N], uint32_t pos = 0) const {
134 return find_first_of(str_view(lit), pos);
135 }
136
141 GAIA_NODISCARD constexpr uint32_t find_last_of(str_view chars, uint32_t pos = BadIndex) const {
142 if (m_size == 0 || chars.empty())
143 return BadIndex;
144
145 uint32_t i = pos;
146 if (i == BadIndex || i >= m_size)
147 i = m_size - 1;
148
149 for (;;) {
150 if (contains(chars, m_data[i]))
151 return i;
152 if (i == 0)
153 break;
154 --i;
155 }
156 return BadIndex;
157 }
158
163 GAIA_NODISCARD constexpr uint32_t find_last_of(char ch, uint32_t pos = BadIndex) const {
164 if (m_size == 0)
165 return BadIndex;
166
167 uint32_t i = pos;
168 if (i == BadIndex || i >= m_size)
169 i = m_size - 1;
170
171 for (;;) {
172 if (m_data[i] == ch)
173 return i;
174 if (i == 0)
175 break;
176 --i;
177 }
178 return BadIndex;
179 }
180
186 template <size_t N>
187 GAIA_NODISCARD constexpr uint32_t find_last_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
188 return find_last_of(str_view(lit), pos);
189 }
190
195 GAIA_NODISCARD constexpr uint32_t find_first_not_of(str_view chars, uint32_t pos = 0) const {
196 if (pos >= m_size)
197 return BadIndex;
198 if (chars.empty())
199 return pos;
200
201 for (uint32_t i = pos; i < m_size; ++i) {
202 if (!contains(chars, m_data[i]))
203 return i;
204 }
205 return BadIndex;
206 }
207
212 GAIA_NODISCARD constexpr uint32_t find_first_not_of(char ch, uint32_t pos = 0) const {
213 if (pos >= m_size)
214 return BadIndex;
215 for (uint32_t i = pos; i < m_size; ++i) {
216 if (m_data[i] != ch)
217 return i;
218 }
219 return BadIndex;
220 }
221
227 template <size_t N>
228 GAIA_NODISCARD constexpr uint32_t find_first_not_of(const char (&lit)[N], uint32_t pos = 0) const {
229 return find_first_not_of(str_view(lit), pos);
230 }
231
236 GAIA_NODISCARD constexpr uint32_t find_last_not_of(str_view chars, uint32_t pos = BadIndex) const {
237 if (m_size == 0)
238 return BadIndex;
239
240 uint32_t i = pos;
241 if (i == BadIndex || i >= m_size)
242 i = m_size - 1;
243
244 if (chars.empty())
245 return i;
246
247 for (;;) {
248 if (!contains(chars, m_data[i]))
249 return i;
250 if (i == 0)
251 break;
252 --i;
253 }
254 return BadIndex;
255 }
256
261 GAIA_NODISCARD constexpr uint32_t find_last_not_of(char ch, uint32_t pos = BadIndex) const {
262 if (m_size == 0)
263 return BadIndex;
264
265 uint32_t i = pos;
266 if (i == BadIndex || i >= m_size)
267 i = m_size - 1;
268
269 for (;;) {
270 if (m_data[i] != ch)
271 return i;
272 if (i == 0)
273 break;
274 --i;
275 }
276 return BadIndex;
277 }
278
284 template <size_t N>
285 GAIA_NODISCARD constexpr uint32_t find_last_not_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
286 return find_last_not_of(str_view(lit), pos);
287 }
288
293 template <size_t N>
294 GAIA_NODISCARD constexpr bool operator==(const char (&lit)[N]) const {
295 static_assert(N > 0);
296 return m_size == (uint32_t)(N - 1) && equal_bytes(m_data, lit, m_size);
297 }
298
302 GAIA_NODISCARD constexpr bool operator==(str_view other) const {
303 return m_size == other.m_size && equal_bytes(m_data, other.m_data, m_size);
304 }
305
309 GAIA_NODISCARD constexpr bool operator!=(str_view other) const {
310 return !operator==(other);
311 }
312
313 private:
314 GAIA_NODISCARD static constexpr bool contains(str_view set, char value) {
315 for (uint32_t i = 0; i < set.m_size; ++i) {
316 if (set.m_data[i] == value)
317 return true;
318 }
319 return false;
320 }
321
322 GAIA_NODISCARD static constexpr bool equal_bytes(const char* left, const char* right, uint32_t size) {
323 for (uint32_t i = 0; i < size; ++i) {
324 if (left[i] != right[i])
325 return false;
326 }
327 return true;
328 }
329 };
330
332 struct str {
335
336 str() = default;
337
340 explicit str(str_view view) {
341 assign(view);
342 }
343
347 template <size_t N>
348 explicit str(const char (&lit)[N]) {
349 assign(lit);
350 }
351
353 void clear() {
354 m_data.clear();
355 }
356
359 void reserve(uint32_t len) {
360 m_data.reserve(len);
361 }
362
366 void assign(const char* data, uint32_t size) {
368 if (size > 0)
369 memcpy(m_data.data(), data, size);
370 }
371
375 assign(view.data(), view.size());
376 }
377
381 template <size_t N>
382 void assign(const char (&lit)[N]) {
383 static_assert(N > 0);
384 assign(lit, (uint32_t)(N - 1));
385 }
386
390 void append(const char* data, uint32_t size) {
391 const auto oldSize = this->size();
392 m_data.resize(oldSize + size);
393 if (size > 0)
394 memcpy(m_data.data() + oldSize, data, size);
395 }
396
400 append(view.data(), view.size());
401 }
402
406 template <size_t N>
407 void append(const char (&lit)[N]) {
408 static_assert(N > 0);
409 append(lit, (uint32_t)(N - 1));
410 }
411
414 void append(char ch) {
415 m_data.push_back(ch);
416 }
417
420 GAIA_NODISCARD const char* data() const {
421 return m_data.data();
422 }
423
426 GAIA_NODISCARD char* data() {
427 return m_data.data();
428 }
429
432 GAIA_NODISCARD uint32_t size() const {
433 return (uint32_t)m_data.size();
434 }
435
438 GAIA_NODISCARD bool empty() const {
439 return m_data.empty();
440 }
441
444 GAIA_NODISCARD str_view view() const {
445 return str_view(data(), size());
446 }
447
450 GAIA_NODISCARD operator str_view() const {
451 return view();
452 }
453
458 template <size_t N>
459 GAIA_NODISCARD bool operator==(const char (&lit)[N]) const {
460 static_assert(N > 0);
461 const auto len = (uint32_t)(N - 1);
462 return size() == len && (len == 0 || memcmp(data(), lit, len) == 0);
463 }
464
468 GAIA_NODISCARD bool operator==(str_view other) const {
469 return size() == other.size() && (size() == 0 || memcmp(data(), other.data(), size()) == 0);
470 }
471
475 GAIA_NODISCARD bool operator==(const str& other) const {
476 return operator==(other.view());
477 }
478
483 GAIA_NODISCARD uint32_t find(str_view value, uint32_t pos = 0) const {
484 return view().find(value, pos);
485 }
486
492 GAIA_NODISCARD uint32_t find(const char* value, uint32_t len, uint32_t pos) const {
493 return view().find(value, len, pos);
494 }
495
501 template <size_t N>
502 GAIA_NODISCARD uint32_t find(const char (&lit)[N], uint32_t pos = 0) const {
503 static_assert(N > 0);
504 return find(str_view(lit), pos);
505 }
506
511 GAIA_NODISCARD uint32_t find(char ch, uint32_t pos = 0) const {
512 return view().find(ch, pos);
513 }
514
519 GAIA_NODISCARD uint32_t find_first_of(str_view chars, uint32_t pos = 0) const {
520 return view().find_first_of(chars, pos);
521 }
522
527 GAIA_NODISCARD uint32_t find_first_of(char ch, uint32_t pos = 0) const {
528 return view().find_first_of(ch, pos);
529 }
530
536 template <size_t N>
537 GAIA_NODISCARD uint32_t find_first_of(const char (&lit)[N], uint32_t pos = 0) const {
538 return view().find_first_of(lit, pos);
539 }
540
545 GAIA_NODISCARD uint32_t find_last_of(str_view chars, uint32_t pos = BadIndex) const {
546 return view().find_last_of(chars, pos);
547 }
548
553 GAIA_NODISCARD uint32_t find_last_of(char ch, uint32_t pos = BadIndex) const {
554 return view().find_last_of(ch, pos);
555 }
556
562 template <size_t N>
563 GAIA_NODISCARD uint32_t find_last_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
564 return view().find_last_of(lit, pos);
565 }
566
571 GAIA_NODISCARD uint32_t find_first_not_of(str_view chars, uint32_t pos = 0) const {
572 return view().find_first_not_of(chars, pos);
573 }
574
579 GAIA_NODISCARD uint32_t find_first_not_of(char ch, uint32_t pos = 0) const {
580 return view().find_first_not_of(ch, pos);
581 }
582
588 template <size_t N>
589 GAIA_NODISCARD uint32_t find_first_not_of(const char (&lit)[N], uint32_t pos = 0) const {
590 return view().find_first_not_of(lit, pos);
591 }
592
597 GAIA_NODISCARD uint32_t find_last_not_of(str_view chars, uint32_t pos = BadIndex) const {
598 return view().find_last_not_of(chars, pos);
599 }
600
605 GAIA_NODISCARD uint32_t find_last_not_of(char ch, uint32_t pos = BadIndex) const {
606 return view().find_last_not_of(ch, pos);
607 }
608
614 template <size_t N>
615 GAIA_NODISCARD uint32_t find_last_not_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
616 return view().find_last_not_of(lit, pos);
617 }
618 };
619
623 GAIA_NODISCARD constexpr bool is_whitespace(char c) {
624 return c == ' ' || (c >= '\t' && c <= '\r');
625 }
626
630 GAIA_NODISCARD constexpr str_view trim(str_view expr) {
631 const auto len = expr.size();
632 if (len == 0)
633 return {};
634
635 uint32_t beg = 0;
636 while (beg < len && is_whitespace(expr.data()[beg]))
637 ++beg;
638 if (beg == len)
639 return {};
640
641 uint32_t end = len - 1;
642 while (end > beg && is_whitespace(expr.data()[end]))
643 --end;
644 return str_view(expr.data() + beg, end - beg + 1);
645 }
646
650 GAIA_NODISCARD constexpr std::span<const char> trim(std::span<const char> expr) {
651 const auto trimmed = trim(str_view(expr.data(), (uint32_t)expr.size()));
652 return std::span<const char>(trimmed.data(), trimmed.size());
653 }
654 } // namespace util
655} // namespace gaia
Array with variable size of elements of type.
Definition darray_impl.h:27
void reserve(size_type cap)
Ensures storage for at least the requested number of elements.
Definition darray_impl.h:223
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_impl.h:504
void clear() noexcept
Removes all elements.
Definition darray_impl.h:449
void resize(size_type count)
Changes the number of elements.
Definition darray_impl.h:240
GAIA_NODISCARD bool empty() const noexcept
Checks whether the container has no elements.
Definition darray_impl.h:510
GAIA_NODISCARD pointer data() noexcept
Returns a pointer to the element storage.
Definition darray_impl.h:193
void push_back(const T &arg)
Appends an element.
Definition darray_impl.h:309
Lightweight non-owning string view over a character sequence.
Definition str.h:13
GAIA_NODISCARD constexpr uint32_t find_last_of(const char(&lit)[N], uint32_t pos=BadIndex) const
Finds the last character that is present in literal set lit.
Definition str.h:187
GAIA_NODISCARD constexpr uint32_t find_first_of(char ch, uint32_t pos=0) const
Finds the first occurrence of character ch.
Definition str.h:123
GAIA_NODISCARD constexpr uint32_t size() const
Returns the number of characters in the view.
Definition str.h:42
GAIA_NODISCARD constexpr bool operator==(const char(&lit)[N]) const
Compares this view with literal lit for exact byte equality.
Definition str.h:294
constexpr str_view(const char *data, uint32_t size)
Constructs a string view from a pointer and an explicit length.
Definition str.h:24
GAIA_NODISCARD constexpr bool operator==(str_view other) const
Compares this view with view other for exact byte equality.
Definition str.h:302
GAIA_NODISCARD constexpr uint32_t find(char ch, uint32_t pos=0) const
Finds the first occurrence of character ch starting at index pos.
Definition str.h:95
GAIA_NODISCARD constexpr uint32_t find_last_not_of(const char(&lit)[N], uint32_t pos=BadIndex) const
Finds the last character that is NOT present in literal set lit.
Definition str.h:285
GAIA_NODISCARD constexpr bool empty() const
Checks whether the view contains no characters.
Definition str.h:48
GAIA_NODISCARD constexpr uint32_t find_last_of(str_view chars, uint32_t pos=BadIndex) const
Finds the last character that is present in set chars.
Definition str.h:141
uint32_t m_size
Number of characters in the view.
Definition str.h:17
GAIA_NODISCARD constexpr uint32_t find_first_not_of(str_view chars, uint32_t pos=0) const
Finds the first character that is NOT present in set chars.
Definition str.h:195
GAIA_NODISCARD constexpr uint32_t find_last_not_of(str_view chars, uint32_t pos=BadIndex) const
Finds the last character that is NOT present in set chars.
Definition str.h:236
const char * m_data
Pointer to the first character in the view.
Definition str.h:15
GAIA_NODISCARD constexpr uint32_t find_first_of(str_view chars, uint32_t pos=0) const
Finds the first character that is present in set chars.
Definition str.h:109
GAIA_NODISCARD constexpr uint32_t find_last_not_of(char ch, uint32_t pos=BadIndex) const
Finds the last character that is different from ch.
Definition str.h:261
GAIA_NODISCARD constexpr uint32_t find_first_of(const char(&lit)[N], uint32_t pos=0) const
Finds the first character that is present in literal set lit.
Definition str.h:133
GAIA_NODISCARD constexpr uint32_t find_last_of(char ch, uint32_t pos=BadIndex) const
Finds the last occurrence of character ch.
Definition str.h:163
constexpr str_view(const char(&lit)[N])
Constructs a string view from a literal, excluding its trailing null terminator.
Definition str.h:30
GAIA_NODISCARD constexpr uint32_t find(const char(&lit)[N], uint32_t pos=0) const
Finds the first occurrence of literal lit starting at index pos.
Definition str.h:86
GAIA_NODISCARD constexpr uint32_t find(const char *value, uint32_t len, uint32_t pos) const
Finds the first occurrence of a character sequence starting at index pos.
Definition str.h:65
GAIA_NODISCARD constexpr bool operator!=(str_view other) const
Compares this view with view other for exact byte inequality.
Definition str.h:309
GAIA_NODISCARD constexpr uint32_t find_first_not_of(const char(&lit)[N], uint32_t pos=0) const
Finds the first character that is NOT present in literal set lit.
Definition str.h:228
GAIA_NODISCARD constexpr const char * data() const
Returns the underlying character pointer.
Definition str.h:36
GAIA_NODISCARD constexpr uint32_t find(str_view value, uint32_t pos=0) const
Finds the first occurrence of substring value starting at index pos.
Definition str.h:56
GAIA_NODISCARD constexpr uint32_t find_first_not_of(char ch, uint32_t pos=0) const
Finds the first character that is different from ch.
Definition str.h:212
Lightweight owning string container with explicit length semantics (no implicit null terminator).
Definition str.h:332
void append(str_view view)
Appends view contents.
Definition str.h:399
GAIA_NODISCARD uint32_t size() const
Returns number of characters stored in the string.
Definition str.h:432
GAIA_NODISCARD uint32_t find(str_view value, uint32_t pos=0) const
Finds the first occurrence of substring value starting at index pos.
Definition str.h:483
GAIA_NODISCARD uint32_t find(char ch, uint32_t pos=0) const
Finds the first occurrence of character ch starting at index pos.
Definition str.h:511
GAIA_NODISCARD char * data()
Returns mutable pointer to internal data.
Definition str.h:426
cnt::darray< char > m_data
Contiguous owned character storage.
Definition str.h:334
GAIA_NODISCARD uint32_t find_first_not_of(const char(&lit)[N], uint32_t pos=0) const
Finds the first character that is NOT present in literal set lit.
Definition str.h:589
GAIA_NODISCARD bool operator==(const char(&lit)[N]) const
Compares this string with literal lit for exact byte equality.
Definition str.h:459
GAIA_NODISCARD uint32_t find_first_of(str_view chars, uint32_t pos=0) const
Finds the first character that is present in set chars.
Definition str.h:519
GAIA_NODISCARD uint32_t find_last_of(str_view chars, uint32_t pos=BadIndex) const
Finds the last character that is present in set chars.
Definition str.h:545
GAIA_NODISCARD uint32_t find_first_not_of(str_view chars, uint32_t pos=0) const
Finds the first character that is NOT present in set chars.
Definition str.h:571
GAIA_NODISCARD uint32_t find_first_not_of(char ch, uint32_t pos=0) const
Finds the first character that is different from ch.
Definition str.h:579
void assign(const char(&lit)[N])
Replaces contents with literal lit.
Definition str.h:382
void append(const char *data, uint32_t size)
Appends size characters from data.
Definition str.h:390
void append(const char(&lit)[N])
Appends literal lit.
Definition str.h:407
GAIA_NODISCARD bool operator==(const str &other) const
Compares this string with string other for exact byte equality.
Definition str.h:475
void clear()
Removes all characters from the string.
Definition str.h:353
GAIA_NODISCARD bool empty() const
Checks whether the string contains no characters.
Definition str.h:438
GAIA_NODISCARD uint32_t find(const char *value, uint32_t len, uint32_t pos) const
Finds the first occurrence of a character sequence starting at index pos.
Definition str.h:492
str(str_view view)
Constructs a string by copying view contents.
Definition str.h:340
GAIA_NODISCARD str_view view() const
Returns a non-owning view over the current contents.
Definition str.h:444
void reserve(uint32_t len)
Reserves capacity for at least len characters.
Definition str.h:359
void assign(const char *data, uint32_t size)
Replaces contents with size characters from data.
Definition str.h:366
GAIA_NODISCARD uint32_t find(const char(&lit)[N], uint32_t pos=0) const
Finds the first occurrence of literal lit starting at index pos.
Definition str.h:502
GAIA_NODISCARD const char * data() const
Returns read-only pointer to internal data.
Definition str.h:420
GAIA_NODISCARD uint32_t find_last_not_of(const char(&lit)[N], uint32_t pos=BadIndex) const
Finds the last character that is NOT present in literal set lit.
Definition str.h:615
void assign(str_view view)
Replaces contents with view contents.
Definition str.h:374
GAIA_NODISCARD bool operator==(str_view other) const
Compares this string with view other for exact byte equality.
Definition str.h:468
GAIA_NODISCARD uint32_t find_last_of(const char(&lit)[N], uint32_t pos=BadIndex) const
Finds the last character that is present in literal set lit.
Definition str.h:563
GAIA_NODISCARD uint32_t find_last_not_of(str_view chars, uint32_t pos=BadIndex) const
Finds the last character that is NOT present in set chars.
Definition str.h:597
GAIA_NODISCARD uint32_t find_first_of(char ch, uint32_t pos=0) const
Finds the first occurrence of character ch.
Definition str.h:527
str(const char(&lit)[N])
Constructs a string from literal lit, excluding trailing null terminator.
Definition str.h:348
void append(char ch)
Appends a single character.
Definition str.h:414
GAIA_NODISCARD uint32_t find_first_of(const char(&lit)[N], uint32_t pos=0) const
Finds the first character that is present in literal set lit.
Definition str.h:537
GAIA_NODISCARD uint32_t find_last_not_of(char ch, uint32_t pos=BadIndex) const
Finds the last character that is different from ch.
Definition str.h:605
GAIA_NODISCARD uint32_t find_last_of(char ch, uint32_t pos=BadIndex) const
Finds the last occurrence of character ch.
Definition str.h:553