@@ -956,74 +956,64 @@ namespace sysstr
956
956
return dest;
957
957
958
958
stack_or_heap_buffer<char32_t , 32 > buffer;
959
-
960
- auto status = get_nfc_qc_status (*first);
961
959
960
+ auto cur = first;
962
961
for ( ; ; )
963
962
{
964
- auto conv_range = find_conversion_range (status, first, last);
965
- for ( ; first != conv_range.begin (); ++first)
966
- dest = write_unsafe<OutEnc>(*first, dest);
967
- if (conv_range.empty ())
968
- {
969
- assert (first == last);
970
- break ;
971
- }
963
+ auto status = get_nfc_qc_status (*cur);
972
964
973
- if constexpr (std::ranges::sized_range<decltype (conv_range)>)
974
- buffer.reserve (conv_range.size ());
975
- nfd<utf32>()(conv_range, std::back_inserter (buffer));
976
- dest = convert (buffer, dest);
977
- first = conv_range.end ();
978
- if (first == last)
979
- break ;
980
- status = nfc_qc_status::stable;
981
- buffer.clear ();
982
- }
983
-
984
- return dest;
985
- }
986
-
987
- private:
988
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
989
- requires (std::is_same_v<std::iter_value_t <It>, char32_t >)
990
- inline auto find_conversion_range (nfc_qc_status first_status,
991
- It first, EndIt last) -> std::ranges::subrange<It>
992
- {
993
- using namespace util ;
994
- using namespace util ::unicode;
995
-
996
- auto status = first_status;
997
- It start = first;
998
- for ( ; ; )
999
- {
1000
965
if (status == nfc_qc_status::bad)
1001
966
{
1002
- for (++first; first != last ; ++first )
967
+ for (++cur; ; ++cur )
1003
968
{
1004
- status = get_nfc_qc_status (*first);
969
+ if (cur == last)
970
+ return convert_slow (buffer, first, cur, dest);
971
+ status = get_nfc_qc_status (*cur);
1005
972
if (status == nfc_qc_status::stable)
1006
973
break ;
1007
974
}
1008
- return {start, first};
975
+ dest = convert_slow (buffer, first, cur, dest);
976
+ buffer.clear ();
977
+ first = cur;
978
+ if (++cur == last)
979
+ return write_unsafe<OutEnc>(*first, dest);
1009
980
}
1010
- if (status == nfc_qc_status::stable)
981
+ else if (status == nfc_qc_status::stable)
1011
982
{
1012
- start = first;
1013
- if (++first == last)
1014
- return {first, first};
983
+ for ( ; first != cur; ++first)
984
+ dest = write_unsafe<OutEnc>(*first, dest);
985
+ for (++cur; ; ++cur)
986
+ {
987
+ if (cur == last)
988
+ return write_unsafe<OutEnc>(*first, dest);
989
+ status = get_nfc_qc_status (*cur);
990
+ if (status != nfc_qc_status::stable)
991
+ break ;
992
+ write_unsafe<OutEnc>(*first, dest);
993
+ ++first;
994
+ }
1015
995
}
1016
996
else
1017
997
{
1018
- if (++first == last)
1019
- return {start , first} ;
998
+ if (++cur == last)
999
+ return convert_slow (buffer , first, cur, dest) ;
1020
1000
}
1021
-
1022
- status = get_nfc_qc_status (*first);
1023
1001
}
1024
- return {first, first}; // == {last, last}
1025
1002
}
1003
+
1004
+ private:
1005
+ template <std::forward_iterator It, std::sentinel_for<It> EndIt, std::output_iterator<utf_char_of<OutEnc>> OutIt>
1006
+ requires (std::is_same_v<std::iter_value_t <It>, char32_t >)
1007
+ static auto convert_slow (util::stack_or_heap_buffer<char32_t , 32 > & buffer,It first, EndIt last, OutIt dest) -> OutIt
1008
+ {
1009
+ if constexpr (std::sized_sentinel_for<It, EndIt>)
1010
+ buffer.reserve (last - first);
1011
+ nfd<utf32>()(std::ranges::subrange{first, last}, std::back_inserter (buffer));
1012
+ return convert (buffer, dest);
1013
+ }
1014
+
1026
1015
1016
+ SYS_STRING_FORCE_INLINE
1027
1017
static auto get_nfc_qc_status (char32_t c) -> nfc_qc_status
1028
1018
{
1029
1019
using namespace util ;
@@ -1042,7 +1032,7 @@ namespace sysstr
1042
1032
1043
1033
template <std::ranges::forward_range Range, std::output_iterator<utf_char_of<OutEnc>> OutIt>
1044
1034
requires (utf_encoding_of<std::ranges::range_value_t <Range>> == utf32)
1045
- inline auto convert (const Range & range, OutIt dest) -> OutIt
1035
+ static inline auto convert (const Range & range, OutIt dest) -> OutIt
1046
1036
{
1047
1037
using namespace util ;
1048
1038
using namespace util ::unicode;
@@ -1145,6 +1135,7 @@ namespace sysstr
1145
1135
1146
1136
}
1147
1137
1138
+ SYS_STRING_FORCE_INLINE
1148
1139
static auto find_composition (uint32_t val , const uint32_t * compositions) -> uint32_t
1149
1140
{
1150
1141
for ( ; ; )
0 commit comments