Line data Source code
1 : // Character Traits for use by standard string and iostream -*- C++ -*-
2 :
3 : // Copyright (C) 1997-2019 Free Software Foundation, Inc.
4 : //
5 : // This file is part of the GNU ISO C++ Library. This library is free
6 : // software; you can redistribute it and/or modify it under the
7 : // terms of the GNU General Public License as published by the
8 : // Free Software Foundation; either version 3, or (at your option)
9 : // any later version.
10 :
11 : // This library is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 :
16 : // Under Section 7 of GPL version 3, you are granted additional
17 : // permissions described in the GCC Runtime Library Exception, version
18 : // 3.1, as published by the Free Software Foundation.
19 :
20 : // You should have received a copy of the GNU General Public License and
21 : // a copy of the GCC Runtime Library Exception along with this program;
22 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 : // <http://www.gnu.org/licenses/>.
24 :
25 : /** @file bits/char_traits.h
26 : * This is an internal header file, included by other library headers.
27 : * Do not attempt to use it directly. @headername{string}
28 : */
29 :
30 : //
31 : // ISO C++ 14882: 21 Strings library
32 : //
33 :
34 : #ifndef _CHAR_TRAITS_H
35 : #define _CHAR_TRAITS_H 1
36 :
37 : #pragma GCC system_header
38 :
39 : #include <bits/stl_algobase.h> // std::copy, std::fill_n
40 : #include <bits/postypes.h> // For streampos
41 : #include <cwchar> // For WEOF, wmemmove, wmemset, etc.
42 :
43 : #ifndef _GLIBCXX_ALWAYS_INLINE
44 : # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
45 : #endif
46 :
47 : namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
48 : {
49 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 :
51 : /**
52 : * @brief Mapping from character type to associated types.
53 : *
54 : * @note This is an implementation class for the generic version
55 : * of char_traits. It defines int_type, off_type, pos_type, and
56 : * state_type. By default these are unsigned long, streamoff,
57 : * streampos, and mbstate_t. Users who need a different set of
58 : * types, but who don't need to change the definitions of any function
59 : * defined in char_traits, can specialize __gnu_cxx::_Char_types
60 : * while leaving __gnu_cxx::char_traits alone. */
61 : template<typename _CharT>
62 : struct _Char_types
63 : {
64 : typedef unsigned long int_type;
65 : typedef std::streampos pos_type;
66 : typedef std::streamoff off_type;
67 : typedef std::mbstate_t state_type;
68 : };
69 :
70 :
71 : /**
72 : * @brief Base class used to implement std::char_traits.
73 : *
74 : * @note For any given actual character type, this definition is
75 : * probably wrong. (Most of the member functions are likely to be
76 : * right, but the int_type and state_type typedefs, and the eof()
77 : * member function, are likely to be wrong.) The reason this class
78 : * exists is so users can specialize it. Classes in namespace std
79 : * may not be specialized for fundamental types, but classes in
80 : * namespace __gnu_cxx may be.
81 : *
82 : * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
83 : * for advice on how to make use of this class for @a unusual character
84 : * types. Also, check out include/ext/pod_char_traits.h.
85 : */
86 : template<typename _CharT>
87 : struct char_traits
88 : {
89 : typedef _CharT char_type;
90 : typedef typename _Char_types<_CharT>::int_type int_type;
91 : typedef typename _Char_types<_CharT>::pos_type pos_type;
92 : typedef typename _Char_types<_CharT>::off_type off_type;
93 : typedef typename _Char_types<_CharT>::state_type state_type;
94 :
95 : static _GLIBCXX14_CONSTEXPR void
96 : assign(char_type& __c1, const char_type& __c2)
97 : { __c1 = __c2; }
98 :
99 : static _GLIBCXX_CONSTEXPR bool
100 : eq(const char_type& __c1, const char_type& __c2)
101 : { return __c1 == __c2; }
102 :
103 : static _GLIBCXX_CONSTEXPR bool
104 : lt(const char_type& __c1, const char_type& __c2)
105 : { return __c1 < __c2; }
106 :
107 : static _GLIBCXX14_CONSTEXPR int
108 : compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
109 :
110 : static _GLIBCXX14_CONSTEXPR std::size_t
111 : length(const char_type* __s);
112 :
113 : static _GLIBCXX14_CONSTEXPR const char_type*
114 : find(const char_type* __s, std::size_t __n, const char_type& __a);
115 :
116 : static char_type*
117 : move(char_type* __s1, const char_type* __s2, std::size_t __n);
118 :
119 : static char_type*
120 : copy(char_type* __s1, const char_type* __s2, std::size_t __n);
121 :
122 : static char_type*
123 : assign(char_type* __s, std::size_t __n, char_type __a);
124 :
125 : static _GLIBCXX_CONSTEXPR char_type
126 : to_char_type(const int_type& __c)
127 : { return static_cast<char_type>(__c); }
128 :
129 : static _GLIBCXX_CONSTEXPR int_type
130 : to_int_type(const char_type& __c)
131 : { return static_cast<int_type>(__c); }
132 :
133 : static _GLIBCXX_CONSTEXPR bool
134 : eq_int_type(const int_type& __c1, const int_type& __c2)
135 : { return __c1 == __c2; }
136 :
137 : static _GLIBCXX_CONSTEXPR int_type
138 : eof()
139 : { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
140 :
141 : static _GLIBCXX_CONSTEXPR int_type
142 : not_eof(const int_type& __c)
143 : { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
144 : };
145 :
146 : template<typename _CharT>
147 : _GLIBCXX14_CONSTEXPR int
148 : char_traits<_CharT>::
149 : compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
150 : {
151 : for (std::size_t __i = 0; __i < __n; ++__i)
152 : if (lt(__s1[__i], __s2[__i]))
153 : return -1;
154 : else if (lt(__s2[__i], __s1[__i]))
155 : return 1;
156 : return 0;
157 : }
158 :
159 : template<typename _CharT>
160 : _GLIBCXX14_CONSTEXPR std::size_t
161 : char_traits<_CharT>::
162 : length(const char_type* __p)
163 : {
164 : std::size_t __i = 0;
165 : while (!eq(__p[__i], char_type()))
166 : ++__i;
167 : return __i;
168 : }
169 :
170 : template<typename _CharT>
171 : _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
172 : char_traits<_CharT>::
173 : find(const char_type* __s, std::size_t __n, const char_type& __a)
174 : {
175 : for (std::size_t __i = 0; __i < __n; ++__i)
176 : if (eq(__s[__i], __a))
177 : return __s + __i;
178 : return 0;
179 : }
180 :
181 : template<typename _CharT>
182 : typename char_traits<_CharT>::char_type*
183 : char_traits<_CharT>::
184 : move(char_type* __s1, const char_type* __s2, std::size_t __n)
185 : {
186 : if (__n == 0)
187 : return __s1;
188 : return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
189 : __n * sizeof(char_type)));
190 : }
191 :
192 : template<typename _CharT>
193 : typename char_traits<_CharT>::char_type*
194 : char_traits<_CharT>::
195 : copy(char_type* __s1, const char_type* __s2, std::size_t __n)
196 : {
197 : // NB: Inline std::copy so no recursive dependencies.
198 : std::copy(__s2, __s2 + __n, __s1);
199 : return __s1;
200 : }
201 :
202 : template<typename _CharT>
203 : typename char_traits<_CharT>::char_type*
204 : char_traits<_CharT>::
205 : assign(char_type* __s, std::size_t __n, char_type __a)
206 : {
207 : // NB: Inline std::fill_n so no recursive dependencies.
208 : std::fill_n(__s, __n, __a);
209 : return __s;
210 : }
211 :
212 : _GLIBCXX_END_NAMESPACE_VERSION
213 : } // namespace
214 :
215 : namespace std _GLIBCXX_VISIBILITY(default)
216 : {
217 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
218 :
219 : #if __cplusplus >= 201703L
220 : #define __cpp_lib_constexpr_char_traits 201611
221 :
222 : /**
223 : * @brief Determine whether the characters of a NULL-terminated
224 : * string are known at compile time.
225 : * @param __s The string.
226 : *
227 : * Assumes that _CharT is a built-in character type.
228 : */
229 : template<typename _CharT>
230 : static _GLIBCXX_ALWAYS_INLINE constexpr bool
231 : __constant_string_p(const _CharT* __s)
232 : {
233 : #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
234 : (void) __s;
235 : // In constexpr contexts all strings should be constant.
236 : return __builtin_is_constant_evaluated();
237 : #else
238 : while (__builtin_constant_p(*__s) && *__s)
239 : __s++;
240 : return __builtin_constant_p(*__s);
241 : #endif
242 : }
243 :
244 : /**
245 : * @brief Determine whether the characters of a character array are
246 : * known at compile time.
247 : * @param __a The character array.
248 : * @param __n Number of characters.
249 : *
250 : * Assumes that _CharT is a built-in character type.
251 : */
252 : template<typename _CharT>
253 : static _GLIBCXX_ALWAYS_INLINE constexpr bool
254 : __constant_char_array_p(const _CharT* __a, size_t __n)
255 : {
256 : #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
257 : (void) __a;
258 : (void) __n;
259 : // In constexpr contexts all character arrays should be constant.
260 : return __builtin_is_constant_evaluated();
261 : #else
262 : size_t __i = 0;
263 : while (__i < __n && __builtin_constant_p(__a[__i]))
264 : __i++;
265 : return __i == __n;
266 : #endif
267 : }
268 : #endif
269 :
270 : // 21.1
271 : /**
272 : * @brief Basis for explicit traits specializations.
273 : *
274 : * @note For any given actual character type, this definition is
275 : * probably wrong. Since this is just a thin wrapper around
276 : * __gnu_cxx::char_traits, it is possible to achieve a more
277 : * appropriate definition by specializing __gnu_cxx::char_traits.
278 : *
279 : * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
280 : * for advice on how to make use of this class for @a unusual character
281 : * types. Also, check out include/ext/pod_char_traits.h.
282 : */
283 : template<class _CharT>
284 : struct char_traits : public __gnu_cxx::char_traits<_CharT>
285 : { };
286 :
287 :
288 : /// 21.1.3.1 char_traits specializations
289 : template<>
290 : struct char_traits<char>
291 : {
292 : typedef char char_type;
293 : typedef int int_type;
294 : typedef streampos pos_type;
295 : typedef streamoff off_type;
296 : typedef mbstate_t state_type;
297 :
298 : static _GLIBCXX17_CONSTEXPR void
299 1934789432 : assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
300 1542471574 : { __c1 = __c2; }
301 :
302 : static _GLIBCXX_CONSTEXPR bool
303 0 : eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
304 0 : { return __c1 == __c2; }
305 :
306 : static _GLIBCXX_CONSTEXPR bool
307 : lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
308 : {
309 : // LWG 467.
310 : return (static_cast<unsigned char>(__c1)
311 : < static_cast<unsigned char>(__c2));
312 : }
313 :
314 : static _GLIBCXX17_CONSTEXPR int
315 65411722 : compare(const char_type* __s1, const char_type* __s2, size_t __n)
316 : {
317 65411722 : if (__n == 0)
318 : return 0;
319 : #if __cplusplus >= 201703L
320 : if (__builtin_constant_p(__n)
321 : && __constant_char_array_p(__s1, __n)
322 : && __constant_char_array_p(__s2, __n))
323 : {
324 : for (size_t __i = 0; __i < __n; ++__i)
325 : if (lt(__s1[__i], __s2[__i]))
326 : return -1;
327 : else if (lt(__s2[__i], __s1[__i]))
328 : return 1;
329 : return 0;
330 : }
331 : #endif
332 65211420 : return __builtin_memcmp(__s1, __s2, __n);
333 : }
334 :
335 : static _GLIBCXX17_CONSTEXPR size_t
336 70647205 : length(const char_type* __s)
337 : {
338 : #if __cplusplus >= 201703L
339 : if (__constant_string_p(__s))
340 : return __gnu_cxx::char_traits<char_type>::length(__s);
341 : #endif
342 70620529 : return __builtin_strlen(__s);
343 : }
344 :
345 : static _GLIBCXX17_CONSTEXPR const char_type*
346 0 : find(const char_type* __s, size_t __n, const char_type& __a)
347 : {
348 0 : if (__n == 0)
349 : return 0;
350 : #if __cplusplus >= 201703L
351 : if (__builtin_constant_p(__n)
352 : && __builtin_constant_p(__a)
353 : && __constant_char_array_p(__s, __n))
354 : return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
355 : #endif
356 0 : return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
357 : }
358 :
359 : static char_type*
360 : move(char_type* __s1, const char_type* __s2, size_t __n)
361 : {
362 : if (__n == 0)
363 : return __s1;
364 : return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
365 : }
366 :
367 : static char_type*
368 1460131843 : copy(char_type* __s1, const char_type* __s2, size_t __n)
369 : {
370 379817985 : if (__n == 0)
371 : return __s1;
372 1441261632 : return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
373 : }
374 :
375 : static char_type*
376 : assign(char_type* __s, size_t __n, char_type __a)
377 : {
378 : if (__n == 0)
379 : return __s;
380 : return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
381 : }
382 :
383 : static _GLIBCXX_CONSTEXPR char_type
384 1846980 : to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
385 1846980 : { return static_cast<char_type>(__c); }
386 :
387 : // To keep both the byte 0xff and the eof symbol 0xffffffff
388 : // from ending up as 0xffffffff.
389 : static _GLIBCXX_CONSTEXPR int_type
390 894484 : to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
391 894484 : { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
392 :
393 : static _GLIBCXX_CONSTEXPR bool
394 0 : eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
395 0 : { return __c1 == __c2; }
396 :
397 : static _GLIBCXX_CONSTEXPR int_type
398 : eof() _GLIBCXX_NOEXCEPT
399 : { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
400 :
401 : static _GLIBCXX_CONSTEXPR int_type
402 0 : not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
403 0 : { return (__c == eof()) ? 0 : __c; }
404 : };
405 :
406 :
407 : #ifdef _GLIBCXX_USE_WCHAR_T
408 : /// 21.1.3.2 char_traits specializations
409 : template<>
410 : struct char_traits<wchar_t>
411 : {
412 : typedef wchar_t char_type;
413 : typedef wint_t int_type;
414 : typedef streamoff off_type;
415 : typedef wstreampos pos_type;
416 : typedef mbstate_t state_type;
417 :
418 : static _GLIBCXX17_CONSTEXPR void
419 0 : assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
420 0 : { __c1 = __c2; }
421 :
422 : static _GLIBCXX_CONSTEXPR bool
423 : eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
424 : { return __c1 == __c2; }
425 :
426 : static _GLIBCXX_CONSTEXPR bool
427 : lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
428 : { return __c1 < __c2; }
429 :
430 : static _GLIBCXX17_CONSTEXPR int
431 : compare(const char_type* __s1, const char_type* __s2, size_t __n)
432 : {
433 : if (__n == 0)
434 : return 0;
435 : #if __cplusplus >= 201703L
436 : if (__builtin_constant_p(__n)
437 : && __constant_char_array_p(__s1, __n)
438 : && __constant_char_array_p(__s2, __n))
439 : return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
440 : #endif
441 : return wmemcmp(__s1, __s2, __n);
442 : }
443 :
444 : static _GLIBCXX17_CONSTEXPR size_t
445 : length(const char_type* __s)
446 : {
447 : #if __cplusplus >= 201703L
448 : if (__constant_string_p(__s))
449 : return __gnu_cxx::char_traits<char_type>::length(__s);
450 : #endif
451 : return wcslen(__s);
452 : }
453 :
454 : static _GLIBCXX17_CONSTEXPR const char_type*
455 : find(const char_type* __s, size_t __n, const char_type& __a)
456 : {
457 : if (__n == 0)
458 : return 0;
459 : #if __cplusplus >= 201703L
460 : if (__builtin_constant_p(__n)
461 : && __builtin_constant_p(__a)
462 : && __constant_char_array_p(__s, __n))
463 : return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
464 : #endif
465 : return wmemchr(__s, __a, __n);
466 : }
467 :
468 : static char_type*
469 : move(char_type* __s1, const char_type* __s2, size_t __n)
470 : {
471 : if (__n == 0)
472 : return __s1;
473 : return wmemmove(__s1, __s2, __n);
474 : }
475 :
476 : static char_type*
477 0 : copy(char_type* __s1, const char_type* __s2, size_t __n)
478 : {
479 0 : if (__n == 0)
480 : return __s1;
481 0 : return wmemcpy(__s1, __s2, __n);
482 : }
483 :
484 : static char_type*
485 : assign(char_type* __s, size_t __n, char_type __a)
486 : {
487 : if (__n == 0)
488 : return __s;
489 : return wmemset(__s, __a, __n);
490 : }
491 :
492 : static _GLIBCXX_CONSTEXPR char_type
493 : to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
494 : { return char_type(__c); }
495 :
496 : static _GLIBCXX_CONSTEXPR int_type
497 : to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
498 : { return int_type(__c); }
499 :
500 : static _GLIBCXX_CONSTEXPR bool
501 : eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
502 : { return __c1 == __c2; }
503 :
504 : static _GLIBCXX_CONSTEXPR int_type
505 : eof() _GLIBCXX_NOEXCEPT
506 : { return static_cast<int_type>(WEOF); }
507 :
508 : static _GLIBCXX_CONSTEXPR int_type
509 : not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
510 : { return eq_int_type(__c, eof()) ? 0 : __c; }
511 : };
512 : #endif //_GLIBCXX_USE_WCHAR_T
513 :
514 : #ifdef _GLIBCXX_USE_CHAR8_T
515 : template<>
516 : struct char_traits<char8_t>
517 : {
518 : typedef char8_t char_type;
519 : typedef unsigned int int_type;
520 : typedef u8streampos pos_type;
521 : typedef streamoff off_type;
522 : typedef mbstate_t state_type;
523 :
524 : static _GLIBCXX17_CONSTEXPR void
525 : assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
526 : { __c1 = __c2; }
527 :
528 : static _GLIBCXX_CONSTEXPR bool
529 : eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
530 : { return __c1 == __c2; }
531 :
532 : static _GLIBCXX_CONSTEXPR bool
533 : lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
534 : { return __c1 < __c2; }
535 :
536 : static _GLIBCXX17_CONSTEXPR int
537 : compare(const char_type* __s1, const char_type* __s2, size_t __n)
538 : {
539 : if (__n == 0)
540 : return 0;
541 : #if __cplusplus > 201402
542 : if (__builtin_constant_p(__n)
543 : && __constant_char_array_p(__s1, __n)
544 : && __constant_char_array_p(__s2, __n))
545 : return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
546 : #endif
547 : return __builtin_memcmp(__s1, __s2, __n);
548 : }
549 :
550 : static _GLIBCXX17_CONSTEXPR size_t
551 : length(const char_type* __s)
552 : {
553 : #if __cplusplus > 201402
554 : if (__constant_string_p(__s))
555 : return __gnu_cxx::char_traits<char_type>::length(__s);
556 : #endif
557 : size_t __i = 0;
558 : while (!eq(__s[__i], char_type()))
559 : ++__i;
560 : return __i;
561 : }
562 :
563 : static _GLIBCXX17_CONSTEXPR const char_type*
564 : find(const char_type* __s, size_t __n, const char_type& __a)
565 : {
566 : if (__n == 0)
567 : return 0;
568 : #if __cplusplus > 201402
569 : if (__builtin_constant_p(__n)
570 : && __builtin_constant_p(__a)
571 : && __constant_char_array_p(__s, __n))
572 : return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
573 : #endif
574 : return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
575 : }
576 :
577 : static char_type*
578 : move(char_type* __s1, const char_type* __s2, size_t __n)
579 : {
580 : if (__n == 0)
581 : return __s1;
582 : return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
583 : }
584 :
585 : static char_type*
586 : copy(char_type* __s1, const char_type* __s2, size_t __n)
587 : {
588 : if (__n == 0)
589 : return __s1;
590 : return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
591 : }
592 :
593 : static char_type*
594 : assign(char_type* __s, size_t __n, char_type __a)
595 : {
596 : if (__n == 0)
597 : return __s;
598 : return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
599 : }
600 :
601 : static _GLIBCXX_CONSTEXPR char_type
602 : to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
603 : { return char_type(__c); }
604 :
605 : static _GLIBCXX_CONSTEXPR int_type
606 : to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
607 : { return int_type(__c); }
608 :
609 : static _GLIBCXX_CONSTEXPR bool
610 : eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
611 : { return __c1 == __c2; }
612 :
613 : static _GLIBCXX_CONSTEXPR int_type
614 : eof() _GLIBCXX_NOEXCEPT
615 : { return static_cast<int_type>(-1); }
616 :
617 : static _GLIBCXX_CONSTEXPR int_type
618 : not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
619 : { return eq_int_type(__c, eof()) ? 0 : __c; }
620 : };
621 : #endif //_GLIBCXX_USE_CHAR8_T
622 :
623 : _GLIBCXX_END_NAMESPACE_VERSION
624 : } // namespace
625 :
626 : #if __cplusplus >= 201103L
627 :
628 : #include <cstdint>
629 :
630 : namespace std _GLIBCXX_VISIBILITY(default)
631 : {
632 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
633 :
634 : template<>
635 : struct char_traits<char16_t>
636 : {
637 : typedef char16_t char_type;
638 : #ifdef _GLIBCXX_USE_C99_STDINT_TR1
639 : typedef uint_least16_t int_type;
640 : #elif defined __UINT_LEAST16_TYPE__
641 : typedef __UINT_LEAST16_TYPE__ int_type;
642 : #else
643 : typedef make_unsigned<char16_t>::type int_type;
644 : #endif
645 : typedef streamoff off_type;
646 : typedef u16streampos pos_type;
647 : typedef mbstate_t state_type;
648 :
649 : static _GLIBCXX17_CONSTEXPR void
650 : assign(char_type& __c1, const char_type& __c2) noexcept
651 : { __c1 = __c2; }
652 :
653 : static constexpr bool
654 : eq(const char_type& __c1, const char_type& __c2) noexcept
655 : { return __c1 == __c2; }
656 :
657 : static constexpr bool
658 : lt(const char_type& __c1, const char_type& __c2) noexcept
659 : { return __c1 < __c2; }
660 :
661 : static _GLIBCXX17_CONSTEXPR int
662 : compare(const char_type* __s1, const char_type* __s2, size_t __n)
663 : {
664 : for (size_t __i = 0; __i < __n; ++__i)
665 : if (lt(__s1[__i], __s2[__i]))
666 : return -1;
667 : else if (lt(__s2[__i], __s1[__i]))
668 : return 1;
669 : return 0;
670 : }
671 :
672 : static _GLIBCXX17_CONSTEXPR size_t
673 : length(const char_type* __s)
674 : {
675 : size_t __i = 0;
676 : while (!eq(__s[__i], char_type()))
677 : ++__i;
678 : return __i;
679 : }
680 :
681 : static _GLIBCXX17_CONSTEXPR const char_type*
682 : find(const char_type* __s, size_t __n, const char_type& __a)
683 : {
684 : for (size_t __i = 0; __i < __n; ++__i)
685 : if (eq(__s[__i], __a))
686 : return __s + __i;
687 : return 0;
688 : }
689 :
690 : static char_type*
691 : move(char_type* __s1, const char_type* __s2, size_t __n)
692 : {
693 : if (__n == 0)
694 : return __s1;
695 : return (static_cast<char_type*>
696 : (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
697 : }
698 :
699 : static char_type*
700 : copy(char_type* __s1, const char_type* __s2, size_t __n)
701 : {
702 : if (__n == 0)
703 : return __s1;
704 : return (static_cast<char_type*>
705 : (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
706 : }
707 :
708 : static char_type*
709 : assign(char_type* __s, size_t __n, char_type __a)
710 : {
711 : for (size_t __i = 0; __i < __n; ++__i)
712 : assign(__s[__i], __a);
713 : return __s;
714 : }
715 :
716 : static constexpr char_type
717 : to_char_type(const int_type& __c) noexcept
718 : { return char_type(__c); }
719 :
720 : static constexpr int_type
721 : to_int_type(const char_type& __c) noexcept
722 : { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
723 :
724 : static constexpr bool
725 : eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
726 : { return __c1 == __c2; }
727 :
728 : static constexpr int_type
729 : eof() noexcept
730 : { return static_cast<int_type>(-1); }
731 :
732 : static constexpr int_type
733 : not_eof(const int_type& __c) noexcept
734 : { return eq_int_type(__c, eof()) ? 0 : __c; }
735 : };
736 :
737 : template<>
738 : struct char_traits<char32_t>
739 : {
740 : typedef char32_t char_type;
741 : #ifdef _GLIBCXX_USE_C99_STDINT_TR1
742 : typedef uint_least32_t int_type;
743 : #elif defined __UINT_LEAST32_TYPE__
744 : typedef __UINT_LEAST32_TYPE__ int_type;
745 : #else
746 : typedef make_unsigned<char32_t>::type int_type;
747 : #endif
748 : typedef streamoff off_type;
749 : typedef u32streampos pos_type;
750 : typedef mbstate_t state_type;
751 :
752 : static _GLIBCXX17_CONSTEXPR void
753 : assign(char_type& __c1, const char_type& __c2) noexcept
754 : { __c1 = __c2; }
755 :
756 : static constexpr bool
757 : eq(const char_type& __c1, const char_type& __c2) noexcept
758 : { return __c1 == __c2; }
759 :
760 : static constexpr bool
761 : lt(const char_type& __c1, const char_type& __c2) noexcept
762 : { return __c1 < __c2; }
763 :
764 : static _GLIBCXX17_CONSTEXPR int
765 : compare(const char_type* __s1, const char_type* __s2, size_t __n)
766 : {
767 : for (size_t __i = 0; __i < __n; ++__i)
768 : if (lt(__s1[__i], __s2[__i]))
769 : return -1;
770 : else if (lt(__s2[__i], __s1[__i]))
771 : return 1;
772 : return 0;
773 : }
774 :
775 : static _GLIBCXX17_CONSTEXPR size_t
776 : length(const char_type* __s)
777 : {
778 : size_t __i = 0;
779 : while (!eq(__s[__i], char_type()))
780 : ++__i;
781 : return __i;
782 : }
783 :
784 : static _GLIBCXX17_CONSTEXPR const char_type*
785 : find(const char_type* __s, size_t __n, const char_type& __a)
786 : {
787 : for (size_t __i = 0; __i < __n; ++__i)
788 : if (eq(__s[__i], __a))
789 : return __s + __i;
790 : return 0;
791 : }
792 :
793 : static char_type*
794 : move(char_type* __s1, const char_type* __s2, size_t __n)
795 : {
796 : if (__n == 0)
797 : return __s1;
798 : return (static_cast<char_type*>
799 : (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
800 : }
801 :
802 : static char_type*
803 : copy(char_type* __s1, const char_type* __s2, size_t __n)
804 : {
805 : if (__n == 0)
806 : return __s1;
807 : return (static_cast<char_type*>
808 : (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
809 : }
810 :
811 : static char_type*
812 : assign(char_type* __s, size_t __n, char_type __a)
813 : {
814 : for (size_t __i = 0; __i < __n; ++__i)
815 : assign(__s[__i], __a);
816 : return __s;
817 : }
818 :
819 : static constexpr char_type
820 : to_char_type(const int_type& __c) noexcept
821 : { return char_type(__c); }
822 :
823 : static constexpr int_type
824 : to_int_type(const char_type& __c) noexcept
825 : { return int_type(__c); }
826 :
827 : static constexpr bool
828 : eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
829 : { return __c1 == __c2; }
830 :
831 : static constexpr int_type
832 : eof() noexcept
833 : { return static_cast<int_type>(-1); }
834 :
835 : static constexpr int_type
836 : not_eof(const int_type& __c) noexcept
837 : { return eq_int_type(__c, eof()) ? 0 : __c; }
838 : };
839 :
840 : _GLIBCXX_END_NAMESPACE_VERSION
841 : } // namespace
842 :
843 : #endif // C++11
844 :
845 : #endif // _CHAR_TRAITS_H
|