@@ -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
0 commit comments