@@ -115,11 +115,54 @@ template <typename CharT, typename Iterator, typename EndIterator> constexpr CTR
115115 return false ;
116116}
117117
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) && (((current.ptr [Idx] != buffer[Idx]) + ... + 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) && (((current.ptr [Idx] != buffer[Idx]) + ... + 0 ) == 0 ) };
129+ }
130+ }
131+ #endif
121132
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 (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 (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_cvref_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)) && (((current[Idx] != static_cast <char_type>(String)) + ... + 0 ) == 0 ) };
151+ } else {
152+ bool same = (compare_character (String, current, end) && ... && true );
153+ return { current, same };
154+ }
155+ #else
156+ if constexpr (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_cvref_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)) && (((current[Idx] != static_cast <char_type>(String)) + ... + 0 ) == 0 ) };
161+ } else {
162+ bool same = (compare_character (String, current, end) && ... && true );
163+ return { current, same };
164+ }
165+ #endif
123166}
124167
125168template <typename R, typename Iterator, typename EndIterator, auto ... String, typename ... Tail>
0 commit comments