Skip to content

Commit 7747f5e

Browse files
author
Julian LALU
committed
Add cstring_view and cwstring_view
1 parent 1d8457b commit 7747f5e

File tree

9 files changed

+1442
-296
lines changed

9 files changed

+1442
-296
lines changed

interface/core/string/cstring.h

Lines changed: 102 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -452,9 +452,26 @@ namespace hud
452452
* @param count Number of character to compare
453453
* @return true if equal, false otherwise
454454
*/
455-
[[nodiscard]] static HD_FORCEINLINE bool equals_partial(const ansichar *string_0, const ansichar *string_1, const usize count) noexcept
455+
[[nodiscard]] static constexpr bool equals_partial(const ansichar *string_0, const ansichar *string_1, const usize count) noexcept
456456
{
457-
return strncmp(string_0, string_1, count) == 0;
457+
if consteval {
458+
size_t i = 0;
459+
while (i < count) {
460+
ansichar c0 = string_0[i];
461+
ansichar c1 = string_1[i];
462+
if (c0 != c1) {
463+
return (c0 - c1) == 0;
464+
}
465+
if (c0 == '\0') {
466+
return true;
467+
}
468+
i++;
469+
}
470+
return true;
471+
}
472+
else {
473+
return strncmp(string_0, string_1, count) == 0;
474+
}
458475
}
459476

460477
/**
@@ -464,9 +481,26 @@ namespace hud
464481
* @param count Number of character to compare
465482
* @return true if equal, false otherwise
466483
*/
467-
[[nodiscard]] static HD_FORCEINLINE bool equals_partial(const wchar *string_0, const wchar *string_1, const usize count) noexcept
484+
[[nodiscard]] static constexpr bool equals_partial(const wchar *string_0, const wchar *string_1, const usize count) noexcept
468485
{
469-
return wcsncmp(string_0, string_1, count) == 0;
486+
if consteval {
487+
size_t i = 0;
488+
while (i < count) {
489+
wchar c0 = string_0[i];
490+
wchar c1 = string_1[i];
491+
if (c0 != c1) {
492+
return (c0 - c1) == 0;
493+
}
494+
if (c0 == L'\0') {
495+
return true;
496+
}
497+
i++;
498+
}
499+
return true;
500+
}
501+
else {
502+
return wcsncmp(string_0, string_1, count) == 0;
503+
}
470504
}
471505

472506
/**
@@ -519,9 +553,27 @@ namespace hud
519553
* @param string_to_find The string to find
520554
* @return Pointer to the first occurrence of string in another string, nullptr if not found
521555
*/
522-
[[nodiscard]] static HD_FORCEINLINE const ansichar *find_string(const ansichar *const string, const ansichar *const string_to_find) noexcept
556+
[[nodiscard]] static constexpr const ansichar *find_string(const ansichar *string, const ansichar *const string_to_find) noexcept
523557
{
524-
return strstr(string, string_to_find);
558+
if consteval {
559+
if (!*string_to_find)
560+
return string;
561+
for (; *string; ++string) {
562+
const ansichar *h = string;
563+
const ansichar *n = string_to_find;
564+
while (*n && *h && *h == *n) {
565+
++h;
566+
++n;
567+
}
568+
569+
if (!*n)
570+
return string;
571+
}
572+
return nullptr;
573+
}
574+
else {
575+
return strstr(string, string_to_find);
576+
}
525577
}
526578

527579
/**
@@ -530,9 +582,27 @@ namespace hud
530582
* @param string_to_find The string to find
531583
* @return Pointer to the first occurrence of string in another string, nullptr if not found
532584
*/
533-
[[nodiscard]] static HD_FORCEINLINE const wchar *find_string(const wchar *const string, const wchar *const string_to_find) noexcept
585+
[[nodiscard]] static constexpr const wchar *find_string(const wchar *string, const wchar *const string_to_find) noexcept
534586
{
535-
return wcsstr(string, string_to_find);
587+
if consteval {
588+
if (!*string_to_find)
589+
return string;
590+
for (; *string; ++string) {
591+
const wchar *h = string;
592+
const wchar *n = string_to_find;
593+
while (*n && *h && *h == *n) {
594+
++h;
595+
++n;
596+
}
597+
598+
if (!*n)
599+
return string;
600+
}
601+
return nullptr;
602+
}
603+
else {
604+
return wcsstr(string, string_to_find);
605+
}
536606
}
537607

538608
/**
@@ -541,9 +611,19 @@ namespace hud
541611
* @param character_to_find The string to find
542612
* @return Pointer to the first occurrence of the character in the string, nullptr if not found
543613
*/
544-
[[nodiscard]] static HD_FORCEINLINE const ansichar *find_character(const ansichar *const string, const ansichar character_to_find) noexcept
614+
[[nodiscard]] static constexpr const ansichar *find_character(const ansichar *string, const ansichar character_to_find) noexcept
545615
{
546-
return strchr(string, character_to_find);
616+
if consteval {
617+
while (*string != '\0') {
618+
if (*string == character_to_find)
619+
return string;
620+
string++;
621+
}
622+
return nullptr;
623+
}
624+
else {
625+
return strchr(string, character_to_find);
626+
}
547627
}
548628

549629
/**
@@ -552,9 +632,19 @@ namespace hud
552632
* @param character_to_find The string to find
553633
* @return Pointer to the first occurrence of the character in the string, nullptr if not found
554634
*/
555-
[[nodiscard]] static HD_FORCEINLINE const wchar *find_character(const wchar *const string, const wchar character_to_find) noexcept
635+
[[nodiscard]] static constexpr const wchar *find_character(const wchar *string, const wchar character_to_find) noexcept
556636
{
557-
return wcschr(string, character_to_find);
637+
if consteval {
638+
while (*string != '\0') {
639+
if (*string == character_to_find)
640+
return string;
641+
string++;
642+
}
643+
return nullptr;
644+
}
645+
else {
646+
return wcschr(string, character_to_find);
647+
}
558648
}
559649

560650
/**

interface/core/string/cstring_view.h

Lines changed: 98 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,50 @@ namespace hud
99
*/
1010
struct cstring_view
1111
{
12+
/**
13+
* Constructs a cstring_view from a C-style string pointer.
14+
* @param str Pointer to a null-terminated string. Must not be null.
15+
*/
1216
constexpr cstring_view(const ansichar *str) noexcept
1317
: ptr_(str)
14-
, len_(cstring::length(str))
1518
{
1619
HUD_CHECK(ptr_ != nullptr && "Invalid null pointer");
1720
}
1821

19-
constexpr cstring_view(const ansichar *str, usize length) noexcept
20-
: ptr_(str)
21-
, len_(length)
22-
{
23-
HUD_CHECK(ptr_ != nullptr && "Invalid null pointer");
24-
HUD_CHECK(cstring::length_safe(str, cstring::RSIZE_MAX_STR) == length && "length must match string length");
25-
}
26-
22+
/**
23+
* Returns the length of the string (number of characters before the null terminator).
24+
* @return The length of the string in characters.
25+
*/
2726
[[nodiscard]]
2827
constexpr usize length() const noexcept
2928
{
30-
return len_;
29+
return cstring::length(ptr_);
3130
}
3231

32+
/**
33+
* Returns a pointer to the underlying C-style string.
34+
* @return A pointer to the string's first character (null-terminated).
35+
*/
3336
[[nodiscard]]
3437
constexpr const ansichar *data() const noexcept
3538
{
3639
return ptr_;
3740
}
3841

42+
/**
43+
* Checks if the string is empty.
44+
* @return true if the string is empty, false otherwise.
45+
*/
3946
[[nodiscard]]
4047
constexpr bool is_empty() const noexcept
4148
{
42-
return len_ == 0;
49+
return hud::character::is_null(ptr_[0]);
4350
}
4451

52+
/**
53+
* Checks if all characters in the string are ASCII characters.
54+
* @return true if the string contains only ASCII characters, false otherwise.
55+
*/
4556
[[nodiscard]]
4657
constexpr bool is_ascii() const noexcept
4758
{
@@ -52,82 +63,107 @@ namespace hud
5263
}
5364
else {
5465
// Mask 16 bytes of 0x80 with the ansichars
55-
const __m128i mask = _mm_set1_epi8(i8(0x80));
56-
for (; i + 16 <= len_; i += 16) {
66+
const __m128i mask = _mm_set1_epi8(char(0x80));
67+
for (; i + 16 <= length(); i += 16) {
5768
__m128i chunk = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr_ + i));
5869
if (_mm_movemask_epi8(_mm_and_si128(chunk, mask)) != 0)
5970
return false;
6071
}
6172
}
6273
#endif
6374
// Do the rest 1 byte at a time
64-
for (; i < len_; ++i) {
65-
if (ptr_[i] & 0x80) {
75+
const ansichar *p = ptr_ + i;
76+
while (*p != '\0') {
77+
if (!character::is_pure_ascii(*p)) {
6678
return false;
6779
}
80+
p++;
6881
}
69-
7082
return true;
7183
}
7284

85+
/**
86+
* Checks if this string is equal to another string.
87+
* @param v Another cstring_view to compare with.
88+
* @return true if both strings are identical, false otherwise.
89+
*/
90+
7391
[[nodiscard]]
7492
constexpr bool equals(const cstring_view &v) const noexcept
7593
{
76-
if (len_ != v.len_) {
77-
return false;
78-
}
79-
usize i {0};
80-
#if HD_SSE2
81-
if consteval {
82-
}
83-
else {
84-
// DO SSE2 comparison of 16 bytes if we have 16 bytes
85-
for (; i + 16 <= len_; i += 16) {
86-
__m128i chunk_this = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr_ + i));
87-
__m128i chunk_v = _mm_loadu_si128(reinterpret_cast<const __m128i *>(v.ptr_ + i));
88-
if (_mm_movemask_epi8(_mm_cmpeq_epi8(chunk_this, chunk_v)) != 0xFFFF)
89-
return false;
90-
}
91-
}
92-
#endif
93-
for (; i < len_; ++i) {
94-
if (ptr_[i] != v.ptr_[i]) {
95-
return false;
96-
}
97-
}
98-
return true;
94+
return hud::cstring::equals(ptr_, v.ptr_);
9995
}
10096

97+
/**
98+
* Checks if the first n characters of this string match those of another string.
99+
* @param v Another cstring_view to compare with.
100+
* @param n Number of characters to compare.
101+
* @return true if the first n characters match, false otherwise.
102+
*/
101103
[[nodiscard]]
102104
constexpr bool equals_partial(const cstring_view &v, const usize n) const noexcept
103105
{
104-
usize len_to_compare = (n < len_) ? n : len_;
105-
len_to_compare = (len_to_compare > v.len_) ? v.len_ : len_to_compare;
106-
usize i {0};
107-
#if HD_SSE2
108-
if consteval {
109-
}
110-
else {
111-
// DO SSE2 comparison of 16 bytes if we have 16 bytes
112-
for (; i + 16 <= len_to_compare; i += 16) {
113-
__m128i chunk_this = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr_ + i));
114-
__m128i chunk_v = _mm_loadu_si128(reinterpret_cast<const __m128i *>(v.ptr_ + i));
115-
if (_mm_movemask_epi8(_mm_cmpeq_epi8(chunk_this, chunk_v)) != 0xFFFF)
116-
return false;
117-
}
118-
}
119-
#endif
120-
for (; i < len_to_compare; ++i) {
121-
if (ptr_[i] != v.ptr_[i]) {
122-
return false;
123-
}
124-
}
125-
return true;
106+
return hud::cstring::equals_partial(ptr_, v.ptr_, n);
107+
}
108+
109+
/**
110+
* Finds the first occurrence of a substring.
111+
* @param to_find The substring to search for.
112+
* @return Index of the first occurrence, or -1 if not found.
113+
*/
114+
[[nodiscard]]
115+
constexpr isize find_first(const cstring_view &to_find) const noexcept
116+
{
117+
const ansichar *result = hud::cstring::find_string(ptr_, to_find.ptr_);
118+
return result == nullptr ? -1 : result - ptr_;
119+
}
120+
121+
/**
122+
* Finds the first occurrence of a character.
123+
* @param character_to_find The character to search for.
124+
* @return Index of the first occurrence, or -1 if not found.
125+
*/
126+
[[nodiscard]]
127+
constexpr isize find_first_character(const ansichar character_to_find) const noexcept
128+
{
129+
const ansichar *result = hud::cstring::find_character(ptr_, character_to_find);
130+
return result == nullptr ? -1 : result - ptr_;
131+
}
132+
133+
/**
134+
* Provides read-only access to a character at a given index.
135+
* @param i Index of the character to access.
136+
* @return A const reference to the character at position i.
137+
*/
138+
[[nodiscard]]
139+
constexpr const ansichar &operator[](const usize i) const noexcept
140+
{
141+
return ptr_[i];
142+
}
143+
/**
144+
* Checks if this string contains a given substring.
145+
* @param to_find The substring to search for.
146+
* @return true if the substring is found, false otherwise.
147+
*/
148+
[[nodiscard]]
149+
constexpr bool contains(const cstring_view &to_find) const noexcept
150+
{
151+
return hud::cstring::find_string(ptr_, to_find.ptr_) != nullptr;
152+
}
153+
/**
154+
* Checks if this string contains a given character.
155+
* @param character_to_find The character to search for.
156+
* @return true if the character is found, false otherwise.
157+
*/
158+
[[nodiscard]]
159+
constexpr bool contains(const ansichar character_to_find) const noexcept
160+
{
161+
return hud::cstring::find_character(ptr_, character_to_find) != nullptr;
126162
}
127163

128164
private:
165+
/**Pointer to the null-terminated C-style string. */
129166
const ansichar *ptr_;
130-
usize len_;
131167
};
132168

133169
} // namespace hud

interface/core/string/string.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef HD_INC_CORE_STRING_STRING_H
2+
#define HD_INC_CORE_STRING_STRING_H
3+
4+
namespace hud
5+
{
6+
class string
7+
{
8+
private:
9+
};
10+
} // namespace hud
11+
12+
#endif HD_INC_CORE_STRING_STRING_H

0 commit comments

Comments
 (0)