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
391 void append(const char* data, uint32_t size) {
392 const auto oldSize = this->size();
393 // The length is 32-bit. A wrapping sum would shrink the buffer right before the copy.
394 GAIA_ASSERT(size <= (uint32_t)-1 - oldSize);
395 if (size == 0 || size > (uint32_t)-1 - oldSize)
396 return;
397
398 m_data.resize(oldSize + size, cnt::ResizePolicy::Scale);
399 memcpy(m_data.data() + oldSize, data, size);
400 }
401
405 append(view.data(), view.size());
406 }
407
411 template <size_t N>
412 void append(const char (&lit)[N]) {
413 static_assert(N > 0);
414 append(lit, (uint32_t)(N - 1));
415 }
416
419 void append(char ch) {
420 m_data.push_back(ch);
421 }
422
425 GAIA_NODISCARD const char* data() const {
426 return m_data.data();
427 }
428
431 GAIA_NODISCARD char* data() {
432 return m_data.data();
433 }
434
437 GAIA_NODISCARD uint32_t size() const {
438 return (uint32_t)m_data.size();
439 }
440
443 GAIA_NODISCARD bool empty() const {
444 return m_data.empty();
445 }
446
449 GAIA_NODISCARD str_view view() const {
450 return str_view(data(), size());
451 }
452
455 GAIA_NODISCARD operator str_view() const {
456 return view();
457 }
458
463 template <size_t N>
464 GAIA_NODISCARD bool operator==(const char (&lit)[N]) const {
465 static_assert(N > 0);
466 const auto len = (uint32_t)(N - 1);
467 return size() == len && (len == 0 || memcmp(data(), lit, len) == 0);
468 }
469
473 GAIA_NODISCARD bool operator==(str_view other) const {
474 return size() == other.size() && (size() == 0 || memcmp(data(), other.data(), size()) == 0);
475 }
476
480 GAIA_NODISCARD bool operator==(const str& other) const {
481 return operator==(other.view());
482 }
483
488 GAIA_NODISCARD uint32_t find(str_view value, uint32_t pos = 0) const {
489 return view().find(value, pos);
490 }
491
497 GAIA_NODISCARD uint32_t find(const char* value, uint32_t len, uint32_t pos) const {
498 return view().find(value, len, pos);
499 }
500
506 template <size_t N>
507 GAIA_NODISCARD uint32_t find(const char (&lit)[N], uint32_t pos = 0) const {
508 static_assert(N > 0);
509 return find(str_view(lit), pos);
510 }
511
516 GAIA_NODISCARD uint32_t find(char ch, uint32_t pos = 0) const {
517 return view().find(ch, pos);
518 }
519
524 GAIA_NODISCARD uint32_t find_first_of(str_view chars, uint32_t pos = 0) const {
525 return view().find_first_of(chars, pos);
526 }
527
532 GAIA_NODISCARD uint32_t find_first_of(char ch, uint32_t pos = 0) const {
533 return view().find_first_of(ch, pos);
534 }
535
541 template <size_t N>
542 GAIA_NODISCARD uint32_t find_first_of(const char (&lit)[N], uint32_t pos = 0) const {
543 return view().find_first_of(lit, pos);
544 }
545
550 GAIA_NODISCARD uint32_t find_last_of(str_view chars, uint32_t pos = BadIndex) const {
551 return view().find_last_of(chars, pos);
552 }
553
558 GAIA_NODISCARD uint32_t find_last_of(char ch, uint32_t pos = BadIndex) const {
559 return view().find_last_of(ch, pos);
560 }
561
567 template <size_t N>
568 GAIA_NODISCARD uint32_t find_last_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
569 return view().find_last_of(lit, pos);
570 }
571
576 GAIA_NODISCARD uint32_t find_first_not_of(str_view chars, uint32_t pos = 0) const {
577 return view().find_first_not_of(chars, pos);
578 }
579
584 GAIA_NODISCARD uint32_t find_first_not_of(char ch, uint32_t pos = 0) const {
585 return view().find_first_not_of(ch, pos);
586 }
587
593 template <size_t N>
594 GAIA_NODISCARD uint32_t find_first_not_of(const char (&lit)[N], uint32_t pos = 0) const {
595 return view().find_first_not_of(lit, pos);
596 }
597
602 GAIA_NODISCARD uint32_t find_last_not_of(str_view chars, uint32_t pos = BadIndex) const {
603 return view().find_last_not_of(chars, pos);
604 }
605
610 GAIA_NODISCARD uint32_t find_last_not_of(char ch, uint32_t pos = BadIndex) const {
611 return view().find_last_not_of(ch, pos);
612 }
613
619 template <size_t N>
620 GAIA_NODISCARD uint32_t find_last_not_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
621 return view().find_last_not_of(lit, pos);
622 }
623 };
624
628 GAIA_NODISCARD constexpr bool is_whitespace(char c) {
629 return c == ' ' || (c >= '\t' && c <= '\r');
630 }
631
635 GAIA_NODISCARD constexpr str_view trim(str_view expr) {
636 const auto len = expr.size();
637 if (len == 0)
638 return {};
639
640 uint32_t beg = 0;
641 while (beg < len && is_whitespace(expr.data()[beg]))
642 ++beg;
643 if (beg == len)
644 return {};
645
646 uint32_t end = len - 1;
647 while (end > beg && is_whitespace(expr.data()[end]))
648 --end;
649 return str_view(expr.data() + beg, end - beg + 1);
650 }
651
655 GAIA_NODISCARD constexpr std::span<const char> trim(std::span<const char> expr) {
656 const auto trimmed = trim(str_view(expr.data(), (uint32_t)expr.size()));
657 return std::span<const char>(trimmed.data(), trimmed.size());
658 }
659 } // namespace util
660} // namespace gaia
Array of elements of type.
Definition darray_ext_impl.h:31
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_ext_impl.h:561
void reserve(size_type cap)
Ensures storage for at least the requested number of elements.
Definition darray_ext_impl.h:266
void push_back(const T &arg)
Appends an element.
Definition darray_ext_impl.h:360
void resize(size_type count, ResizePolicy policy=ResizePolicy::Exact)
Changes the number of elements.
Definition darray_ext_impl.h:289
void clear() noexcept
Removes all elements.
Definition darray_ext_impl.h:518
GAIA_NODISCARD pointer data() noexcept
Returns a pointer to the element storage.
Definition darray_ext_impl.h:236
GAIA_NODISCARD bool empty() const noexcept
Checks whether the container has no elements.
Definition darray_ext_impl.h:567
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:404
GAIA_NODISCARD uint32_t size() const
Returns number of characters stored in the string.
Definition str.h:437
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:488
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:516
GAIA_NODISCARD char * data()
Returns mutable pointer to internal data.
Definition str.h:431
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:594
GAIA_NODISCARD bool operator==(const char(&lit)[N]) const
Compares this string with literal lit for exact byte equality.
Definition str.h:464
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:524
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:550
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:576
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:584
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. Appends that would push the length past 32 bits are rejected.
Definition str.h:391
void append(const char(&lit)[N])
Appends literal lit.
Definition str.h:412
GAIA_NODISCARD bool operator==(const str &other) const
Compares this string with string other for exact byte equality.
Definition str.h:480
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:443
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:497
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:449
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:507
GAIA_NODISCARD const char * data() const
Returns read-only pointer to internal data.
Definition str.h:425
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:620
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:473
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:568
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:602
GAIA_NODISCARD uint32_t find_first_of(char ch, uint32_t pos=0) const
Finds the first occurrence of character ch.
Definition str.h:532
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:419
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:542
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:610
GAIA_NODISCARD uint32_t find_last_of(char ch, uint32_t pos=BadIndex) const
Finds the last occurrence of character ch.
Definition str.h:558