@@ -18,27 +18,27 @@ namespace sysstr
18
18
class utf_converter
19
19
{
20
20
private:
21
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
21
+ template <std::input_iterator It, std::sentinel_for<It> EndIt>
22
22
static void reading (It first, EndIt last) noexcept (noexcept (*first++) && noexcept (first != last));
23
- template <std::ranges::forward_range Range>
23
+ template <std::ranges::input_range Range>
24
24
static void reading (Range && range) noexcept (noexcept (reading(std::ranges::begin(range), std::ranges::end(range))));
25
25
template <std::output_iterator<utf_char_of<To>> OutIt>
26
26
static void writing (OutIt dest) noexcept (noexcept (*dest++ = utf_char_of<To>()));
27
27
template <class Func >
28
28
static void applying (Func func) noexcept (noexcept (func(utf_char_of<To>())));
29
29
public:
30
- template <std::ranges::forward_range Range, class Func >
30
+ template <std::ranges::input_range Range, class Func >
31
31
static Func for_each_converted (Range && range, Func func) noexcept (noexcept (reading(std::forward<Range>(range))) && noexcept (applying(func)));
32
32
33
- template <std::ranges::forward_range Range, std::output_iterator<utf_char_of<To>> OutIt>
33
+ template <std::ranges::input_range Range, std::output_iterator<utf_char_of<To>> OutIt>
34
34
SYS_STRING_FORCE_INLINE
35
35
static OutIt convert (Range && range, OutIt dest) noexcept (noexcept (reading(std::forward<Range>(range))) && noexcept (writing(dest)))
36
36
{
37
37
for_each_converted (std::forward<Range>(range), [&](auto c) { *dest++ = c; });
38
38
return dest;
39
39
}
40
40
41
- template <std::ranges::forward_range Range>
41
+ template <std::ranges::input_range Range>
42
42
SYS_STRING_FORCE_INLINE
43
43
static size_t converted_length (Range && range) noexcept (noexcept (reading(std::forward<Range>(range))))
44
44
{
@@ -47,7 +47,7 @@ namespace sysstr
47
47
return ret;
48
48
}
49
49
50
- template <std::forward_iterator It, std::sentinel_for<It> EndIt, class Func >
50
+ template <std::input_iterator It, std::sentinel_for<It> EndIt, class Func >
51
51
SYS_STRING_FORCE_INLINE
52
52
static Func for_each_converted (It first, EndIt last, Func func) noexcept (noexcept (reading(first, last)) && noexcept (applying(func)))
53
53
{
@@ -56,15 +56,15 @@ namespace sysstr
56
56
}
57
57
58
58
59
- template <std::forward_iterator It, std::sentinel_for<It> EndIt, std::output_iterator<utf_char_of<To>> OutIt>
59
+ template <std::input_iterator It, std::sentinel_for<It> EndIt, std::output_iterator<utf_char_of<To>> OutIt>
60
60
SYS_STRING_FORCE_INLINE
61
61
static OutIt convert (It first, EndIt last, OutIt dest) noexcept (noexcept (reading(first, last)) && noexcept (writing(dest)))
62
62
{
63
63
for_each_converted (first, last, [&](auto c) { *dest++ = c; });
64
64
return dest;
65
65
}
66
66
67
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
67
+ template <std::input_iterator It, std::sentinel_for<It> EndIt>
68
68
SYS_STRING_FORCE_INLINE
69
69
static size_t converted_length (It first, EndIt last) noexcept (noexcept (reading(first, last)))
70
70
{
@@ -79,26 +79,26 @@ namespace sysstr
79
79
class utf32_input
80
80
{
81
81
private:
82
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
82
+ template <std::input_iterator It, std::sentinel_for<It> EndIt>
83
83
static void reading (It first, EndIt last) noexcept (noexcept (*first++) && noexcept (first != last));
84
- template <std::ranges::forward_range Range>
84
+ template <std::ranges::input_range Range>
85
85
static void reading (Range && range) noexcept (noexcept (reading(std::ranges::begin(range), std::ranges::end(range))));
86
86
87
87
public:
88
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
88
+ template <std::input_iterator It, std::sentinel_for<It> EndIt>
89
89
static char32_t read (It & first, EndIt last) noexcept (noexcept (reading(first,last)));
90
90
91
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
91
+ template <std::input_iterator It, std::sentinel_for<It> EndIt>
92
92
static char32_t read_reversed (It & first, EndIt last) noexcept (noexcept (reading(first,last)));
93
93
94
- template <std::ranges::forward_range Range, class Sink >
94
+ template <std::ranges::input_range Range, class Sink >
95
95
SYS_STRING_FORCE_INLINE
96
96
static Sink read (Range && range, Sink sink) noexcept (noexcept (reading(std::forward<Range>(range))) && noexcept (sink(char32_t ())))
97
97
{
98
98
return read (std::ranges::begin (std::forward<Range>(range)), std::ranges::end (std::forward<Range>(range)), sink);
99
99
}
100
100
101
- template <std::forward_iterator It, std::sentinel_for<It> EndIt, class Sink >
101
+ template <std::input_iterator It, std::sentinel_for<It> EndIt, class Sink >
102
102
SYS_STRING_FORCE_INLINE
103
103
static Sink read (It first, EndIt last, Sink sink) noexcept (noexcept (reading(first,last)) && noexcept (sink(char32_t ())))
104
104
{
@@ -248,7 +248,7 @@ namespace sysstr
248
248
};
249
249
250
250
template <utf_encoding From, utf_encoding To>
251
- template <std::ranges::forward_range Range, class Func >
251
+ template <std::ranges::input_range Range, class Func >
252
252
SYS_STRING_FORCE_INLINE
253
253
Func utf_converter<From, To>::for_each_converted(Range && range, Func func)
254
254
noexcept (noexcept (reading(std::forward<Range>(range))) && noexcept (applying(func)))
@@ -258,7 +258,7 @@ namespace sysstr
258
258
259
259
260
260
template <utf_encoding From>
261
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
261
+ template <std::input_iterator It, std::sentinel_for<It> EndIt>
262
262
SYS_STRING_FORCE_INLINE
263
263
char32_t utf32_input<From>::read(It & first, EndIt last) noexcept (noexcept (reading(first,last)))
264
264
{
@@ -318,7 +318,7 @@ namespace sysstr
318
318
}
319
319
320
320
template <utf_encoding From>
321
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
321
+ template <std::input_iterator It, std::sentinel_for<It> EndIt>
322
322
SYS_STRING_FORCE_INLINE
323
323
char32_t utf32_input<From>::read_reversed(It & first, EndIt last) noexcept (noexcept (reading(first, last)))
324
324
{
@@ -334,24 +334,42 @@ namespace sysstr
334
334
if (decoder.error () || first == last)
335
335
return char32_t {U' \uFFFD ' };
336
336
337
- It rewind_point = first;
338
- for ( ; ; )
337
+ if constexpr (std::forward_iterator<It>)
339
338
{
340
- byte = uint8_t (*first);
341
- ++first;
342
- decoder.put (byte);
343
-
344
- if (decoder.done ())
345
- return char32_t {decoder.value ()};
346
-
347
- if (decoder.error ())
348
- {
349
- first = std::move (rewind_point);
350
- return char32_t {U' \uFFFD ' };
339
+ It rewind_point = first;
340
+ for ( ; ; )
341
+ {
342
+ byte = uint8_t (*first);
343
+ ++first;
344
+ decoder.put (byte);
345
+
346
+ if (decoder.done ())
347
+ return char32_t {decoder.value ()};
348
+
349
+ if (decoder.error ())
350
+ {
351
+ first = std::move (rewind_point);
352
+ return char32_t {U' \uFFFD ' };
353
+ }
354
+
355
+ if (first == last)
356
+ return char32_t {u' \uFFFD ' };
357
+ }
358
+ }
359
+ else
360
+ {
361
+ for ( ; ; )
362
+ {
363
+ byte = uint8_t (*first);
364
+ decoder.put (byte);
365
+ if (decoder.error ())
366
+ return char32_t {U' \uFFFD ' };
367
+ ++first;
368
+ if (decoder.done ())
369
+ return char32_t {decoder.value ()};
370
+ if (first == last)
371
+ return char32_t {U' \uFFFD ' };
351
372
}
352
-
353
- if (first == last)
354
- return char32_t {u' \uFFFD ' };
355
373
}
356
374
}
357
375
else if constexpr (From == utf16)
0 commit comments