Concrete type-erased string class. Holds all string logic (write, append, find, replace, resize, hashing, …) and is directly constructible from a caller-provided buffer (`char* + len`) or `fl::span `. `fl::string` is a thin wrapper that co-locates a default-sized inline buffer with the `basic_string` state and adds composite-type formatters (vec2, vector, span, …). See `agents/docs/string-arc
| 42 | /// `basic_string` state and adds composite-type formatters |
| 43 | /// (vec2, vector, span, …). See `agents/docs/string-architecture.md`. |
| 44 | class basic_string { |
| 45 | public: |
| 46 | // ======= NESTED TYPES ======= |
| 47 | |
| 48 | // Non-owning pointer to constant null-terminated string data. |
| 49 | struct ConstLiteral { |
| 50 | const char* data; |
| 51 | constexpr ConstLiteral() FL_NOEXCEPT : data(nullptr) {} |
| 52 | constexpr explicit ConstLiteral(const char* str) FL_NOEXCEPT : data(str) {} |
| 53 | }; |
| 54 | |
| 55 | // Non-owning pointer + length to constant string data. |
| 56 | struct ConstView { |
| 57 | const char* data; |
| 58 | fl::size length; |
| 59 | constexpr ConstView() FL_NOEXCEPT : data(nullptr), length(0) {} |
| 60 | constexpr ConstView(const char* str, fl::size len) FL_NOEXCEPT : data(str), length(len) {} |
| 61 | }; |
| 62 | |
| 63 | class iterator { |
| 64 | private: |
| 65 | char* ptr; |
| 66 | public: |
| 67 | typedef char value_type; |
| 68 | typedef char& reference; |
| 69 | typedef char* pointer; |
| 70 | typedef fl::ptrdiff_t difference_type; |
| 71 | typedef fl::random_access_iterator_tag iterator_category; |
| 72 | |
| 73 | iterator() FL_NOEXCEPT : ptr(nullptr) {} |
| 74 | explicit iterator(char* p) FL_NOEXCEPT : ptr(p) {} |
| 75 | |
| 76 | reference operator*() const FL_NOEXCEPT { return *ptr; } |
| 77 | pointer operator->() const FL_NOEXCEPT { return ptr; } |
| 78 | iterator& operator++() FL_NOEXCEPT { ++ptr; return *this; } |
| 79 | iterator operator++(int) FL_NOEXCEPT { iterator tmp = *this; ++ptr; return tmp; } |
| 80 | iterator& operator--() FL_NOEXCEPT { --ptr; return *this; } |
| 81 | iterator operator--(int) FL_NOEXCEPT { iterator tmp = *this; --ptr; return tmp; } |
| 82 | |
| 83 | iterator operator+(difference_type n) const FL_NOEXCEPT { return iterator(ptr + n); } |
| 84 | iterator operator-(difference_type n) const FL_NOEXCEPT { return iterator(ptr - n); } |
| 85 | iterator& operator+=(difference_type n) FL_NOEXCEPT { ptr += n; return *this; } |
| 86 | iterator& operator-=(difference_type n) FL_NOEXCEPT { ptr -= n; return *this; } |
| 87 | difference_type operator-(const iterator& other) const FL_NOEXCEPT { return ptr - other.ptr; } |
| 88 | reference operator[](difference_type n) const FL_NOEXCEPT { return ptr[n]; } |
| 89 | |
| 90 | bool operator==(const iterator& other) const FL_NOEXCEPT { return ptr == other.ptr; } |
| 91 | bool operator!=(const iterator& other) const FL_NOEXCEPT { return ptr != other.ptr; } |
| 92 | bool operator<(const iterator& other) const FL_NOEXCEPT { return ptr < other.ptr; } |
| 93 | bool operator>(const iterator& other) const FL_NOEXCEPT { return ptr > other.ptr; } |
| 94 | bool operator<=(const iterator& other) const FL_NOEXCEPT { return ptr <= other.ptr; } |
| 95 | bool operator>=(const iterator& other) const FL_NOEXCEPT { return ptr >= other.ptr; } |
| 96 | |
| 97 | operator char*() const FL_NOEXCEPT { return ptr; } |
| 98 | }; |
| 99 | |
| 100 | class const_iterator { |
| 101 | private: |