Gaia-ECS v0.9.3
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 {
14 const char* m_data = nullptr;
15 uint32_t m_size = 0;
16
18 str_view() = default;
19
23 constexpr str_view(const char* data, uint32_t size): m_data(data), m_size(size) {}
24
28 template <size_t N>
29 constexpr str_view(const char (&lit)[N]): m_data(lit), m_size((uint32_t)(N - 1)) {
30 static_assert(N > 0);
31 }
32
35 GAIA_NODISCARD constexpr const char* data() const {
36 return m_data;
37 }
38
41 GAIA_NODISCARD constexpr uint32_t size() const {
42 return m_size;
43 }
44
47 GAIA_NODISCARD constexpr bool empty() const {
48 return m_size == 0;
49 }
50
55 GAIA_NODISCARD constexpr uint32_t find(str_view value, uint32_t pos = 0) const {
56 return find(value.data(), value.size(), pos);
57 }
58
64 GAIA_NODISCARD constexpr uint32_t find(const char* value, uint32_t len, uint32_t pos) const {
65 if (pos > m_size)
66 return BadIndex;
67 if (len == 0)
68 return pos;
69 if (len > m_size - pos)
70 return BadIndex;
71
72 for (uint32_t i = pos; i + len <= m_size; ++i) {
73 if (equal_bytes(m_data + i, value, len))
74 return i;
75 }
76 return BadIndex;
77 }
78
84 template <size_t N>
85 GAIA_NODISCARD constexpr uint32_t find(const char (&lit)[N], uint32_t pos = 0) const {
86 static_assert(N > 0);
87 return find(str_view(lit), pos);
88 }
89
94 GAIA_NODISCARD constexpr uint32_t find(char ch, uint32_t pos = 0) const {
95 if (pos >= m_size)
96 return BadIndex;
97 for (uint32_t i = pos; i < m_size; ++i) {
98 if (m_data[i] == ch)
99 return i;
100 }
101 return BadIndex;
102 }
103
108 GAIA_NODISCARD constexpr uint32_t find_first_of(str_view chars, uint32_t pos = 0) const {
109 if (pos >= m_size || chars.empty())
110 return BadIndex;
111 for (uint32_t i = pos; i < m_size; ++i) {
112 if (contains(chars, m_data[i]))
113 return i;
114 }
115 return BadIndex;
116 }
117
122 GAIA_NODISCARD constexpr uint32_t find_first_of(char ch, uint32_t pos = 0) const {
123 return find(ch, pos);
124 }
125
131 template <size_t N>
132 GAIA_NODISCARD constexpr uint32_t find_first_of(const char (&lit)[N], uint32_t pos = 0) const {
133 return find_first_of(str_view(lit), pos);
134 }
135
140 GAIA_NODISCARD constexpr uint32_t find_last_of(str_view chars, uint32_t pos = BadIndex) const {
141 if (m_size == 0 || chars.empty())
142 return BadIndex;
143
144 uint32_t i = pos;
145 if (i == BadIndex || i >= m_size)
146 i = m_size - 1;
147
148 for (;;) {
149 if (contains(chars, m_data[i]))
150 return i;
151 if (i == 0)
152 break;
153 --i;
154 }
155 return BadIndex;
156 }
157
162 GAIA_NODISCARD constexpr uint32_t find_last_of(char ch, uint32_t pos = BadIndex) const {
163 if (m_size == 0)
164 return BadIndex;
165
166 uint32_t i = pos;
167 if (i == BadIndex || i >= m_size)
168 i = m_size - 1;
169
170 for (;;) {
171 if (m_data[i] == ch)
172 return i;
173 if (i == 0)
174 break;
175 --i;
176 }
177 return BadIndex;
178 }
179
185 template <size_t N>
186 GAIA_NODISCARD constexpr uint32_t find_last_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
187 return find_last_of(str_view(lit), pos);
188 }
189
194 GAIA_NODISCARD constexpr uint32_t find_first_not_of(str_view chars, uint32_t pos = 0) const {
195 if (pos >= m_size)
196 return BadIndex;
197 if (chars.empty())
198 return pos;
199
200 for (uint32_t i = pos; i < m_size; ++i) {
201 if (!contains(chars, m_data[i]))
202 return i;
203 }
204 return BadIndex;
205 }
206
211 GAIA_NODISCARD constexpr uint32_t find_first_not_of(char ch, uint32_t pos = 0) const {
212 if (pos >= m_size)
213 return BadIndex;
214 for (uint32_t i = pos; i < m_size; ++i) {
215 if (m_data[i] != ch)
216 return i;
217 }
218 return BadIndex;
219 }
220
226 template <size_t N>
227 GAIA_NODISCARD constexpr uint32_t find_first_not_of(const char (&lit)[N], uint32_t pos = 0) const {
228 return find_first_not_of(str_view(lit), pos);
229 }
230
235 GAIA_NODISCARD constexpr uint32_t find_last_not_of(str_view chars, uint32_t pos = BadIndex) const {
236 if (m_size == 0)
237 return BadIndex;
238
239 uint32_t i = pos;
240 if (i == BadIndex || i >= m_size)
241 i = m_size - 1;
242
243 if (chars.empty())
244 return i;
245
246 for (;;) {
247 if (!contains(chars, m_data[i]))
248 return i;
249 if (i == 0)
250 break;
251 --i;
252 }
253 return BadIndex;
254 }
255
260 GAIA_NODISCARD constexpr uint32_t find_last_not_of(char ch, uint32_t pos = BadIndex) const {
261 if (m_size == 0)
262 return BadIndex;
263
264 uint32_t i = pos;
265 if (i == BadIndex || i >= m_size)
266 i = m_size - 1;
267
268 for (;;) {
269 if (m_data[i] != ch)
270 return i;
271 if (i == 0)
272 break;
273 --i;
274 }
275 return BadIndex;
276 }
277
283 template <size_t N>
284 GAIA_NODISCARD constexpr uint32_t find_last_not_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
285 return find_last_not_of(str_view(lit), pos);
286 }
287
292 template <size_t N>
293 GAIA_NODISCARD constexpr bool operator==(const char (&lit)[N]) const {
294 static_assert(N > 0);
295 return m_size == (uint32_t)(N - 1) && equal_bytes(m_data, lit, m_size);
296 }
297
301 GAIA_NODISCARD constexpr bool operator==(str_view other) const {
302 return m_size == other.m_size && equal_bytes(m_data, other.m_data, m_size);
303 }
304
308 GAIA_NODISCARD constexpr bool operator!=(str_view other) const {
309 return !operator==(other);
310 }
311
312 private:
313 GAIA_NODISCARD static constexpr bool contains(str_view set, char value) {
314 for (uint32_t i = 0; i < set.m_size; ++i) {
315 if (set.m_data[i] == value)
316 return true;
317 }
318 return false;
319 }
320
321 GAIA_NODISCARD static constexpr bool equal_bytes(const char* left, const char* right, uint32_t size) {
322 for (uint32_t i = 0; i < size; ++i) {
323 if (left[i] != right[i])
324 return false;
325 }
326 return true;
327 }
328 };
329
331 struct str {
332 cnt::darray<char> m_data;
333
335 str() = default;
336
339 explicit str(str_view view) {
340 assign(view);
341 }
342
346 template <size_t N>
347 explicit str(const char (&lit)[N]) {
348 assign(lit);
349 }
350
352 void clear() {
353 m_data.clear();
354 }
355
358 void reserve(uint32_t len) {
359 m_data.reserve(len);
360 }
361
365 void assign(const char* data, uint32_t size) {
366 m_data.resize(size);
367 if (size > 0)
368 memcpy(m_data.data(), data, size);
369 }
370
374 assign(view.data(), view.size());
375 }
376
380 template <size_t N>
381 void assign(const char (&lit)[N]) {
382 static_assert(N > 0);
383 assign(lit, (uint32_t)(N - 1));
384 }
385
389 void append(const char* data, uint32_t size) {
390 const auto oldSize = this->size();
391 m_data.resize(oldSize + size);
392 if (size > 0)
393 memcpy(m_data.data() + oldSize, data, size);
394 }
395
399 append(view.data(), view.size());
400 }
401
405 template <size_t N>
406 void append(const char (&lit)[N]) {
407 static_assert(N > 0);
408 append(lit, (uint32_t)(N - 1));
409 }
410
413 void append(char ch) {
414 m_data.push_back(ch);
415 }
416
419 GAIA_NODISCARD const char* data() const {
420 return m_data.data();
421 }
422
425 GAIA_NODISCARD char* data() {
426 return m_data.data();
427 }
428
431 GAIA_NODISCARD uint32_t size() const {
432 return (uint32_t)m_data.size();
433 }
434
437 GAIA_NODISCARD bool empty() const {
438 return m_data.empty();
439 }
440
443 GAIA_NODISCARD str_view view() const {
444 return str_view(data(), size());
445 }
446
449 GAIA_NODISCARD operator str_view() const {
450 return view();
451 }
452
457 template <size_t N>
458 GAIA_NODISCARD bool operator==(const char (&lit)[N]) const {
459 static_assert(N > 0);
460 const auto len = (uint32_t)(N - 1);
461 return size() == len && (len == 0 || memcmp(data(), lit, len) == 0);
462 }
463
467 GAIA_NODISCARD bool operator==(str_view other) const {
468 return size() == other.size() && (size() == 0 || memcmp(data(), other.data(), size()) == 0);
469 }
470
474 GAIA_NODISCARD bool operator==(const str& other) const {
475 return operator==(other.view());
476 }
477
482 GAIA_NODISCARD uint32_t find(str_view value, uint32_t pos = 0) const {
483 return view().find(value, pos);
484 }
485
491 GAIA_NODISCARD uint32_t find(const char* value, uint32_t len, uint32_t pos) const {
492 return view().find(value, len, pos);
493 }
494
500 template <size_t N>
501 GAIA_NODISCARD uint32_t find(const char (&lit)[N], uint32_t pos = 0) const {
502 static_assert(N > 0);
503 return find(str_view(lit), pos);
504 }
505
510 GAIA_NODISCARD uint32_t find(char ch, uint32_t pos = 0) const {
511 return view().find(ch, pos);
512 }
513
518 GAIA_NODISCARD uint32_t find_first_of(str_view chars, uint32_t pos = 0) const {
519 return view().find_first_of(chars, pos);
520 }
521
526 GAIA_NODISCARD uint32_t find_first_of(char ch, uint32_t pos = 0) const {
527 return view().find_first_of(ch, pos);
528 }
529
535 template <size_t N>
536 GAIA_NODISCARD uint32_t find_first_of(const char (&lit)[N], uint32_t pos = 0) const {
537 return view().find_first_of(lit, pos);
538 }
539
544 GAIA_NODISCARD uint32_t find_last_of(str_view chars, uint32_t pos = BadIndex) const {
545 return view().find_last_of(chars, pos);
546 }
547
552 GAIA_NODISCARD uint32_t find_last_of(char ch, uint32_t pos = BadIndex) const {
553 return view().find_last_of(ch, pos);
554 }
555
561 template <size_t N>
562 GAIA_NODISCARD uint32_t find_last_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
563 return view().find_last_of(lit, pos);
564 }
565
570 GAIA_NODISCARD uint32_t find_first_not_of(str_view chars, uint32_t pos = 0) const {
571 return view().find_first_not_of(chars, pos);
572 }
573
578 GAIA_NODISCARD uint32_t find_first_not_of(char ch, uint32_t pos = 0) const {
579 return view().find_first_not_of(ch, pos);
580 }
581
587 template <size_t N>
588 GAIA_NODISCARD uint32_t find_first_not_of(const char (&lit)[N], uint32_t pos = 0) const {
589 return view().find_first_not_of(lit, pos);
590 }
591
596 GAIA_NODISCARD uint32_t find_last_not_of(str_view chars, uint32_t pos = BadIndex) const {
597 return view().find_last_not_of(chars, pos);
598 }
599
604 GAIA_NODISCARD uint32_t find_last_not_of(char ch, uint32_t pos = BadIndex) const {
605 return view().find_last_not_of(ch, pos);
606 }
607
613 template <size_t N>
614 GAIA_NODISCARD uint32_t find_last_not_of(const char (&lit)[N], uint32_t pos = BadIndex) const {
615 return view().find_last_not_of(lit, pos);
616 }
617 };
618
622 GAIA_NODISCARD constexpr bool is_whitespace(char c) {
623 return c == ' ' || (c >= '\t' && c <= '\r');
624 }
625
629 GAIA_NODISCARD constexpr str_view trim(str_view expr) {
630 const auto len = expr.size();
631 if (len == 0)
632 return {};
633
634 uint32_t beg = 0;
635 while (beg < len && is_whitespace(expr.data()[beg]))
636 ++beg;
637 if (beg == len)
638 return {};
639
640 uint32_t end = len - 1;
641 while (end > beg && is_whitespace(expr.data()[end]))
642 --end;
643 return str_view(expr.data() + beg, end - beg + 1);
644 }
645
649 GAIA_NODISCARD constexpr std::span<const char> trim(std::span<const char> expr) {
650 const auto trimmed = trim(str_view(expr.data(), (uint32_t)expr.size()));
651 return std::span<const char>(trimmed.data(), trimmed.size());
652 }
653 } // namespace util
654} // namespace gaia
Array with variable size of elements of type.
Definition darray_impl.h:25
Definition span_impl.h:99
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
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:186
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:122
GAIA_NODISCARD constexpr uint32_t size() const
Returns the number of characters in the view.
Definition str.h:41
GAIA_NODISCARD constexpr bool operator==(const char(&lit)[N]) const
Compares this view with literal lit for exact byte equality.
Definition str.h:293
constexpr str_view(const char *data, uint32_t size)
Constructs a string view from a pointer and an explicit length.
Definition str.h:23
GAIA_NODISCARD constexpr bool operator==(str_view other) const
Compares this view with view other for exact byte equality.
Definition str.h:301
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:94
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:284
GAIA_NODISCARD constexpr bool empty() const
Checks whether the view contains no characters.
Definition str.h:47
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:140
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:194
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:235
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:108
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:260
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:132
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:162
constexpr str_view(const char(&lit)[N])
Constructs a string view from a literal, excluding its trailing null terminator.
Definition str.h:29
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:85
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:64
GAIA_NODISCARD constexpr bool operator!=(str_view other) const
Compares this view with view other for exact byte inequality.
Definition str.h:308
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:227
GAIA_NODISCARD constexpr const char * data() const
Returns the underlying character pointer.
Definition str.h:35
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:55
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:211
str_view()=default
Constructs an empty string view.
Lightweight owning string container with explicit length semantics (no implicit null terminator).
Definition str.h:331
str()=default
Constructs an empty string.
void append(str_view view)
Appends view contents.
Definition str.h:398
GAIA_NODISCARD uint32_t size() const
Returns number of characters stored in the string.
Definition str.h:431
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:482
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:510
GAIA_NODISCARD char * data()
Returns mutable pointer to internal data.
Definition str.h:425
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:588
GAIA_NODISCARD bool operator==(const char(&lit)[N]) const
Compares this string with literal lit for exact byte equality.
Definition str.h:458
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:518
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:544
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:570
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:578
void assign(const char(&lit)[N])
Replaces contents with literal lit.
Definition str.h:381
void append(const char *data, uint32_t size)
Appends size characters from data.
Definition str.h:389
void append(const char(&lit)[N])
Appends literal lit.
Definition str.h:406
GAIA_NODISCARD bool operator==(const str &other) const
Compares this string with string other for exact byte equality.
Definition str.h:474
void clear()
Removes all characters from the string.
Definition str.h:352
GAIA_NODISCARD bool empty() const
Checks whether the string contains no characters.
Definition str.h:437
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:491
str(str_view view)
Constructs a string by copying view contents.
Definition str.h:339
GAIA_NODISCARD str_view view() const
Returns a non-owning view over the current contents.
Definition str.h:443
void reserve(uint32_t len)
Reserves capacity for at least len characters.
Definition str.h:358
void assign(const char *data, uint32_t size)
Replaces contents with size characters from data.
Definition str.h:365
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:501
GAIA_NODISCARD const char * data() const
Returns read-only pointer to internal data.
Definition str.h:419
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:614
void assign(str_view view)
Replaces contents with view contents.
Definition str.h:373
GAIA_NODISCARD bool operator==(str_view other) const
Compares this string with view other for exact byte equality.
Definition str.h:467
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:562
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:596
GAIA_NODISCARD uint32_t find_first_of(char ch, uint32_t pos=0) const
Finds the first occurrence of character ch.
Definition str.h:526
str(const char(&lit)[N])
Constructs a string from literal lit, excluding trailing null terminator.
Definition str.h:347
void append(char ch)
Appends a single character.
Definition str.h:413
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:536
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:604
GAIA_NODISCARD uint32_t find_last_of(char ch, uint32_t pos=BadIndex) const
Finds the last occurrence of character ch.
Definition str.h:552