tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
cstr.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2
3#ifndef TETL_CSTRING_ALGORITHM_HPP
4#define TETL_CSTRING_ALGORITHM_HPP
5
6namespace etl::detail {
7
8template <typename CharT>
9[[nodiscard]] constexpr auto strcpy(CharT* dest, CharT const* src) -> CharT*
10{
11 auto* temp = dest;
12 while ((*dest++ = *src++) != CharT(0)) { }
13 return temp;
14}
15
16template <typename CharT, typename SizeT>
17[[nodiscard]] constexpr auto strncpy(CharT* dest, CharT const* src, SizeT count) -> CharT*
18{
19 auto* temp = dest;
20 for (SizeT counter = 0; counter != count and *src != CharT(0);) {
21 *dest = *src;
22 ++src;
23 ++dest;
24 ++counter;
25 }
26
27 return temp;
28}
29
30template <typename CharT, typename SizeT>
31[[nodiscard]] constexpr auto strlen(CharT const* str) -> SizeT
32{
33 CharT const* s = nullptr;
34 for (s = str; *s != CharT(0); ++s) { }
35 return static_cast<SizeT>(s - str);
36}
37
38template <typename CharT, typename SizeT>
39[[nodiscard]] constexpr auto strcat(CharT* dest, CharT const* src) -> CharT*
40{
41 auto* ptr = dest + strlen<CharT, SizeT>(dest);
42 while (*src != CharT(0)) {
43 *ptr++ = *src++;
44 }
45 *ptr = CharT(0);
46 return dest;
47}
48
49template <typename CharT, typename SizeT>
50[[nodiscard]] constexpr auto strncat(CharT* dest, CharT const* src, SizeT const count) -> CharT*
51{
52 auto* ptr = dest + strlen<CharT, SizeT>(dest);
53 SizeT localCounter = 0;
54 while (*src != CharT(0) && localCounter != count) {
55 *ptr++ = *src++;
56 ++localCounter;
57 }
58
59 *ptr = CharT(0);
60 return dest;
61}
62
63template <typename CharT>
64[[nodiscard]] constexpr auto strcmp(CharT const* lhs, CharT const* rhs) -> int
65{
66 for (; *lhs != CharT(0); ++lhs, ++rhs) {
67 if (*lhs != *rhs) {
68 break;
69 }
70 }
71 return static_cast<int>(*lhs) - static_cast<int>(*rhs);
72}
73
74template <typename CharT, typename SizeT>
75[[nodiscard]] constexpr auto strncmp(CharT const* lhs, CharT const* rhs, SizeT const count) -> int
76{
77 CharT u1{};
78 CharT u2{};
79
80 auto localCount = count;
81 while (localCount-- > 0) {
82 u1 = static_cast<CharT>(*lhs++);
83 u2 = static_cast<CharT>(*rhs++);
84 if (u1 != u2) {
85 return static_cast<int>(u1 - u2);
86 }
87 if (u1 == CharT(0)) {
88 return 0;
89 }
90 }
91
92 return 0;
93}
94
95template <typename CharT>
96[[nodiscard]] constexpr auto strchr(CharT* str, int ch) -> CharT*
97{
98 while (*str != CharT(0)) {
99 if (*str == static_cast<CharT>(ch)) {
100 return str;
101 }
102 ++str;
103 }
104
105 if (static_cast<CharT>(ch) == CharT(0)) {
106 return str;
107 }
108 return nullptr;
109}
110
111template <typename CharT, typename SizeT>
112[[nodiscard]] constexpr auto strrchr(CharT* str, int ch) -> CharT*
113{
114 if (str == nullptr) {
115 return nullptr;
116 }
117 auto len = strlen<CharT, SizeT>(str);
118 if (static_cast<CharT>(ch) == CharT(0)) {
119 return str + len;
120 }
121
122 while (len-- != 0) {
123 if (str[len] == static_cast<CharT>(ch)) {
124 return str + len;
125 }
126 }
127
128 return nullptr;
129}
130
131template <typename CharT, typename SizeT, bool InclusiveSearch>
132[[nodiscard]] constexpr auto is_legal_char(CharT const* options, SizeT len, CharT ch) noexcept -> bool
133{
134 for (SizeT i = 0; i < len; ++i) {
135 if (options[i] == ch) {
136 return InclusiveSearch;
137 }
138 }
139 return !InclusiveSearch;
140}
141
142template <typename CharT, typename SizeT, bool InclusiveSearch>
143[[nodiscard]] constexpr auto strspn(CharT const* dest, CharT const* src) noexcept -> SizeT
144{
145 auto result = SizeT{0};
146 auto const length = strlen<CharT, SizeT>(dest);
147 auto const srcLen = strlen<CharT, SizeT>(src);
148 for (SizeT i = 0; i < length; ++i) {
149 if (!is_legal_char<CharT, SizeT, InclusiveSearch>(src, srcLen, dest[i])) {
150 break;
151 }
152 ++result;
153 }
154
155 return result;
156}
157
158template <typename CharT, typename SizeT>
159[[nodiscard]] constexpr auto strpbrk_impl(CharT* s, CharT* del) noexcept -> CharT*
160{
161 auto const i = strspn<CharT, SizeT, false>(s, del);
162 if (i != 0) {
163 return s + i;
164 }
165 if (is_legal_char<CharT, SizeT, true>(del, strlen<CharT, SizeT>(del), s[0])) {
166 return s;
167 }
168 return nullptr;
169}
170
171template <typename CharT>
172[[nodiscard]] constexpr auto strstr_impl(CharT* haystack, CharT* needle) noexcept -> CharT*
173{
174 while (*haystack != CharT(0)) {
175 if ((*haystack == *needle) && (strcmp(haystack, needle) == 0)) {
176 return haystack;
177 }
178 haystack++;
179 }
180 return nullptr;
181}
182
183template <typename CharT, typename SizeT>
184constexpr auto memcpy(void* dest, void const* src, SizeT n) -> void*
185{
186 auto* dp = static_cast<CharT*>(dest);
187 auto const* sp = static_cast<CharT const*>(src);
188 while (n-- != CharT(0)) {
189 *dp++ = *sp++;
190 }
191 return dest;
192}
193
194template <typename CharT, typename ValT, typename SizeT>
195constexpr auto memset(CharT* const s, ValT const c, SizeT n) -> CharT*
196{
197 auto* p = s;
198 while (n-- != CharT(0)) {
199 *p++ = static_cast<CharT>(c);
200 }
201 return s;
202}
203
204// Check original implementation. They use `__np_anyptrlt` which is not
205// portable. https://clc-wiki.net/wiki/C_standard_library:string.h:memmove
206template <typename CharT, typename SizeT>
207constexpr auto memmove(void* dest, void const* src, SizeT n) -> CharT*
208{
209 auto const* ps = static_cast<CharT const*>(src);
210 auto* pd = static_cast<CharT*>(dest);
211
212 if (ps < pd) {
213 for (pd += n, ps += n; n-- != CharT(0);) {
214 *--pd = *--ps;
215 }
216 } else {
217 while (n-- != CharT(0)) {
218 *pd++ = *ps++;
219 }
220 }
221
222 return static_cast<CharT*>(dest);
223}
224
225template <typename CharT, typename SizeT>
226constexpr auto memchr(CharT* ptr, CharT ch, SizeT n) -> CharT*
227{
228 for (SizeT i{0}; i != n; ++i) {
229 if (ptr[i] == ch) {
230 return ptr + i;
231 }
232 }
233 return nullptr;
234}
235
236} // namespace etl::detail
237
238#endif // TETL_CSTRING_ALGORITHM_HPP
constexpr auto count(InputIt first, InputIt last, T const &value) -> typename iterator_traits< InputIt >::difference_type
Returns the number of elements in the range [first, last) satisfying specific criteria....
Definition count.hpp:21