@@ -121,10 +121,17 @@ namespace sysstr
121
121
SYS_STRING_FORCE_INLINE
122
122
constexpr void operator ()(char32_t value) noexcept (noexcept (sink(utf_char_of<To>())))
123
123
{
124
- utf_codepoint_encoder<To, false > encoder;
125
- encoder.put (value);
126
- for (auto first = encoder.begin (), last = encoder.end (); first != last; ++first)
127
- sink (*first);
124
+ if constexpr (To != utf32)
125
+ {
126
+ utf_codepoint_encoder<To, false > encoder;
127
+ encoder.put (value);
128
+ for (auto first = encoder.begin (), last = encoder.end (); first != last; ++first)
129
+ sink (*first);
130
+ }
131
+ else
132
+ {
133
+ sink (value);
134
+ }
128
135
}
129
136
};
130
137
// Moronic GCC refuses to accept deduction guide not on namespace level
@@ -135,28 +142,6 @@ namespace sysstr
135
142
{ return writer<Sink>(sink); }
136
143
};
137
144
138
- template <>
139
- struct utf32_output <utf32>
140
- {
141
- template <class Sink >
142
- struct writer
143
- {
144
- Sink sink;
145
-
146
- writer (Sink s) : sink(s) {}
147
-
148
- constexpr void operator ()(char32_t value) noexcept (noexcept (sink(value)))
149
- {
150
- sink (value);
151
- }
152
- };
153
- // Moronic GCC refuses to accept deduction guide not on namespace level
154
- // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79501
155
- // template<class Sink> writer(Sink sink) -> writer<Sink>;
156
- template <class Sink > static auto make_writer (Sink sink) -> writer<Sink>
157
- { return writer<Sink>(sink); }
158
- };
159
-
160
145
template <utf_encoding From, utf_encoding To>
161
146
template <std::ranges::forward_range Range, class Func >
162
147
SYS_STRING_FORCE_INLINE
@@ -167,141 +152,126 @@ namespace sysstr
167
152
}
168
153
169
154
170
- // MARK:- UTF-16
171
-
172
- template <>
155
+ template <utf_encoding From>
173
156
template <std::forward_iterator It, std::sentinel_for<It> EndIt>
174
157
SYS_STRING_FORCE_INLINE
175
- char32_t utf32_input<utf16 >::read(It & first, EndIt last) noexcept (noexcept (reading(first,last)))
158
+ char32_t utf32_input<From >::read(It & first, EndIt last) noexcept (noexcept (reading(first,last)))
176
159
{
177
- utf_codepoint_decoder<utf16> decoder;
160
+ if constexpr (From == utf8)
161
+ {
162
+ uint8_t byte = uint8_t (*first);
163
+ ++first;
164
+ if (byte <= 0x7f )
165
+ return char32_t {byte};
178
166
179
- decoder. put ( uint16_t (*first)) ;
180
- ++first ;
181
- if (decoder.done () )
182
- return char32_t {decoder. value () };
167
+ utf_codepoint_decoder<utf8> decoder;
168
+ decoder. put (byte) ;
169
+ if (decoder.error () || first == last )
170
+ return char32_t {U ' \uFFFD ' };
183
171
184
- if (decoder.error () || first == last)
185
- return char32_t {U' \uFFFD ' };
172
+ for ( ; ; )
173
+ {
174
+ byte = uint8_t (*first);
175
+ decoder.put (byte);
176
+ if (decoder.error ())
177
+ return char32_t {U' \uFFFD ' };
178
+ ++first;
179
+ if (decoder.done ())
180
+ return char32_t {decoder.value ()};
181
+ if (first == last)
182
+ return char32_t {U' \uFFFD ' };
183
+ }
184
+ }
185
+ else if constexpr (From == utf16)
186
+ {
187
+ utf_codepoint_decoder<utf16> decoder;
186
188
187
- decoder.put (uint16_t (*first));
188
- if (!decoder. done ())
189
- return char32_t {U ' \uFFFD ' };
190
- ++first ;
189
+ decoder.put (uint16_t (*first));
190
+ ++first;
191
+ if (decoder. done ())
192
+ return char32_t {decoder. value ()} ;
191
193
192
- return char32_t { decoder.value ()};
193
- }
194
+ if ( decoder.error () || first == last)
195
+ return char32_t {U ' \uFFFD ' };
194
196
195
- template <>
196
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
197
- SYS_STRING_FORCE_INLINE
198
- char32_t utf32_input<utf16>::read_reversed(It & first, EndIt last) noexcept (noexcept (reading(first, last)))
199
- {
200
- utf_reverse_codepoint_decoder<utf16> decoder;
197
+ decoder.put (uint16_t (*first));
198
+ if (!decoder.done ())
199
+ return char32_t {U' \uFFFD ' };
200
+ ++first;
201
201
202
- decoder.put (uint16_t (*first));
203
- ++first;
204
- if (decoder.done ())
205
202
return char32_t {decoder.value ()};
203
+ }
204
+ else if constexpr (From == utf32)
205
+ {
206
+ utf_codepoint_decoder<utf32> decoder;
207
+ bool res = decoder.put (uint32_t (*first));
208
+ ++first;
209
+ return res ? char32_t {decoder.value ()} : U' \uFFFD ' ;
210
+ }
206
211
207
- if (decoder.error () || first == last)
208
- return char32_t {U' \uFFFD ' };
209
-
210
- decoder.put (uint16_t (*first));
211
- if (!decoder.done ())
212
- return char32_t {U' \uFFFD ' };
213
- ++first;
214
212
215
- return char32_t {decoder.value ()};
216
213
}
217
214
218
- // MARK:- UTF-8
219
-
220
- template <>
215
+ template <utf_encoding From>
221
216
template <std::forward_iterator It, std::sentinel_for<It> EndIt>
222
217
SYS_STRING_FORCE_INLINE
223
- char32_t utf32_input<utf8 >::read (It & first, EndIt last) noexcept (noexcept (reading(first, last)))
218
+ char32_t utf32_input<From >::read_reversed (It & first, EndIt last) noexcept (noexcept (reading(first, last)))
224
219
{
225
- uint8_t byte = uint8_t (*first);
226
- ++first;
227
- if (byte <= 0x7f )
228
- return char32_t {byte};
229
-
230
- utf_codepoint_decoder<utf8> decoder;
231
- decoder.put (byte);
232
- if (decoder.error () || first == last)
233
- return char32_t {U' \uFFFD ' };
234
-
235
- for ( ; ; )
220
+ if constexpr (From == utf8)
236
221
{
237
- byte = uint8_t (*first);
238
- decoder.put (byte);
239
- if (decoder.error ())
240
- return char32_t {U' \uFFFD ' };
222
+ uint8_t byte = uint8_t (*first);
241
223
++first;
242
- if (decoder.done ())
243
- return char32_t {decoder.value ()};
244
- if (first == last)
224
+ if (byte <= 0x7f )
225
+ return char32_t {byte};
226
+
227
+ utf_reverse_codepoint_decoder<utf8> decoder;
228
+ decoder.put (byte);
229
+ if (decoder.error () || first == last)
245
230
return char32_t {U' \uFFFD ' };
246
- }
247
- }
248
-
249
- template <>
250
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
251
- SYS_STRING_FORCE_INLINE
252
- char32_t utf32_input<utf8>::read_reversed(It & first, EndIt last) noexcept (noexcept (reading(first, last)))
253
- {
254
- uint8_t byte = uint8_t (*first);
255
- ++first;
256
- if (byte <= 0x7f )
257
- return char32_t {byte};
258
-
259
- utf_reverse_codepoint_decoder<utf8> decoder;
260
- decoder.put (byte);
261
- if (decoder.error () || first == last)
262
- return char32_t {U' \uFFFD ' };
263
231
264
- It rewind_point = first;
265
- for ( ; ; )
232
+ It rewind_point = first;
233
+ for ( ; ; )
234
+ {
235
+ byte = uint8_t (*first);
236
+ ++first;
237
+ decoder.put (byte);
238
+
239
+ if (decoder.done ())
240
+ return char32_t {decoder.value ()};
241
+
242
+ if (decoder.error ())
243
+ {
244
+ first = std::move (rewind_point);
245
+ return char32_t {U' \uFFFD ' };
246
+ }
247
+
248
+ if (first == last)
249
+ return char32_t {u' \uFFFD ' };
250
+ }
251
+ }
252
+ else if constexpr (From == utf16)
266
253
{
267
- byte = uint8_t (*first);
268
- ++first;
269
- decoder.put (byte);
254
+ utf_reverse_codepoint_decoder<utf16> decoder;
270
255
256
+ decoder.put (uint16_t (*first));
257
+ ++first;
271
258
if (decoder.done ())
272
259
return char32_t {decoder.value ()};
273
-
274
- if (decoder.error ())
275
- {
276
- first = std::move (rewind_point);
277
- return char32_t {U' \uFFFD ' };
278
- }
279
-
280
- if (first == last)
281
- return char32_t {u' \uFFFD ' };
282
- }
283
- }
284
260
285
- // MARK:- UTF-32
261
+ if (decoder.error () || first == last)
262
+ return char32_t {U' \uFFFD ' };
286
263
287
-
288
- template <>
289
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
290
- SYS_STRING_FORCE_INLINE
291
- char32_t utf32_input<utf32>::read(It & first, EndIt last) noexcept (noexcept (reading(first, last)))
292
- {
293
- utf_codepoint_decoder<utf32> decoder;
294
- bool res = decoder.put (uint32_t (*first));
295
- ++first;
296
- return res ? char32_t {decoder.value ()} : U' \uFFFD ' ;
297
- }
264
+ decoder.put (uint16_t (*first));
265
+ if (!decoder.done ())
266
+ return char32_t {U' \uFFFD ' };
267
+ ++first;
298
268
299
- template <>
300
- template <std::forward_iterator It, std::sentinel_for<It> EndIt>
301
- SYS_STRING_FORCE_INLINE
302
- char32_t utf32_input<utf32>::read_reversed(It & first, EndIt last) noexcept ( noexcept (reading(first, last)))
303
- {
304
- return utf32_input::read (first, last);
269
+ return char32_t {decoder. value ()};
270
+ }
271
+ else if constexpr (From == utf32)
272
+ {
273
+ return utf32_input::read (first, last);
274
+ }
305
275
}
306
276
}
307
277
0 commit comments