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