1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
5#include <algorithm>
6#include <cstddef>
7
8namespace 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