]>
Commit | Line | Data |
---|---|---|
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 |
47 | namespace __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 |
215 | namespace 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 |
623 | namespace 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 |