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