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