]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/char_traits.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / char_traits.h
CommitLineData
725dc051
BK
1// Character Traits for use by standard string and iostream -*- C++ -*-
2
8d9254fc 3// Copyright (C) 1997-2020 Free Software Foundation, Inc.
725dc051
BK
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
748086b7 8// Free Software Foundation; either version 3, or (at your option)
725dc051
BK
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
748086b7
JJ
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.
725dc051 19
748086b7
JJ
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/>.
725dc051 24
f910786b 25/** @file bits/char_traits.h
729e3d3f 26 * This is an internal header file, included by other library headers.
f910786b 27 * Do not attempt to use it directly. @headername{string}
729e3d3f
PE
28 */
29
143c27b0
BK
30//
31// ISO C++ 14882: 21 Strings library
32//
33
3d7c150e
BK
34#ifndef _CHAR_TRAITS_H
35#define _CHAR_TRAITS_H 1
725dc051 36
b0a85b86
GDR
37#pragma GCC system_header
38
4f39bf5c 39#include <bits/stl_algobase.h> // std::copy, std::fill_n
39b8cd70 40#include <bits/postypes.h> // For streampos
39b8cd70 41#include <cwchar> // For WEOF, wmemmove, wmemset, etc.
725dc051 42
b51483f4 43#ifndef _GLIBCXX_ALWAYS_INLINE
612c9c70 44# define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
b51483f4
PA
45#endif
46
12ffa228
BK
47namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
48{
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 50
aa2d5ba2 51 /**
d5ff4e3f 52 * @brief Mapping from character type to associated types.
ed6814f7 53 *
d5ff4e3f
MA
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,
ed6814f7 57 * streampos, and mbstate_t. Users who need a different set of
d5ff4e3f
MA
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. */
65be6ddd 61 template<typename _CharT>
d5ff4e3f
MA
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
28dac70a 79 * may not be specialized for fundamental types, but classes in
d5ff4e3f 80 * namespace __gnu_cxx may be.
51122a42 81 *
10d43d2f 82 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
2a60a9f6 83 * for advice on how to make use of this class for @a unusual character
6309eefc
BK
84 * types. Also, check out include/ext/pod_char_traits.h.
85 */
d5ff4e3f 86 template<typename _CharT>
725dc051
BK
87 struct char_traits
88 {
d5ff4e3f
MA
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;
ed6814f7 94
8c3b5c71 95 static _GLIBCXX14_CONSTEXPR void
d5ff4e3f
MA
96 assign(char_type& __c1, const char_type& __c2)
97 { __c1 = __c2; }
725dc051 98
94a86be0 99 static _GLIBCXX_CONSTEXPR bool
d5ff4e3f
MA
100 eq(const char_type& __c1, const char_type& __c2)
101 { return __c1 == __c2; }
725dc051 102
94a86be0 103 static _GLIBCXX_CONSTEXPR bool
d5ff4e3f
MA
104 lt(const char_type& __c1, const char_type& __c2)
105 { return __c1 < __c2; }
725dc051 106
8c3b5c71 107 static _GLIBCXX14_CONSTEXPR int
d5ff4e3f 108 compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
725dc051 109
8c3b5c71 110 static _GLIBCXX14_CONSTEXPR std::size_t
f13a69ec 111 length(const char_type* __s);
725dc051 112
8c3b5c71 113 static _GLIBCXX14_CONSTEXPR const char_type*
d5ff4e3f 114 find(const char_type* __s, std::size_t __n, const char_type& __a);
725dc051 115
ed6814f7 116 static char_type*
d5ff4e3f 117 move(char_type* __s1, const char_type* __s2, std::size_t __n);
725dc051 118
ed6814f7 119 static char_type*
d5ff4e3f 120 copy(char_type* __s1, const char_type* __s2, std::size_t __n);
725dc051 121
ed6814f7 122 static char_type*
d5ff4e3f 123 assign(char_type* __s, std::size_t __n, char_type __a);
725dc051 124
94a86be0 125 static _GLIBCXX_CONSTEXPR char_type
d5ff4e3f
MA
126 to_char_type(const int_type& __c)
127 { return static_cast<char_type>(__c); }
725dc051 128
94a86be0 129 static _GLIBCXX_CONSTEXPR int_type
d5ff4e3f
MA
130 to_int_type(const char_type& __c)
131 { return static_cast<int_type>(__c); }
725dc051 132
94a86be0 133 static _GLIBCXX_CONSTEXPR bool
d5ff4e3f
MA
134 eq_int_type(const int_type& __c1, const int_type& __c2)
135 { return __c1 == __c2; }
725dc051 136
94a86be0 137 static _GLIBCXX_CONSTEXPR int_type
d5ff4e3f 138 eof()
ddc9c40d 139 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
725dc051 140
94a86be0 141 static _GLIBCXX_CONSTEXPR int_type
d5ff4e3f 142 not_eof(const int_type& __c)
5a9ed693 143 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
725dc051
BK
144 };
145
d5ff4e3f 146 template<typename _CharT>
8c3b5c71 147 _GLIBCXX14_CONSTEXPR int
d5ff4e3f
MA
148 char_traits<_CharT>::
149 compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
150 {
05a2763e 151 for (std::size_t __i = 0; __i < __n; ++__i)
d5ff4e3f
MA
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>
8c3b5c71 160 _GLIBCXX14_CONSTEXPR std::size_t
d5ff4e3f
MA
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>
8c3b5c71 171 _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
d5ff4e3f
MA
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 {
e002afaa
JW
186 if (__n == 0)
187 return __s1;
538075fe
PC
188 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
189 __n * sizeof(char_type)));
d5ff4e3f
MA
190 }
191
192 template<typename _CharT>
ed6814f7 193 typename char_traits<_CharT>::char_type*
d5ff4e3f
MA
194 char_traits<_CharT>::
195 copy(char_type* __s1, const char_type* __s2, std::size_t __n)
196 {
c2ba9709 197 // NB: Inline std::copy so no recursive dependencies.
d5ff4e3f
MA
198 std::copy(__s2, __s2 + __n, __s1);
199 return __s1;
200 }
201
202 template<typename _CharT>
ed6814f7 203 typename char_traits<_CharT>::char_type*
d5ff4e3f
MA
204 char_traits<_CharT>::
205 assign(char_type* __s, std::size_t __n, char_type __a)
206 {
c2ba9709 207 // NB: Inline std::fill_n so no recursive dependencies.
d5ff4e3f
MA
208 std::fill_n(__s, __n, __a);
209 return __s;
210 }
d5ff4e3f 211
12ffa228
BK
212_GLIBCXX_END_NAMESPACE_VERSION
213} // namespace
3cbc7af0 214
12ffa228
BK
215namespace std _GLIBCXX_VISIBILITY(default)
216{
217_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 218
5a95794c
JW
219#if __cplusplus >= 201703L
220#define __cpp_lib_constexpr_char_traits 201611
221
b51483f4
PA
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 {
8f10fb50
JJ
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
b51483f4
PA
238 while (__builtin_constant_p(*__s) && *__s)
239 __s++;
240 return __builtin_constant_p(*__s);
8f10fb50 241#endif
b51483f4
PA
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 {
8f10fb50
JJ
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
b51483f4 262 size_t __i = 0;
ace857f9 263 while (__i < __n && __builtin_constant_p(__a[__i]))
b51483f4
PA
264 __i++;
265 return __i == __n;
8f10fb50 266#endif
b51483f4
PA
267 }
268#endif
269
d5ff4e3f
MA
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 *
10d43d2f 279 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
2a60a9f6 280 * for advice on how to make use of this class for @a unusual character
d5ff4e3f
MA
281 * types. Also, check out include/ext/pod_char_traits.h.
282 */
283 template<class _CharT>
6309eefc 284 struct char_traits : public __gnu_cxx::char_traits<_CharT>
d5ff4e3f
MA
285 { };
286
97644827 287
939759fc 288 /// 21.1.3.1 char_traits specializations
725dc051
BK
289 template<>
290 struct char_traits<char>
291 {
d5ff4e3f
MA
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;
725dc051 297
8c3b5c71 298 static _GLIBCXX17_CONSTEXPR void
2789f415 299 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
300 { __c1 = __c2; }
301
94a86be0 302 static _GLIBCXX_CONSTEXPR bool
2789f415 303 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
462ec415 304 { return __c1 == __c2; }
725dc051 305
94a86be0 306 static _GLIBCXX_CONSTEXPR bool
2789f415 307 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
6cdbb7e8
PC
308 {
309 // LWG 467.
310 return (static_cast<unsigned char>(__c1)
311 < static_cast<unsigned char>(__c2));
312 }
725dc051 313
b51483f4 314 static _GLIBCXX17_CONSTEXPR int
725dc051 315 compare(const char_type* __s1, const char_type* __s2, size_t __n)
4a88769c 316 {
ace857f9
JW
317 if (__n == 0)
318 return 0;
5a95794c 319#if __cplusplus >= 201703L
b51483f4
PA
320 if (__builtin_constant_p(__n)
321 && __constant_char_array_p(__s1, __n)
322 && __constant_char_array_p(__s2, __n))
323 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
324#endif
4a88769c
JW
325 return __builtin_memcmp(__s1, __s2, __n);
326 }
725dc051 327
b51483f4 328 static _GLIBCXX17_CONSTEXPR size_t
725dc051 329 length(const char_type* __s)
b51483f4 330 {
5a95794c 331#if __cplusplus >= 201703L
b51483f4
PA
332 if (__constant_string_p(__s))
333 return __gnu_cxx::char_traits<char_type>::length(__s);
334#endif
335 return __builtin_strlen(__s);
336 }
725dc051 337
b51483f4 338 static _GLIBCXX17_CONSTEXPR const char_type*
725dc051 339 find(const char_type* __s, size_t __n, const char_type& __a)
4a88769c 340 {
ace857f9
JW
341 if (__n == 0)
342 return 0;
5a95794c 343#if __cplusplus >= 201703L
b51483f4
PA
344 if (__builtin_constant_p(__n)
345 && __builtin_constant_p(__a)
346 && __constant_char_array_p(__s, __n))
347 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
348#endif
4a88769c
JW
349 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
350 }
725dc051 351
ed6814f7 352 static char_type*
725dc051 353 move(char_type* __s1, const char_type* __s2, size_t __n)
4a88769c
JW
354 {
355 if (__n == 0)
356 return __s1;
357 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
358 }
725dc051 359
ed6814f7 360 static char_type*
725dc051 361 copy(char_type* __s1, const char_type* __s2, size_t __n)
4a88769c
JW
362 {
363 if (__n == 0)
364 return __s1;
365 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
366 }
725dc051 367
ed6814f7 368 static char_type*
725dc051 369 assign(char_type* __s, size_t __n, char_type __a)
4a88769c
JW
370 {
371 if (__n == 0)
372 return __s;
373 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
374 }
725dc051 375
94a86be0 376 static _GLIBCXX_CONSTEXPR char_type
2789f415 377 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
725dc051
BK
378 { return static_cast<char_type>(__c); }
379
380 // To keep both the byte 0xff and the eof symbol 0xffffffff
381 // from ending up as 0xffffffff.
94a86be0 382 static _GLIBCXX_CONSTEXPR int_type
2789f415 383 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
725dc051
BK
384 { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
385
94a86be0 386 static _GLIBCXX_CONSTEXPR bool
2789f415 387 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
388 { return __c1 == __c2; }
389
94a86be0 390 static _GLIBCXX_CONSTEXPR int_type
2789f415 391 eof() _GLIBCXX_NOEXCEPT
ddc9c40d 392 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
725dc051 393
94a86be0 394 static _GLIBCXX_CONSTEXPR int_type
2789f415 395 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
725dc051
BK
396 { return (__c == eof()) ? 0 : __c; }
397 };
398
399
3d7c150e 400#ifdef _GLIBCXX_USE_WCHAR_T
939759fc 401 /// 21.1.3.2 char_traits specializations
725dc051
BK
402 template<>
403 struct char_traits<wchar_t>
404 {
d5ff4e3f
MA
405 typedef wchar_t char_type;
406 typedef wint_t int_type;
407 typedef streamoff off_type;
408 typedef wstreampos pos_type;
409 typedef mbstate_t state_type;
ed6814f7 410
8c3b5c71 411 static _GLIBCXX17_CONSTEXPR void
2789f415 412 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
413 { __c1 = __c2; }
414
94a86be0 415 static _GLIBCXX_CONSTEXPR bool
2789f415 416 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
462ec415 417 { return __c1 == __c2; }
725dc051 418
94a86be0 419 static _GLIBCXX_CONSTEXPR bool
2789f415 420 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
421 { return __c1 < __c2; }
422
b51483f4 423 static _GLIBCXX17_CONSTEXPR int
725dc051 424 compare(const char_type* __s1, const char_type* __s2, size_t __n)
4a88769c 425 {
ace857f9
JW
426 if (__n == 0)
427 return 0;
5a95794c 428#if __cplusplus >= 201703L
b51483f4
PA
429 if (__builtin_constant_p(__n)
430 && __constant_char_array_p(__s1, __n)
431 && __constant_char_array_p(__s2, __n))
432 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
433#endif
ace857f9 434 return wmemcmp(__s1, __s2, __n);
4a88769c 435 }
725dc051 436
b51483f4 437 static _GLIBCXX17_CONSTEXPR size_t
725dc051 438 length(const char_type* __s)
b51483f4 439 {
5a95794c 440#if __cplusplus >= 201703L
b51483f4
PA
441 if (__constant_string_p(__s))
442 return __gnu_cxx::char_traits<char_type>::length(__s);
b51483f4 443#endif
ace857f9 444 return wcslen(__s);
b51483f4 445 }
725dc051 446
b51483f4 447 static _GLIBCXX17_CONSTEXPR const char_type*
725dc051 448 find(const char_type* __s, size_t __n, const char_type& __a)
4a88769c 449 {
ace857f9
JW
450 if (__n == 0)
451 return 0;
5a95794c 452#if __cplusplus >= 201703L
b51483f4
PA
453 if (__builtin_constant_p(__n)
454 && __builtin_constant_p(__a)
455 && __constant_char_array_p(__s, __n))
456 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
457#endif
ace857f9 458 return wmemchr(__s, __a, __n);
4a88769c 459 }
725dc051 460
ed6814f7 461 static char_type*
73a530bd 462 move(char_type* __s1, const char_type* __s2, size_t __n)
4a88769c
JW
463 {
464 if (__n == 0)
465 return __s1;
466 return wmemmove(__s1, __s2, __n);
467 }
725dc051 468
ed6814f7 469 static char_type*
725dc051 470 copy(char_type* __s1, const char_type* __s2, size_t __n)
4a88769c
JW
471 {
472 if (__n == 0)
473 return __s1;
474 return wmemcpy(__s1, __s2, __n);
475 }
725dc051 476
ed6814f7 477 static char_type*
725dc051 478 assign(char_type* __s, size_t __n, char_type __a)
4a88769c
JW
479 {
480 if (__n == 0)
481 return __s;
482 return wmemset(__s, __a, __n);
483 }
725dc051 484
94a86be0 485 static _GLIBCXX_CONSTEXPR char_type
2789f415 486 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
2fb63453 487 { return char_type(__c); }
725dc051 488
94a86be0 489 static _GLIBCXX_CONSTEXPR int_type
2789f415 490 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
2fb63453 491 { return int_type(__c); }
725dc051 492
94a86be0 493 static _GLIBCXX_CONSTEXPR bool
2789f415 494 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
495 { return __c1 == __c2; }
496
94a86be0 497 static _GLIBCXX_CONSTEXPR int_type
2789f415 498 eof() _GLIBCXX_NOEXCEPT
2fb63453 499 { return static_cast<int_type>(WEOF); }
725dc051 500
94a86be0 501 static _GLIBCXX_CONSTEXPR int_type
2789f415 502 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
725dc051
BK
503 { return eq_int_type(__c, eof()) ? 0 : __c; }
504 };
3d7c150e 505#endif //_GLIBCXX_USE_WCHAR_T
725dc051 506
c124af93
TH
507#ifdef _GLIBCXX_USE_CHAR8_T
508 template<>
509 struct char_traits<char8_t>
510 {
511 typedef char8_t char_type;
512 typedef unsigned int int_type;
513 typedef u8streampos pos_type;
514 typedef streamoff off_type;
515 typedef mbstate_t state_type;
516
517 static _GLIBCXX17_CONSTEXPR void
518 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
519 { __c1 = __c2; }
520
521 static _GLIBCXX_CONSTEXPR bool
522 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
523 { return __c1 == __c2; }
524
525 static _GLIBCXX_CONSTEXPR bool
526 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
527 { return __c1 < __c2; }
528
529 static _GLIBCXX17_CONSTEXPR int
530 compare(const char_type* __s1, const char_type* __s2, size_t __n)
531 {
ace857f9
JW
532 if (__n == 0)
533 return 0;
c124af93
TH
534#if __cplusplus > 201402
535 if (__builtin_constant_p(__n)
536 && __constant_char_array_p(__s1, __n)
537 && __constant_char_array_p(__s2, __n))
538 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
539#endif
c124af93
TH
540 return __builtin_memcmp(__s1, __s2, __n);
541 }
542
543 static _GLIBCXX17_CONSTEXPR size_t
544 length(const char_type* __s)
545 {
546#if __cplusplus > 201402
547 if (__constant_string_p(__s))
548 return __gnu_cxx::char_traits<char_type>::length(__s);
549#endif
550 size_t __i = 0;
551 while (!eq(__s[__i], char_type()))
552 ++__i;
553 return __i;
554 }
555
556 static _GLIBCXX17_CONSTEXPR const char_type*
557 find(const char_type* __s, size_t __n, const char_type& __a)
558 {
ace857f9
JW
559 if (__n == 0)
560 return 0;
c124af93
TH
561#if __cplusplus > 201402
562 if (__builtin_constant_p(__n)
563 && __builtin_constant_p(__a)
564 && __constant_char_array_p(__s, __n))
565 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
566#endif
c124af93
TH
567 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
568 }
569
570 static char_type*
571 move(char_type* __s1, const char_type* __s2, size_t __n)
572 {
573 if (__n == 0)
574 return __s1;
575 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
576 }
577
578 static char_type*
579 copy(char_type* __s1, const char_type* __s2, size_t __n)
580 {
581 if (__n == 0)
582 return __s1;
583 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
584 }
585
586 static char_type*
587 assign(char_type* __s, size_t __n, char_type __a)
588 {
589 if (__n == 0)
590 return __s;
591 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
592 }
593
594 static _GLIBCXX_CONSTEXPR char_type
595 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
596 { return char_type(__c); }
597
598 static _GLIBCXX_CONSTEXPR int_type
599 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
600 { return int_type(__c); }
601
602 static _GLIBCXX_CONSTEXPR bool
603 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
604 { return __c1 == __c2; }
605
606 static _GLIBCXX_CONSTEXPR int_type
607 eof() _GLIBCXX_NOEXCEPT
608 { return static_cast<int_type>(-1); }
609
610 static _GLIBCXX_CONSTEXPR int_type
611 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
612 { return eq_int_type(__c, eof()) ? 0 : __c; }
613 };
614#endif //_GLIBCXX_USE_CHAR8_T
615
12ffa228
BK
616_GLIBCXX_END_NAMESPACE_VERSION
617} // namespace
725dc051 618
612c9c70 619#if __cplusplus >= 201103L
5e44d591
PC
620
621#include <cstdint>
622
12ffa228
BK
623namespace std _GLIBCXX_VISIBILITY(default)
624{
625_GLIBCXX_BEGIN_NAMESPACE_VERSION
5e44d591
PC
626
627 template<>
628 struct char_traits<char16_t>
629 {
630 typedef char16_t char_type;
612c9c70 631#ifdef _GLIBCXX_USE_C99_STDINT_TR1
5e44d591 632 typedef uint_least16_t int_type;
612c9c70
JW
633#elif defined __UINT_LEAST16_TYPE__
634 typedef __UINT_LEAST16_TYPE__ int_type;
635#else
636 typedef make_unsigned<char16_t>::type int_type;
637#endif
5e44d591
PC
638 typedef streamoff off_type;
639 typedef u16streampos pos_type;
640 typedef mbstate_t state_type;
641
8c3b5c71 642 static _GLIBCXX17_CONSTEXPR void
2789f415 643 assign(char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
644 { __c1 = __c2; }
645
2789f415
PC
646 static constexpr bool
647 eq(const char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
648 { return __c1 == __c2; }
649
2789f415
PC
650 static constexpr bool
651 lt(const char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
652 { return __c1 < __c2; }
653
8c3b5c71 654 static _GLIBCXX17_CONSTEXPR int
5e44d591
PC
655 compare(const char_type* __s1, const char_type* __s2, size_t __n)
656 {
657 for (size_t __i = 0; __i < __n; ++__i)
658 if (lt(__s1[__i], __s2[__i]))
659 return -1;
660 else if (lt(__s2[__i], __s1[__i]))
661 return 1;
662 return 0;
663 }
664
8c3b5c71 665 static _GLIBCXX17_CONSTEXPR size_t
5e44d591
PC
666 length(const char_type* __s)
667 {
668 size_t __i = 0;
669 while (!eq(__s[__i], char_type()))
670 ++__i;
671 return __i;
672 }
673
8c3b5c71 674 static _GLIBCXX17_CONSTEXPR const char_type*
5e44d591
PC
675 find(const char_type* __s, size_t __n, const char_type& __a)
676 {
677 for (size_t __i = 0; __i < __n; ++__i)
678 if (eq(__s[__i], __a))
679 return __s + __i;
680 return 0;
681 }
682
683 static char_type*
684 move(char_type* __s1, const char_type* __s2, size_t __n)
685 {
4a88769c
JW
686 if (__n == 0)
687 return __s1;
5e44d591
PC
688 return (static_cast<char_type*>
689 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
690 }
691
692 static char_type*
693 copy(char_type* __s1, const char_type* __s2, size_t __n)
694 {
4a88769c
JW
695 if (__n == 0)
696 return __s1;
5e44d591
PC
697 return (static_cast<char_type*>
698 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
699 }
700
701 static char_type*
702 assign(char_type* __s, size_t __n, char_type __a)
2fb63453
PC
703 {
704 for (size_t __i = 0; __i < __n; ++__i)
705 assign(__s[__i], __a);
5e44d591
PC
706 return __s;
707 }
708
2789f415
PC
709 static constexpr char_type
710 to_char_type(const int_type& __c) noexcept
2fb63453 711 { return char_type(__c); }
5e44d591 712
2789f415
PC
713 static constexpr int_type
714 to_int_type(const char_type& __c) noexcept
4c19e432 715 { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
5e44d591 716
2789f415
PC
717 static constexpr bool
718 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
5e44d591
PC
719 { return __c1 == __c2; }
720
2789f415
PC
721 static constexpr int_type
722 eof() noexcept
2fb63453 723 { return static_cast<int_type>(-1); }
5e44d591 724
2789f415
PC
725 static constexpr int_type
726 not_eof(const int_type& __c) noexcept
5e44d591
PC
727 { return eq_int_type(__c, eof()) ? 0 : __c; }
728 };
729
730 template<>
731 struct char_traits<char32_t>
732 {
733 typedef char32_t char_type;
612c9c70 734#ifdef _GLIBCXX_USE_C99_STDINT_TR1
5e44d591 735 typedef uint_least32_t int_type;
612c9c70
JW
736#elif defined __UINT_LEAST32_TYPE__
737 typedef __UINT_LEAST32_TYPE__ int_type;
738#else
739 typedef make_unsigned<char32_t>::type int_type;
740#endif
5e44d591
PC
741 typedef streamoff off_type;
742 typedef u32streampos pos_type;
743 typedef mbstate_t state_type;
744
8c3b5c71 745 static _GLIBCXX17_CONSTEXPR void
2789f415 746 assign(char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
747 { __c1 = __c2; }
748
2789f415
PC
749 static constexpr bool
750 eq(const char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
751 { return __c1 == __c2; }
752
2789f415
PC
753 static constexpr bool
754 lt(const char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
755 { return __c1 < __c2; }
756
8c3b5c71 757 static _GLIBCXX17_CONSTEXPR int
5e44d591
PC
758 compare(const char_type* __s1, const char_type* __s2, size_t __n)
759 {
760 for (size_t __i = 0; __i < __n; ++__i)
761 if (lt(__s1[__i], __s2[__i]))
762 return -1;
763 else if (lt(__s2[__i], __s1[__i]))
764 return 1;
765 return 0;
766 }
767
8c3b5c71 768 static _GLIBCXX17_CONSTEXPR size_t
5e44d591
PC
769 length(const char_type* __s)
770 {
771 size_t __i = 0;
772 while (!eq(__s[__i], char_type()))
773 ++__i;
774 return __i;
775 }
776
8c3b5c71 777 static _GLIBCXX17_CONSTEXPR const char_type*
5e44d591
PC
778 find(const char_type* __s, size_t __n, const char_type& __a)
779 {
780 for (size_t __i = 0; __i < __n; ++__i)
781 if (eq(__s[__i], __a))
782 return __s + __i;
783 return 0;
784 }
785
786 static char_type*
787 move(char_type* __s1, const char_type* __s2, size_t __n)
788 {
4a88769c
JW
789 if (__n == 0)
790 return __s1;
5e44d591
PC
791 return (static_cast<char_type*>
792 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
793 }
794
795 static char_type*
796 copy(char_type* __s1, const char_type* __s2, size_t __n)
797 {
4a88769c
JW
798 if (__n == 0)
799 return __s1;
5e44d591
PC
800 return (static_cast<char_type*>
801 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
802 }
803
804 static char_type*
805 assign(char_type* __s, size_t __n, char_type __a)
806 {
2fb63453
PC
807 for (size_t __i = 0; __i < __n; ++__i)
808 assign(__s[__i], __a);
5e44d591
PC
809 return __s;
810 }
811
2789f415
PC
812 static constexpr char_type
813 to_char_type(const int_type& __c) noexcept
2fb63453 814 { return char_type(__c); }
5e44d591 815
2789f415
PC
816 static constexpr int_type
817 to_int_type(const char_type& __c) noexcept
2fb63453 818 { return int_type(__c); }
5e44d591 819
2789f415
PC
820 static constexpr bool
821 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
5e44d591
PC
822 { return __c1 == __c2; }
823
2789f415
PC
824 static constexpr int_type
825 eof() noexcept
2fb63453 826 { return static_cast<int_type>(-1); }
5e44d591 827
2789f415
PC
828 static constexpr int_type
829 not_eof(const int_type& __c) noexcept
5e44d591
PC
830 { return eq_int_type(__c, eof()) ? 0 : __c; }
831 };
832
12ffa228
BK
833_GLIBCXX_END_NAMESPACE_VERSION
834} // namespace
5e44d591 835
612c9c70 836#endif // C++11
5e44d591 837
5e44d591 838#endif // _CHAR_TRAITS_H