@@ -115,11 +115,54 @@ template <typename CharT, typename Iterator, typename EndIterator> constexpr CTR
115
115
return false ;
116
116
}
117
117
118
- template <auto ... String, size_t ... Idx, typename Iterator, typename EndIterator> constexpr CTRE_FORCE_INLINE string_match_result<Iterator> evaluate_match_string (Iterator current, [[maybe_unused]] const EndIterator end, std::index_sequence<Idx...>) noexcept {
119
-
120
- bool same = (compare_character (String, current, end) && ... && true );
118
+ #if __cpp_char8_t >= 201811
119
+ template <size_t N, size_t ... Idx, typename Iterator, typename EndIterator> constexpr CTRE_FORCE_INLINE string_match_result<Iterator> evaluate_match_utf8_string (Iterator current, [[maybe_unused]] const EndIterator end, char8_t (&buffer)[N], std::index_sequence<Idx...>) noexcept {
120
+ // abuse inside knowledge of how utf8_iterator works
121
+ if constexpr (!std::is_same_v<::std::remove_const_t <EndIterator>, utf8_iterator::sentinel>) {
122
+ size_t count = end.ptr - current.ptr ; // size_t count = std::distance(current.ptr, end.ptr);
123
+ size_t bump = ((count < N) ? count : N);
124
+ return { Iterator{current.ptr + bump, current.end }, (count >= N) && (((static_cast <char8_t >(current.ptr [Idx] != buffer[Idx])) | ... | char8_t {0 }) == 0 ) };
125
+ } else {
126
+ size_t count = current.end - current.ptr ; // size_t count = std::distance(current.ptr, current.end);
127
+ size_t bump = ((count < N) ? count : N);
128
+ return { Iterator{current.ptr + bump, current.end }, (count >= N) && ((((static_cast <char8_t >(current.ptr [Idx] != buffer[Idx])) | ... | char8_t {0 }) == 0 ) };
129
+ }
130
+ }
131
+ #endif
121
132
122
- return {current, same};
133
+ template <auto ... String, size_t ... Idx, typename Iterator, typename EndIterator> constexpr CTRE_FORCE_INLINE string_match_result<Iterator> evaluate_match_string (Iterator current, [[maybe_unused]] const EndIterator end, std::index_sequence<Idx...>) noexcept {
134
+ #if __cpp_char8_t >= 201811
135
+ if constexpr (sizeof ...(String) && std::is_same_v<::std::remove_const_t <Iterator>, utf8_iterator> && (std::is_same_v<std::remove_const_t <Iterator>, std::remove_const_t <EndIterator>> || std::is_same_v<::std::remove_const_t <EndIterator>, utf8_iterator::sentinel>)) {
136
+ constexpr size_t str_length = (utf8_codepoint_length (String) + ... + 0ULL );
137
+ // encode our String... into it's utf8 representation
138
+ char8_t utf8_sequence[str_length];
139
+ char8_t * ptr = utf8_sequence;
140
+ ((ptr = utf32_codepoint_to_utf8_codepoint (String, ptr)), ...);
141
+ // run the comparison
142
+ return evaluate_match_utf8_string (current, end, utf8_sequence, std::make_index_sequence<str_length>());
143
+ } else if constexpr (sizeof ...(String) && is_random_accessible (typename std::iterator_traits<Iterator>::iterator_category{}) && std::is_same_v<std::remove_const_t <Iterator>, std::remove_const_t <EndIterator>>) {
144
+ using char_type = ::std::remove_reference_t <::std::remove_cv_t <decltype (*current)>>;
145
+ // check the remaining bytes*
146
+ size_t count = end - current;
147
+ // make sure we only "bump" the iterator a safe distance
148
+ size_t bump = ((count < sizeof ...(String)) ? count : sizeof ...(String));
149
+ // do math against how many characters we match, avoid as many branches as possible
150
+ return { current + bump, (count >= sizeof ...(String)) && (((static_cast <char_type>(current[Idx] != static_cast <char_type>(String))) | ... | static_cast <char_type>(0 )) == 0 ) };
151
+ } else {
152
+ bool same = (compare_character (String, current, end) && ... && true );
153
+ return { current, same };
154
+ }
155
+ #else
156
+ if constexpr (sizeof ...(String) && is_random_accessible (typename std::iterator_traits<Iterator>::iterator_category{}) && std::is_same_v<std::remove_const_t <Iterator>, std::remove_const_t <EndIterator>>) {
157
+ using char_type = ::std::remove_reference_t <::std::remove_cv_t <decltype (*current)>>;
158
+ size_t count = end - current;
159
+ size_t bump = ((count < sizeof ...(String)) ? count : sizeof ...(String));
160
+ return { current + bump, (count >= sizeof ...(String)) && (((static_cast <char_type>(current[Idx] != static_cast <char_type>(String))) | ... | static_cast <char_type>(0 )) == 0 ) };
161
+ } else {
162
+ bool same = (compare_character (String, current, end) && ... && true );
163
+ return { current, same };
164
+ }
165
+ #endif
123
166
}
124
167
125
168
template <typename R, typename Iterator, typename EndIterator, auto ... String, typename ... Tail>
0 commit comments