]> gcc.gnu.org Git - gcc.git/blame - libstdc++-v3/include/bits/char_traits.h
libstdc++: Add comparison operators for string and regex types
[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.
875d6cb3
JW
42#if __cplusplus > 201703L
43# include <compare>
44#endif
725dc051 45
b51483f4 46#ifndef _GLIBCXX_ALWAYS_INLINE
612c9c70 47# define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
b51483f4
PA
48#endif
49
12ffa228
BK
50namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
51{
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 53
aa2d5ba2 54 /**
d5ff4e3f 55 * @brief Mapping from character type to associated types.
ed6814f7 56 *
d5ff4e3f
MA
57 * @note This is an implementation class for the generic version
58 * of char_traits. It defines int_type, off_type, pos_type, and
59 * state_type. By default these are unsigned long, streamoff,
ed6814f7 60 * streampos, and mbstate_t. Users who need a different set of
d5ff4e3f
MA
61 * types, but who don't need to change the definitions of any function
62 * defined in char_traits, can specialize __gnu_cxx::_Char_types
63 * while leaving __gnu_cxx::char_traits alone. */
65be6ddd 64 template<typename _CharT>
d5ff4e3f
MA
65 struct _Char_types
66 {
67 typedef unsigned long int_type;
68 typedef std::streampos pos_type;
69 typedef std::streamoff off_type;
70 typedef std::mbstate_t state_type;
71 };
72
73
74 /**
75 * @brief Base class used to implement std::char_traits.
76 *
77 * @note For any given actual character type, this definition is
78 * probably wrong. (Most of the member functions are likely to be
79 * right, but the int_type and state_type typedefs, and the eof()
80 * member function, are likely to be wrong.) The reason this class
81 * exists is so users can specialize it. Classes in namespace std
28dac70a 82 * may not be specialized for fundamental types, but classes in
d5ff4e3f 83 * namespace __gnu_cxx may be.
51122a42 84 *
10d43d2f 85 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
2a60a9f6 86 * for advice on how to make use of this class for @a unusual character
6309eefc
BK
87 * types. Also, check out include/ext/pod_char_traits.h.
88 */
d5ff4e3f 89 template<typename _CharT>
725dc051
BK
90 struct char_traits
91 {
d5ff4e3f
MA
92 typedef _CharT char_type;
93 typedef typename _Char_types<_CharT>::int_type int_type;
94 typedef typename _Char_types<_CharT>::pos_type pos_type;
95 typedef typename _Char_types<_CharT>::off_type off_type;
96 typedef typename _Char_types<_CharT>::state_type state_type;
875d6cb3
JW
97#if __cpp_lib_three_way_comparison
98 using comparison_category = std::strong_ordering;
99#endif
ed6814f7 100
8c3b5c71 101 static _GLIBCXX14_CONSTEXPR void
d5ff4e3f
MA
102 assign(char_type& __c1, const char_type& __c2)
103 { __c1 = __c2; }
725dc051 104
94a86be0 105 static _GLIBCXX_CONSTEXPR bool
d5ff4e3f
MA
106 eq(const char_type& __c1, const char_type& __c2)
107 { return __c1 == __c2; }
725dc051 108
94a86be0 109 static _GLIBCXX_CONSTEXPR bool
d5ff4e3f
MA
110 lt(const char_type& __c1, const char_type& __c2)
111 { return __c1 < __c2; }
725dc051 112
8c3b5c71 113 static _GLIBCXX14_CONSTEXPR int
d5ff4e3f 114 compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
725dc051 115
8c3b5c71 116 static _GLIBCXX14_CONSTEXPR std::size_t
f13a69ec 117 length(const char_type* __s);
725dc051 118
8c3b5c71 119 static _GLIBCXX14_CONSTEXPR const char_type*
d5ff4e3f 120 find(const char_type* __s, std::size_t __n, const char_type& __a);
725dc051 121
b6966987 122 static _GLIBCXX20_CONSTEXPR char_type*
d5ff4e3f 123 move(char_type* __s1, const char_type* __s2, std::size_t __n);
725dc051 124
b6966987 125 static _GLIBCXX20_CONSTEXPR char_type*
d5ff4e3f 126 copy(char_type* __s1, const char_type* __s2, std::size_t __n);
725dc051 127
b6966987 128 static _GLIBCXX20_CONSTEXPR char_type*
d5ff4e3f 129 assign(char_type* __s, std::size_t __n, char_type __a);
725dc051 130
94a86be0 131 static _GLIBCXX_CONSTEXPR char_type
d5ff4e3f
MA
132 to_char_type(const int_type& __c)
133 { return static_cast<char_type>(__c); }
725dc051 134
94a86be0 135 static _GLIBCXX_CONSTEXPR int_type
d5ff4e3f
MA
136 to_int_type(const char_type& __c)
137 { return static_cast<int_type>(__c); }
725dc051 138
94a86be0 139 static _GLIBCXX_CONSTEXPR bool
d5ff4e3f
MA
140 eq_int_type(const int_type& __c1, const int_type& __c2)
141 { return __c1 == __c2; }
725dc051 142
94a86be0 143 static _GLIBCXX_CONSTEXPR int_type
d5ff4e3f 144 eof()
ddc9c40d 145 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
725dc051 146
94a86be0 147 static _GLIBCXX_CONSTEXPR int_type
d5ff4e3f 148 not_eof(const int_type& __c)
5a9ed693 149 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
725dc051
BK
150 };
151
d5ff4e3f 152 template<typename _CharT>
8c3b5c71 153 _GLIBCXX14_CONSTEXPR int
d5ff4e3f
MA
154 char_traits<_CharT>::
155 compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
156 {
05a2763e 157 for (std::size_t __i = 0; __i < __n; ++__i)
d5ff4e3f
MA
158 if (lt(__s1[__i], __s2[__i]))
159 return -1;
160 else if (lt(__s2[__i], __s1[__i]))
161 return 1;
162 return 0;
163 }
164
165 template<typename _CharT>
8c3b5c71 166 _GLIBCXX14_CONSTEXPR std::size_t
d5ff4e3f
MA
167 char_traits<_CharT>::
168 length(const char_type* __p)
169 {
170 std::size_t __i = 0;
171 while (!eq(__p[__i], char_type()))
172 ++__i;
173 return __i;
174 }
175
176 template<typename _CharT>
8c3b5c71 177 _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
d5ff4e3f
MA
178 char_traits<_CharT>::
179 find(const char_type* __s, std::size_t __n, const char_type& __a)
180 {
181 for (std::size_t __i = 0; __i < __n; ++__i)
182 if (eq(__s[__i], __a))
183 return __s + __i;
184 return 0;
185 }
186
187 template<typename _CharT>
b6966987 188 _GLIBCXX20_CONSTEXPR
d5ff4e3f
MA
189 typename char_traits<_CharT>::char_type*
190 char_traits<_CharT>::
191 move(char_type* __s1, const char_type* __s2, std::size_t __n)
192 {
e002afaa
JW
193 if (__n == 0)
194 return __s1;
b6966987
JW
195#ifdef __cpp_lib_is_constant_evaluated
196 if (std::is_constant_evaluated())
197 {
198 if (__s1 > __s2 && __s1 < __s2 + __n)
199 std::copy_backward(__s2, __s2 + __n, __s1);
200 else
201 std::copy(__s2, __s2 + __n, __s1);
202 return __s1;
203 }
204#endif
538075fe
PC
205 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
206 __n * sizeof(char_type)));
d5ff4e3f
MA
207 }
208
209 template<typename _CharT>
b6966987 210 _GLIBCXX20_CONSTEXPR
ed6814f7 211 typename char_traits<_CharT>::char_type*
d5ff4e3f
MA
212 char_traits<_CharT>::
213 copy(char_type* __s1, const char_type* __s2, std::size_t __n)
214 {
c2ba9709 215 // NB: Inline std::copy so no recursive dependencies.
d5ff4e3f
MA
216 std::copy(__s2, __s2 + __n, __s1);
217 return __s1;
218 }
219
220 template<typename _CharT>
b6966987 221 _GLIBCXX20_CONSTEXPR
ed6814f7 222 typename char_traits<_CharT>::char_type*
d5ff4e3f
MA
223 char_traits<_CharT>::
224 assign(char_type* __s, std::size_t __n, char_type __a)
225 {
c2ba9709 226 // NB: Inline std::fill_n so no recursive dependencies.
d5ff4e3f
MA
227 std::fill_n(__s, __n, __a);
228 return __s;
229 }
d5ff4e3f 230
12ffa228
BK
231_GLIBCXX_END_NAMESPACE_VERSION
232} // namespace
3cbc7af0 233
12ffa228
BK
234namespace std _GLIBCXX_VISIBILITY(default)
235{
236_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 237
5a95794c
JW
238#if __cplusplus >= 201703L
239#define __cpp_lib_constexpr_char_traits 201611
240
b51483f4
PA
241 /**
242 * @brief Determine whether the characters of a NULL-terminated
243 * string are known at compile time.
244 * @param __s The string.
245 *
246 * Assumes that _CharT is a built-in character type.
247 */
248 template<typename _CharT>
249 static _GLIBCXX_ALWAYS_INLINE constexpr bool
250 __constant_string_p(const _CharT* __s)
251 {
8f10fb50
JJ
252#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
253 (void) __s;
254 // In constexpr contexts all strings should be constant.
255 return __builtin_is_constant_evaluated();
256#else
b51483f4
PA
257 while (__builtin_constant_p(*__s) && *__s)
258 __s++;
259 return __builtin_constant_p(*__s);
8f10fb50 260#endif
b51483f4
PA
261 }
262
263 /**
264 * @brief Determine whether the characters of a character array are
265 * known at compile time.
266 * @param __a The character array.
267 * @param __n Number of characters.
268 *
269 * Assumes that _CharT is a built-in character type.
270 */
271 template<typename _CharT>
272 static _GLIBCXX_ALWAYS_INLINE constexpr bool
273 __constant_char_array_p(const _CharT* __a, size_t __n)
274 {
8f10fb50
JJ
275#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
276 (void) __a;
277 (void) __n;
278 // In constexpr contexts all character arrays should be constant.
279 return __builtin_is_constant_evaluated();
280#else
b51483f4 281 size_t __i = 0;
ace857f9 282 while (__i < __n && __builtin_constant_p(__a[__i]))
b51483f4
PA
283 __i++;
284 return __i == __n;
8f10fb50 285#endif
b51483f4
PA
286 }
287#endif
288
d5ff4e3f
MA
289 // 21.1
290 /**
291 * @brief Basis for explicit traits specializations.
292 *
293 * @note For any given actual character type, this definition is
294 * probably wrong. Since this is just a thin wrapper around
295 * __gnu_cxx::char_traits, it is possible to achieve a more
296 * appropriate definition by specializing __gnu_cxx::char_traits.
297 *
10d43d2f 298 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
2a60a9f6 299 * for advice on how to make use of this class for @a unusual character
d5ff4e3f
MA
300 * types. Also, check out include/ext/pod_char_traits.h.
301 */
302 template<class _CharT>
6309eefc 303 struct char_traits : public __gnu_cxx::char_traits<_CharT>
d5ff4e3f
MA
304 { };
305
97644827 306
939759fc 307 /// 21.1.3.1 char_traits specializations
725dc051
BK
308 template<>
309 struct char_traits<char>
310 {
d5ff4e3f
MA
311 typedef char char_type;
312 typedef int int_type;
313 typedef streampos pos_type;
314 typedef streamoff off_type;
315 typedef mbstate_t state_type;
875d6cb3
JW
316#if __cpp_lib_three_way_comparison
317 using comparison_category = strong_ordering;
318#endif
725dc051 319
8c3b5c71 320 static _GLIBCXX17_CONSTEXPR void
2789f415 321 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
322 { __c1 = __c2; }
323
94a86be0 324 static _GLIBCXX_CONSTEXPR bool
2789f415 325 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
462ec415 326 { return __c1 == __c2; }
725dc051 327
94a86be0 328 static _GLIBCXX_CONSTEXPR bool
2789f415 329 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
6cdbb7e8
PC
330 {
331 // LWG 467.
332 return (static_cast<unsigned char>(__c1)
333 < static_cast<unsigned char>(__c2));
334 }
725dc051 335
b51483f4 336 static _GLIBCXX17_CONSTEXPR int
725dc051 337 compare(const char_type* __s1, const char_type* __s2, size_t __n)
4a88769c 338 {
ace857f9
JW
339 if (__n == 0)
340 return 0;
5a95794c 341#if __cplusplus >= 201703L
b51483f4
PA
342 if (__builtin_constant_p(__n)
343 && __constant_char_array_p(__s1, __n)
344 && __constant_char_array_p(__s2, __n))
345 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
346#endif
4a88769c
JW
347 return __builtin_memcmp(__s1, __s2, __n);
348 }
725dc051 349
b51483f4 350 static _GLIBCXX17_CONSTEXPR size_t
725dc051 351 length(const char_type* __s)
b51483f4 352 {
5a95794c 353#if __cplusplus >= 201703L
b51483f4
PA
354 if (__constant_string_p(__s))
355 return __gnu_cxx::char_traits<char_type>::length(__s);
356#endif
357 return __builtin_strlen(__s);
358 }
725dc051 359
b51483f4 360 static _GLIBCXX17_CONSTEXPR const char_type*
725dc051 361 find(const char_type* __s, size_t __n, const char_type& __a)
4a88769c 362 {
ace857f9
JW
363 if (__n == 0)
364 return 0;
5a95794c 365#if __cplusplus >= 201703L
b51483f4
PA
366 if (__builtin_constant_p(__n)
367 && __builtin_constant_p(__a)
368 && __constant_char_array_p(__s, __n))
369 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
370#endif
4a88769c
JW
371 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
372 }
725dc051 373
b6966987 374 static _GLIBCXX20_CONSTEXPR char_type*
725dc051 375 move(char_type* __s1, const char_type* __s2, size_t __n)
4a88769c
JW
376 {
377 if (__n == 0)
378 return __s1;
b6966987
JW
379#ifdef __cpp_lib_is_constant_evaluated
380 if (std::is_constant_evaluated())
381 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
382#endif
4a88769c
JW
383 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
384 }
725dc051 385
b6966987 386 static _GLIBCXX20_CONSTEXPR char_type*
725dc051 387 copy(char_type* __s1, const char_type* __s2, size_t __n)
4a88769c
JW
388 {
389 if (__n == 0)
390 return __s1;
b6966987
JW
391#ifdef __cpp_lib_is_constant_evaluated
392 if (std::is_constant_evaluated())
393 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
394#endif
4a88769c
JW
395 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
396 }
725dc051 397
b6966987 398 static _GLIBCXX20_CONSTEXPR char_type*
725dc051 399 assign(char_type* __s, size_t __n, char_type __a)
4a88769c
JW
400 {
401 if (__n == 0)
402 return __s;
b6966987
JW
403#ifdef __cpp_lib_is_constant_evaluated
404 if (std::is_constant_evaluated())
405 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
406#endif
4a88769c
JW
407 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
408 }
725dc051 409
94a86be0 410 static _GLIBCXX_CONSTEXPR char_type
2789f415 411 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
725dc051
BK
412 { return static_cast<char_type>(__c); }
413
414 // To keep both the byte 0xff and the eof symbol 0xffffffff
415 // from ending up as 0xffffffff.
94a86be0 416 static _GLIBCXX_CONSTEXPR int_type
2789f415 417 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
725dc051
BK
418 { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
419
94a86be0 420 static _GLIBCXX_CONSTEXPR bool
2789f415 421 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
422 { return __c1 == __c2; }
423
94a86be0 424 static _GLIBCXX_CONSTEXPR int_type
2789f415 425 eof() _GLIBCXX_NOEXCEPT
ddc9c40d 426 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
725dc051 427
94a86be0 428 static _GLIBCXX_CONSTEXPR int_type
2789f415 429 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
725dc051
BK
430 { return (__c == eof()) ? 0 : __c; }
431 };
432
433
3d7c150e 434#ifdef _GLIBCXX_USE_WCHAR_T
939759fc 435 /// 21.1.3.2 char_traits specializations
725dc051
BK
436 template<>
437 struct char_traits<wchar_t>
438 {
d5ff4e3f
MA
439 typedef wchar_t char_type;
440 typedef wint_t int_type;
441 typedef streamoff off_type;
442 typedef wstreampos pos_type;
443 typedef mbstate_t state_type;
875d6cb3
JW
444#if __cpp_lib_three_way_comparison
445 using comparison_category = strong_ordering;
446#endif
ed6814f7 447
8c3b5c71 448 static _GLIBCXX17_CONSTEXPR void
2789f415 449 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
450 { __c1 = __c2; }
451
94a86be0 452 static _GLIBCXX_CONSTEXPR bool
2789f415 453 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
462ec415 454 { return __c1 == __c2; }
725dc051 455
94a86be0 456 static _GLIBCXX_CONSTEXPR bool
2789f415 457 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
458 { return __c1 < __c2; }
459
b51483f4 460 static _GLIBCXX17_CONSTEXPR int
725dc051 461 compare(const char_type* __s1, const char_type* __s2, size_t __n)
4a88769c 462 {
ace857f9
JW
463 if (__n == 0)
464 return 0;
5a95794c 465#if __cplusplus >= 201703L
b51483f4
PA
466 if (__builtin_constant_p(__n)
467 && __constant_char_array_p(__s1, __n)
468 && __constant_char_array_p(__s2, __n))
469 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
470#endif
ace857f9 471 return wmemcmp(__s1, __s2, __n);
4a88769c 472 }
725dc051 473
b51483f4 474 static _GLIBCXX17_CONSTEXPR size_t
725dc051 475 length(const char_type* __s)
b51483f4 476 {
5a95794c 477#if __cplusplus >= 201703L
b51483f4
PA
478 if (__constant_string_p(__s))
479 return __gnu_cxx::char_traits<char_type>::length(__s);
b51483f4 480#endif
ace857f9 481 return wcslen(__s);
b51483f4 482 }
725dc051 483
b51483f4 484 static _GLIBCXX17_CONSTEXPR const char_type*
725dc051 485 find(const char_type* __s, size_t __n, const char_type& __a)
4a88769c 486 {
ace857f9
JW
487 if (__n == 0)
488 return 0;
5a95794c 489#if __cplusplus >= 201703L
b51483f4
PA
490 if (__builtin_constant_p(__n)
491 && __builtin_constant_p(__a)
492 && __constant_char_array_p(__s, __n))
493 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
494#endif
ace857f9 495 return wmemchr(__s, __a, __n);
4a88769c 496 }
725dc051 497
b6966987 498 static _GLIBCXX20_CONSTEXPR char_type*
73a530bd 499 move(char_type* __s1, const char_type* __s2, size_t __n)
4a88769c
JW
500 {
501 if (__n == 0)
502 return __s1;
b6966987
JW
503#ifdef __cpp_lib_is_constant_evaluated
504 if (std::is_constant_evaluated())
505 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
506#endif
4a88769c
JW
507 return wmemmove(__s1, __s2, __n);
508 }
725dc051 509
b6966987 510 static _GLIBCXX20_CONSTEXPR char_type*
725dc051 511 copy(char_type* __s1, const char_type* __s2, size_t __n)
4a88769c
JW
512 {
513 if (__n == 0)
514 return __s1;
b6966987
JW
515#ifdef __cpp_lib_is_constant_evaluated
516 if (std::is_constant_evaluated())
517 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
518#endif
4a88769c
JW
519 return wmemcpy(__s1, __s2, __n);
520 }
725dc051 521
b6966987 522 static _GLIBCXX20_CONSTEXPR char_type*
725dc051 523 assign(char_type* __s, size_t __n, char_type __a)
4a88769c
JW
524 {
525 if (__n == 0)
526 return __s;
b6966987
JW
527#ifdef __cpp_lib_is_constant_evaluated
528 if (std::is_constant_evaluated())
529 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
530#endif
4a88769c
JW
531 return wmemset(__s, __a, __n);
532 }
725dc051 533
94a86be0 534 static _GLIBCXX_CONSTEXPR char_type
2789f415 535 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
2fb63453 536 { return char_type(__c); }
725dc051 537
94a86be0 538 static _GLIBCXX_CONSTEXPR int_type
2789f415 539 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
2fb63453 540 { return int_type(__c); }
725dc051 541
94a86be0 542 static _GLIBCXX_CONSTEXPR bool
2789f415 543 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
725dc051
BK
544 { return __c1 == __c2; }
545
94a86be0 546 static _GLIBCXX_CONSTEXPR int_type
2789f415 547 eof() _GLIBCXX_NOEXCEPT
2fb63453 548 { return static_cast<int_type>(WEOF); }
725dc051 549
94a86be0 550 static _GLIBCXX_CONSTEXPR int_type
2789f415 551 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
725dc051
BK
552 { return eq_int_type(__c, eof()) ? 0 : __c; }
553 };
3d7c150e 554#endif //_GLIBCXX_USE_WCHAR_T
725dc051 555
c124af93
TH
556#ifdef _GLIBCXX_USE_CHAR8_T
557 template<>
558 struct char_traits<char8_t>
559 {
560 typedef char8_t char_type;
561 typedef unsigned int int_type;
562 typedef u8streampos pos_type;
563 typedef streamoff off_type;
564 typedef mbstate_t state_type;
875d6cb3
JW
565#if __cpp_lib_three_way_comparison
566 using comparison_category = strong_ordering;
567#endif
c124af93
TH
568
569 static _GLIBCXX17_CONSTEXPR void
570 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
571 { __c1 = __c2; }
572
573 static _GLIBCXX_CONSTEXPR bool
574 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
575 { return __c1 == __c2; }
576
577 static _GLIBCXX_CONSTEXPR bool
578 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
579 { return __c1 < __c2; }
580
581 static _GLIBCXX17_CONSTEXPR int
582 compare(const char_type* __s1, const char_type* __s2, size_t __n)
583 {
ace857f9
JW
584 if (__n == 0)
585 return 0;
c124af93
TH
586#if __cplusplus > 201402
587 if (__builtin_constant_p(__n)
588 && __constant_char_array_p(__s1, __n)
589 && __constant_char_array_p(__s2, __n))
590 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
591#endif
c124af93
TH
592 return __builtin_memcmp(__s1, __s2, __n);
593 }
594
595 static _GLIBCXX17_CONSTEXPR size_t
596 length(const char_type* __s)
597 {
598#if __cplusplus > 201402
599 if (__constant_string_p(__s))
600 return __gnu_cxx::char_traits<char_type>::length(__s);
601#endif
602 size_t __i = 0;
603 while (!eq(__s[__i], char_type()))
604 ++__i;
605 return __i;
606 }
607
608 static _GLIBCXX17_CONSTEXPR const char_type*
609 find(const char_type* __s, size_t __n, const char_type& __a)
610 {
ace857f9
JW
611 if (__n == 0)
612 return 0;
c124af93
TH
613#if __cplusplus > 201402
614 if (__builtin_constant_p(__n)
615 && __builtin_constant_p(__a)
616 && __constant_char_array_p(__s, __n))
617 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
618#endif
c124af93
TH
619 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
620 }
621
b6966987 622 static _GLIBCXX20_CONSTEXPR char_type*
c124af93
TH
623 move(char_type* __s1, const char_type* __s2, size_t __n)
624 {
625 if (__n == 0)
626 return __s1;
b6966987
JW
627#ifdef __cpp_lib_is_constant_evaluated
628 if (std::is_constant_evaluated())
629 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
630#endif
c124af93
TH
631 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
632 }
633
b6966987 634 static _GLIBCXX20_CONSTEXPR char_type*
c124af93
TH
635 copy(char_type* __s1, const char_type* __s2, size_t __n)
636 {
637 if (__n == 0)
638 return __s1;
b6966987
JW
639#ifdef __cpp_lib_is_constant_evaluated
640 if (std::is_constant_evaluated())
641 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
642#endif
c124af93
TH
643 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
644 }
645
b6966987 646 static _GLIBCXX20_CONSTEXPR char_type*
c124af93
TH
647 assign(char_type* __s, size_t __n, char_type __a)
648 {
649 if (__n == 0)
650 return __s;
b6966987
JW
651#ifdef __cpp_lib_is_constant_evaluated
652 if (std::is_constant_evaluated())
653 return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
654#endif
c124af93
TH
655 return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
656 }
657
658 static _GLIBCXX_CONSTEXPR char_type
659 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
660 { return char_type(__c); }
661
662 static _GLIBCXX_CONSTEXPR int_type
663 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
664 { return int_type(__c); }
665
666 static _GLIBCXX_CONSTEXPR bool
667 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
668 { return __c1 == __c2; }
669
670 static _GLIBCXX_CONSTEXPR int_type
671 eof() _GLIBCXX_NOEXCEPT
672 { return static_cast<int_type>(-1); }
673
674 static _GLIBCXX_CONSTEXPR int_type
675 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
676 { return eq_int_type(__c, eof()) ? 0 : __c; }
677 };
678#endif //_GLIBCXX_USE_CHAR8_T
679
12ffa228
BK
680_GLIBCXX_END_NAMESPACE_VERSION
681} // namespace
725dc051 682
612c9c70 683#if __cplusplus >= 201103L
5e44d591
PC
684
685#include <cstdint>
686
12ffa228
BK
687namespace std _GLIBCXX_VISIBILITY(default)
688{
689_GLIBCXX_BEGIN_NAMESPACE_VERSION
5e44d591
PC
690
691 template<>
692 struct char_traits<char16_t>
693 {
694 typedef char16_t char_type;
612c9c70 695#ifdef _GLIBCXX_USE_C99_STDINT_TR1
5e44d591 696 typedef uint_least16_t int_type;
612c9c70
JW
697#elif defined __UINT_LEAST16_TYPE__
698 typedef __UINT_LEAST16_TYPE__ int_type;
699#else
700 typedef make_unsigned<char16_t>::type int_type;
701#endif
5e44d591
PC
702 typedef streamoff off_type;
703 typedef u16streampos pos_type;
704 typedef mbstate_t state_type;
875d6cb3
JW
705#if __cpp_lib_three_way_comparison
706 using comparison_category = strong_ordering;
707#endif
5e44d591 708
8c3b5c71 709 static _GLIBCXX17_CONSTEXPR void
2789f415 710 assign(char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
711 { __c1 = __c2; }
712
2789f415
PC
713 static constexpr bool
714 eq(const char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
715 { return __c1 == __c2; }
716
2789f415
PC
717 static constexpr bool
718 lt(const char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
719 { return __c1 < __c2; }
720
8c3b5c71 721 static _GLIBCXX17_CONSTEXPR int
5e44d591
PC
722 compare(const char_type* __s1, const char_type* __s2, size_t __n)
723 {
724 for (size_t __i = 0; __i < __n; ++__i)
725 if (lt(__s1[__i], __s2[__i]))
726 return -1;
727 else if (lt(__s2[__i], __s1[__i]))
728 return 1;
729 return 0;
730 }
731
8c3b5c71 732 static _GLIBCXX17_CONSTEXPR size_t
5e44d591
PC
733 length(const char_type* __s)
734 {
735 size_t __i = 0;
736 while (!eq(__s[__i], char_type()))
737 ++__i;
738 return __i;
739 }
740
8c3b5c71 741 static _GLIBCXX17_CONSTEXPR const char_type*
5e44d591
PC
742 find(const char_type* __s, size_t __n, const char_type& __a)
743 {
744 for (size_t __i = 0; __i < __n; ++__i)
745 if (eq(__s[__i], __a))
746 return __s + __i;
747 return 0;
748 }
749
b6966987 750 static _GLIBCXX20_CONSTEXPR char_type*
5e44d591
PC
751 move(char_type* __s1, const char_type* __s2, size_t __n)
752 {
4a88769c
JW
753 if (__n == 0)
754 return __s1;
b6966987
JW
755#ifdef __cpp_lib_is_constant_evaluated
756 if (std::is_constant_evaluated())
757 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
758#endif
5e44d591
PC
759 return (static_cast<char_type*>
760 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
761 }
762
b6966987 763 static _GLIBCXX20_CONSTEXPR char_type*
5e44d591
PC
764 copy(char_type* __s1, const char_type* __s2, size_t __n)
765 {
4a88769c
JW
766 if (__n == 0)
767 return __s1;
b6966987
JW
768#ifdef __cpp_lib_is_constant_evaluated
769 if (std::is_constant_evaluated())
770 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
771#endif
5e44d591
PC
772 return (static_cast<char_type*>
773 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
774 }
775
b6966987 776 static _GLIBCXX20_CONSTEXPR char_type*
5e44d591 777 assign(char_type* __s, size_t __n, char_type __a)
2fb63453
PC
778 {
779 for (size_t __i = 0; __i < __n; ++__i)
780 assign(__s[__i], __a);
5e44d591
PC
781 return __s;
782 }
783
2789f415
PC
784 static constexpr char_type
785 to_char_type(const int_type& __c) noexcept
2fb63453 786 { return char_type(__c); }
5e44d591 787
2789f415
PC
788 static constexpr int_type
789 to_int_type(const char_type& __c) noexcept
4c19e432 790 { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
5e44d591 791
2789f415
PC
792 static constexpr bool
793 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
5e44d591
PC
794 { return __c1 == __c2; }
795
2789f415
PC
796 static constexpr int_type
797 eof() noexcept
2fb63453 798 { return static_cast<int_type>(-1); }
5e44d591 799
2789f415
PC
800 static constexpr int_type
801 not_eof(const int_type& __c) noexcept
5e44d591
PC
802 { return eq_int_type(__c, eof()) ? 0 : __c; }
803 };
804
805 template<>
806 struct char_traits<char32_t>
807 {
808 typedef char32_t char_type;
612c9c70 809#ifdef _GLIBCXX_USE_C99_STDINT_TR1
5e44d591 810 typedef uint_least32_t int_type;
612c9c70
JW
811#elif defined __UINT_LEAST32_TYPE__
812 typedef __UINT_LEAST32_TYPE__ int_type;
813#else
814 typedef make_unsigned<char32_t>::type int_type;
815#endif
5e44d591
PC
816 typedef streamoff off_type;
817 typedef u32streampos pos_type;
818 typedef mbstate_t state_type;
875d6cb3
JW
819#if __cpp_lib_three_way_comparison
820 using comparison_category = strong_ordering;
821#endif
5e44d591 822
8c3b5c71 823 static _GLIBCXX17_CONSTEXPR void
2789f415 824 assign(char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
825 { __c1 = __c2; }
826
2789f415
PC
827 static constexpr bool
828 eq(const char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
829 { return __c1 == __c2; }
830
2789f415
PC
831 static constexpr bool
832 lt(const char_type& __c1, const char_type& __c2) noexcept
5e44d591
PC
833 { return __c1 < __c2; }
834
8c3b5c71 835 static _GLIBCXX17_CONSTEXPR int
5e44d591
PC
836 compare(const char_type* __s1, const char_type* __s2, size_t __n)
837 {
838 for (size_t __i = 0; __i < __n; ++__i)
839 if (lt(__s1[__i], __s2[__i]))
840 return -1;
841 else if (lt(__s2[__i], __s1[__i]))
842 return 1;
843 return 0;
844 }
845
8c3b5c71 846 static _GLIBCXX17_CONSTEXPR size_t
5e44d591
PC
847 length(const char_type* __s)
848 {
849 size_t __i = 0;
850 while (!eq(__s[__i], char_type()))
851 ++__i;
852 return __i;
853 }
854
8c3b5c71 855 static _GLIBCXX17_CONSTEXPR const char_type*
5e44d591
PC
856 find(const char_type* __s, size_t __n, const char_type& __a)
857 {
858 for (size_t __i = 0; __i < __n; ++__i)
859 if (eq(__s[__i], __a))
860 return __s + __i;
861 return 0;
862 }
863
b6966987 864 static _GLIBCXX20_CONSTEXPR char_type*
5e44d591
PC
865 move(char_type* __s1, const char_type* __s2, size_t __n)
866 {
4a88769c
JW
867 if (__n == 0)
868 return __s1;
b6966987
JW
869#ifdef __cpp_lib_is_constant_evaluated
870 if (std::is_constant_evaluated())
871 return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
872#endif
5e44d591
PC
873 return (static_cast<char_type*>
874 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
875 }
876
b6966987 877 static _GLIBCXX20_CONSTEXPR char_type*
5e44d591
PC
878 copy(char_type* __s1, const char_type* __s2, size_t __n)
879 {
4a88769c
JW
880 if (__n == 0)
881 return __s1;
b6966987
JW
882#ifdef __cpp_lib_is_constant_evaluated
883 if (std::is_constant_evaluated())
884 return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
885#endif
5e44d591
PC
886 return (static_cast<char_type*>
887 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
888 }
889
b6966987 890 static _GLIBCXX20_CONSTEXPR char_type*
5e44d591
PC
891 assign(char_type* __s, size_t __n, char_type __a)
892 {
2fb63453
PC
893 for (size_t __i = 0; __i < __n; ++__i)
894 assign(__s[__i], __a);
5e44d591
PC
895 return __s;
896 }
897
2789f415
PC
898 static constexpr char_type
899 to_char_type(const int_type& __c) noexcept
2fb63453 900 { return char_type(__c); }
5e44d591 901
2789f415
PC
902 static constexpr int_type
903 to_int_type(const char_type& __c) noexcept
2fb63453 904 { return int_type(__c); }
5e44d591 905
2789f415
PC
906 static constexpr bool
907 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
5e44d591
PC
908 { return __c1 == __c2; }
909
2789f415
PC
910 static constexpr int_type
911 eof() noexcept
2fb63453 912 { return static_cast<int_type>(-1); }
5e44d591 913
2789f415
PC
914 static constexpr int_type
915 not_eof(const int_type& __c) noexcept
5e44d591
PC
916 { return eq_int_type(__c, eof()) ? 0 : __c; }
917 };
918
875d6cb3
JW
919#if __cpp_lib_three_way_comparison
920 namespace __detail
921 {
922 template<typename _ChTraits>
923 constexpr auto
924 __char_traits_cmp_cat(int __cmp) noexcept
925 {
926 if constexpr (requires { typename _ChTraits::comparison_category; })
927 {
928 using _Cat = typename _ChTraits::comparison_category;
929 static_assert( !is_void_v<common_comparison_category_t<_Cat>> );
930 return static_cast<_Cat>(__cmp <=> 0);
931 }
932 else
933 return static_cast<weak_ordering>(__cmp <=> 0);
934 }
935 } // namespace __detail
936#endif // C++20
937
12ffa228
BK
938_GLIBCXX_END_NAMESPACE_VERSION
939} // namespace
5e44d591 940
612c9c70 941#endif // C++11
5e44d591 942
5e44d591 943#endif // _CHAR_TRAITS_H
This page took 2.037211 seconds and 5 git commands to generate.