@@ -170,31 +170,72 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char> {
170
170
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof () _NOEXCEPT { return int_type (EOF); }
171
171
};
172
172
173
- // char_traits<wchar_t>
174
-
175
- #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
176
- template <>
177
- struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t > {
178
- using char_type = wchar_t ;
179
- using int_type = wint_t ;
173
+ template <class _CharT , class _IntT , _IntT _EOFVal>
174
+ struct __char_traits_base {
175
+ using char_type = _CharT;
176
+ using int_type = _IntT;
180
177
using off_type = streamoff;
181
- using pos_type = streampos;
182
178
using state_type = mbstate_t ;
183
- # if _LIBCPP_STD_VER >= 20
179
+ #if _LIBCPP_STD_VER >= 20
184
180
using comparison_category = strong_ordering;
185
- # endif
181
+ #endif
186
182
187
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
188
- assign (char_type& __c1, const char_type& __c2) _NOEXCEPT {
189
- __c1 = __c2;
183
+ // There are different aliases for the different char types, but they are all aliases to this type
184
+ using pos_type = fpos<mbstate_t >;
185
+
186
+ _LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX17 void
187
+ assign (char_type& __lhs, const char_type& __rhs) _NOEXCEPT {
188
+ __lhs = __rhs;
190
189
}
191
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq (char_type __c1, char_type __c2) _NOEXCEPT {
192
- return __c1 == __c2;
190
+
191
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq (char_type __lhs, char_type __rhs) _NOEXCEPT {
192
+ return __lhs == __rhs;
193
193
}
194
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt (char_type __c1, char_type __c2) _NOEXCEPT {
195
- return __c1 < __c2;
194
+
195
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool lt (char_type __lhs, char_type __rhs) _NOEXCEPT {
196
+ return __lhs < __rhs;
196
197
}
197
198
199
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
200
+ move (char_type* __dest, const char_type* __src, size_t __n) _NOEXCEPT {
201
+ return std::__constexpr_memmove (__dest, __src, __element_count (__n));
202
+ }
203
+
204
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
205
+ copy (char_type* __dest, const char_type* __src, size_t __n) _NOEXCEPT {
206
+ _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES (!std::__is_pointer_in_range (__dest, __dest + __n, __src),
207
+ " char_traits::copy: source and destination ranges overlap" );
208
+ return std::__constexpr_memmove (__dest, __src, __element_count (__n));
209
+ }
210
+
211
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
212
+ assign (char_type* __str, size_t __n, char_type __fill_char) _NOEXCEPT {
213
+ std::fill_n (__str, __n, __fill_char);
214
+ return __str;
215
+ }
216
+
217
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR char_type to_char_type (int_type __c) _NOEXCEPT {
218
+ return char_type (__c);
219
+ }
220
+
221
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type to_int_type (char_type __c) _NOEXCEPT { return int_type (__c); }
222
+
223
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq_int_type (int_type __lhs, int_type __rhs) _NOEXCEPT {
224
+ return __lhs == __rhs;
225
+ }
226
+
227
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type eof () _NOEXCEPT { return _EOFVal; }
228
+
229
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type not_eof (int_type __c) _NOEXCEPT {
230
+ return eq_int_type (__c, eof ()) ? static_cast <int_type>(~eof ()) : __c;
231
+ }
232
+ };
233
+
234
+ // char_traits<wchar_t>
235
+
236
+ #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
237
+ template <>
238
+ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t > : __char_traits_base<wchar_t , wint_t , static_cast <wint_t >(WEOF)> {
198
239
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
199
240
compare (const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
200
241
if (__n == 0 )
@@ -212,63 +253,14 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t> {
212
253
return nullptr ;
213
254
return std::__constexpr_wmemchr (__s, __a, __n);
214
255
}
215
-
216
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
217
- move (char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
218
- return std::__constexpr_memmove (__s1, __s2, __element_count (__n));
219
- }
220
-
221
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
222
- copy (char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
223
- _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES (!std::__is_pointer_in_range (__s1, __s1 + __n, __s2),
224
- " char_traits::copy: source and destination ranges overlap" );
225
- std::__constexpr_memmove (__s1, __s2, __element_count (__n));
226
- return __s1;
227
- }
228
-
229
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
230
- assign (char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
231
- std::fill_n (__s, __n, __a);
232
- return __s;
233
- }
234
-
235
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof (int_type __c) _NOEXCEPT {
236
- return eq_int_type (__c, eof ()) ? ~eof () : __c;
237
- }
238
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type (int_type __c) _NOEXCEPT {
239
- return char_type (__c);
240
- }
241
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type (char_type __c) _NOEXCEPT {
242
- return int_type (__c);
243
- }
244
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type (int_type __c1, int_type __c2) _NOEXCEPT {
245
- return __c1 == __c2;
246
- }
247
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof () _NOEXCEPT { return int_type (WEOF); }
248
256
};
249
257
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
250
258
251
259
#ifndef _LIBCPP_HAS_NO_CHAR8_T
252
260
253
261
template <>
254
- struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t > {
255
- using char_type = char8_t ;
256
- using int_type = unsigned int ;
257
- using off_type = streamoff;
258
- using pos_type = u8streampos;
259
- using state_type = mbstate_t ;
260
- # if _LIBCPP_STD_VER >= 20
261
- using comparison_category = strong_ordering;
262
- # endif
263
-
264
- static inline _LIBCPP_HIDE_FROM_ABI constexpr void assign (char_type& __c1, const char_type& __c2) noexcept {
265
- __c1 = __c2;
266
- }
267
- static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq (char_type __c1, char_type __c2) noexcept {
268
- return __c1 == __c2;
269
- }
270
- static inline _LIBCPP_HIDE_FROM_ABI constexpr bool lt (char_type __c1, char_type __c2) noexcept { return __c1 < __c2; }
271
-
262
+ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t >
263
+ : __char_traits_base<char8_t , unsigned int , static_cast <unsigned int >(EOF)> {
272
264
static _LIBCPP_HIDE_FROM_ABI constexpr int
273
265
compare (const char_type* __s1, const char_type* __s2, size_t __n) noexcept {
274
266
return std::__constexpr_memcmp (__s1, __s2, __element_count (__n));
@@ -282,61 +274,13 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> {
282
274
find (const char_type* __s, size_t __n, const char_type& __a) noexcept {
283
275
return std::__constexpr_memchr (__s, __a, __n);
284
276
}
285
-
286
- static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
287
- move (char_type* __s1, const char_type* __s2, size_t __n) noexcept {
288
- return std::__constexpr_memmove (__s1, __s2, __element_count (__n));
289
- }
290
-
291
- static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
292
- copy (char_type* __s1, const char_type* __s2, size_t __n) noexcept {
293
- _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES (!std::__is_pointer_in_range (__s1, __s1 + __n, __s2),
294
- " char_traits::copy: source and destination ranges overlap" );
295
- std::__constexpr_memmove (__s1, __s2, __element_count (__n));
296
- return __s1;
297
- }
298
-
299
- static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
300
- assign (char_type* __s, size_t __n, char_type __a) noexcept {
301
- std::fill_n (__s, __n, __a);
302
- return __s;
303
- }
304
-
305
- static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type not_eof (int_type __c) noexcept {
306
- return eq_int_type (__c, eof ()) ? ~eof () : __c;
307
- }
308
- static inline _LIBCPP_HIDE_FROM_ABI constexpr char_type to_char_type (int_type __c) noexcept { return char_type (__c); }
309
- static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type to_int_type (char_type __c) noexcept { return int_type (__c); }
310
- static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq_int_type (int_type __c1, int_type __c2) noexcept {
311
- return __c1 == __c2;
312
- }
313
- static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type eof () noexcept { return int_type (EOF); }
314
277
};
315
278
316
279
#endif // _LIBCPP_HAS_NO_CHAR8_T
317
280
318
281
template <>
319
- struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t > {
320
- using char_type = char16_t ;
321
- using int_type = uint_least16_t ;
322
- using off_type = streamoff;
323
- using pos_type = u16streampos;
324
- using state_type = mbstate_t ;
325
- #if _LIBCPP_STD_VER >= 20
326
- using comparison_category = strong_ordering;
327
- #endif
328
-
329
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
330
- assign (char_type& __c1, const char_type& __c2) _NOEXCEPT {
331
- __c1 = __c2;
332
- }
333
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq (char_type __c1, char_type __c2) _NOEXCEPT {
334
- return __c1 == __c2;
335
- }
336
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt (char_type __c1, char_type __c2) _NOEXCEPT {
337
- return __c1 < __c2;
338
- }
339
-
282
+ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t >
283
+ : __char_traits_base<char16_t , uint_least16_t , static_cast <uint_least16_t >(0xFFFF )> {
340
284
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
341
285
compare (const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
342
286
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length (const char_type* __s) _NOEXCEPT;
@@ -349,38 +293,6 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> {
349
293
return nullptr ;
350
294
return __match;
351
295
}
352
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
353
- move (char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
354
- return std::__constexpr_memmove (__s1, __s2, __element_count (__n));
355
- }
356
-
357
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
358
- copy (char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
359
- _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES (!std::__is_pointer_in_range (__s1, __s1 + __n, __s2),
360
- " char_traits::copy: source and destination ranges overlap" );
361
- std::__constexpr_memmove (__s1, __s2, __element_count (__n));
362
- return __s1;
363
- }
364
-
365
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
366
- assign (char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
367
- std::fill_n (__s, __n, __a);
368
- return __s;
369
- }
370
-
371
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof (int_type __c) _NOEXCEPT {
372
- return eq_int_type (__c, eof ()) ? ~eof () : __c;
373
- }
374
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type (int_type __c) _NOEXCEPT {
375
- return char_type (__c);
376
- }
377
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type (char_type __c) _NOEXCEPT {
378
- return int_type (__c);
379
- }
380
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type (int_type __c1, int_type __c2) _NOEXCEPT {
381
- return __c1 == __c2;
382
- }
383
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof () _NOEXCEPT { return int_type (0xFFFF ); }
384
296
};
385
297
386
298
inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
@@ -402,27 +314,8 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t char_traits<char16_t>::length(const
402
314
}
403
315
404
316
template <>
405
- struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t > {
406
- using char_type = char32_t ;
407
- using int_type = uint_least32_t ;
408
- using off_type = streamoff;
409
- using pos_type = u32streampos;
410
- using state_type = mbstate_t ;
411
- #if _LIBCPP_STD_VER >= 20
412
- using comparison_category = strong_ordering;
413
- #endif
414
-
415
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
416
- assign (char_type& __c1, const char_type& __c2) _NOEXCEPT {
417
- __c1 = __c2;
418
- }
419
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq (char_type __c1, char_type __c2) _NOEXCEPT {
420
- return __c1 == __c2;
421
- }
422
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt (char_type __c1, char_type __c2) _NOEXCEPT {
423
- return __c1 < __c2;
424
- }
425
-
317
+ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t >
318
+ : __char_traits_base<char32_t , uint_least32_t , static_cast <uint_least32_t >(0xFFFFFFFF )> {
426
319
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
427
320
compare (const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
428
321
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length (const char_type* __s) _NOEXCEPT;
@@ -435,37 +328,6 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> {
435
328
return nullptr ;
436
329
return __match;
437
330
}
438
-
439
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
440
- move (char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
441
- return std::__constexpr_memmove (__s1, __s2, __element_count (__n));
442
- }
443
-
444
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
445
- copy (char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
446
- std::__constexpr_memmove (__s1, __s2, __element_count (__n));
447
- return __s1;
448
- }
449
-
450
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
451
- assign (char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
452
- std::fill_n (__s, __n, __a);
453
- return __s;
454
- }
455
-
456
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof (int_type __c) _NOEXCEPT {
457
- return eq_int_type (__c, eof ()) ? ~eof () : __c;
458
- }
459
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type (int_type __c) _NOEXCEPT {
460
- return char_type (__c);
461
- }
462
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type (char_type __c) _NOEXCEPT {
463
- return int_type (__c);
464
- }
465
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type (int_type __c1, int_type __c2) _NOEXCEPT {
466
- return __c1 == __c2;
467
- }
468
- static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof () _NOEXCEPT { return int_type (0xFFFFFFFF ); }
469
331
};
470
332
471
333
inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
0 commit comments