Branch data 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 : : assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
300 : : { __c1 = __c2; }
301 : :
302 : : static _GLIBCXX_CONSTEXPR bool
303 : : eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
304 : : { 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 : : compare(const char_type* __s1, const char_type* __s2, size_t __n)
316 : : {
317 : : 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 : : return __builtin_memcmp(__s1, __s2, __n);
333 : : }
334 : :
335 : : static _GLIBCXX17_CONSTEXPR size_t
336 : 0 : 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 : 0 : return __builtin_strlen(__s);
343 : : }
344 : :
345 : : static _GLIBCXX17_CONSTEXPR const char_type*
346 : : find(const char_type* __s, size_t __n, const char_type& __a)
347 : : {
348 : : 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 : : 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 : : copy(char_type* __s1, const char_type* __s2, size_t __n)
369 : : {
370 : : if (__n == 0)
371 : : return __s1;
372 : : 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 : : to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
385 : : { 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 : : to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
391 : : { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
392 : :
393 : : static _GLIBCXX_CONSTEXPR bool
394 : : eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
395 : : { 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 : : not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
403 : : { 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 : : assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
420 : : { __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 : : copy(char_type* __s1, const char_type* __s2, size_t __n)
478 : : {
479 : : if (__n == 0)
480 : : return __s1;
481 : : 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
|