1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #pragma once |
4 | |
5 | #include <algorithm> |
6 | #include <cstddef> |
7 | |
8 | namespace mos |
9 | { |
10 | template<typename CharT> |
11 | constexpr auto generic_strlen(const CharT *c) |
12 | { |
13 | if (!c) |
14 | return size_t(0); |
15 | size_t len = 0; |
16 | while (*(c++)) |
17 | { |
18 | len++; |
19 | } |
20 | return len; |
21 | } |
22 | |
23 | template<typename CharT> |
24 | constexpr auto generic_strnlen(const CharT *c, size_t max) |
25 | { |
26 | size_t len = 0; |
27 | while (len < max && *(c++)) |
28 | { |
29 | len++; |
30 | } |
31 | return len; |
32 | } |
33 | |
34 | template<typename CharT> |
35 | constexpr auto generic_strncmp(const CharT *a, const CharT *b, size_t n) |
36 | { |
37 | for (size_t i = 0; i < n; i++) |
38 | { |
39 | if (a[i] != b[i]) |
40 | return a[i] - b[i]; |
41 | } |
42 | return 0; |
43 | } |
44 | |
45 | template<typename CharT> |
46 | class basic_string_view |
47 | { |
48 | public: |
49 | basic_string_view(std::nullptr_t) = delete; |
50 | constexpr basic_string_view() : _pointer(nullptr), _length(0) {}; |
51 | constexpr basic_string_view(const CharT *cs) : _pointer(cs), _length(generic_strlen(cs)) {}; |
52 | constexpr basic_string_view(const CharT *s, size_t length) : _pointer(s), _length(length) {}; |
53 | |
54 | const CharT *data() const |
55 | { |
56 | return _pointer; |
57 | } |
58 | |
59 | const CharT &operator[](size_t index) const |
60 | { |
61 | return _pointer[index]; |
62 | } |
63 | |
64 | size_t size() const |
65 | { |
66 | return _length; |
67 | } |
68 | |
69 | constexpr bool empty() const |
70 | { |
71 | return _length == 0; |
72 | } |
73 | |
74 | bool operator==(basic_string_view other) const |
75 | { |
76 | if (_length != other._length) |
77 | return false; |
78 | |
79 | return generic_strncmp(_pointer, other._pointer, _length) == 0; |
80 | } |
81 | |
82 | constexpr basic_string_view substring(size_t start, size_t end = -1) const |
83 | { |
84 | const auto len = std::min<size_t>(a: end, b: _length - start); |
85 | return basic_string_view(_pointer + start, len); |
86 | } |
87 | |
88 | constexpr size_t find(CharT c) const |
89 | { |
90 | for (size_t i = 0; i < _length; i++) |
91 | { |
92 | if (_pointer[i] == c) |
93 | return i; |
94 | } |
95 | return size_t(-1); |
96 | } |
97 | |
98 | constexpr size_t find(basic_string_view str) const |
99 | { |
100 | for (size_t i = 0; i < _length; i++) |
101 | { |
102 | if (generic_strncmp(_pointer + i, str._pointer, str._length) == 0) |
103 | return i; |
104 | } |
105 | return size_t(-1); |
106 | } |
107 | |
108 | private: |
109 | const CharT *_pointer; |
110 | size_t _length; |
111 | }; |
112 | |
113 | typedef basic_string_view<char> string_view; |
114 | |
115 | namespace string_literals |
116 | { |
117 | constexpr string_view operator"" _sv(const char *str, size_t len) |
118 | { |
119 | return string_view(str, len); |
120 | } |
121 | } // namespace string_literals |
122 | } // namespace mos |
123 | |