]>
Commit | Line | Data |
---|---|---|
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, |
1814157e | 4 | // 2006, 2007, 2008 |
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 | |
10 | // Free Software Foundation; either version 2, 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 | // You should have received a copy of the GNU General Public License along | |
19 | // with this library; see the file COPYING. If not, write to the Free | |
83f51799 | 20 | // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
725dc051 BK |
21 | // USA. |
22 | ||
23 | // As a special exception, you may use this file as part of a free software | |
24 | // library without restriction. Specifically, if other files instantiate | |
25 | // templates or use macros or inline functions from this file, or you compile | |
26 | // this file and link it with other files to produce an executable, this | |
27 | // file does not by itself cause the resulting executable to be covered by | |
28 | // the GNU General Public License. This exception does not however | |
29 | // invalidate any other reasons why the executable file might be covered by | |
30 | // the GNU General Public License. | |
31 | ||
729e3d3f PE |
32 | /** @file char_traits.h |
33 | * This is an internal header file, included by other library headers. | |
34 | * You should not attempt to use it directly. | |
35 | */ | |
36 | ||
143c27b0 BK |
37 | // |
38 | // ISO C++ 14882: 21 Strings library | |
39 | // | |
40 | ||
3d7c150e BK |
41 | #ifndef _CHAR_TRAITS_H |
42 | #define _CHAR_TRAITS_H 1 | |
725dc051 | 43 | |
b0a85b86 GDR |
44 | #pragma GCC system_header |
45 | ||
4f39bf5c | 46 | #include <bits/stl_algobase.h> // std::copy, std::fill_n |
39b8cd70 | 47 | #include <bits/postypes.h> // For streampos |
39b8cd70 | 48 | #include <cwchar> // For WEOF, wmemmove, wmemset, etc. |
725dc051 | 49 | |
1814157e PC |
50 | #ifndef _GLIBCXX_STDIO_MACROS |
51 | # include <cstdio> // For EOF | |
52 | # define _CHAR_TRAITS_EOF EOF | |
53 | #else | |
54 | # define _CHAR_TRAITS_EOF (-1) | |
55 | #endif | |
56 | ||
3cbc7af0 BK |
57 | _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) |
58 | ||
aa2d5ba2 | 59 | /** |
d5ff4e3f | 60 | * @brief Mapping from character type to associated types. |
ed6814f7 | 61 | * |
d5ff4e3f MA |
62 | * @note This is an implementation class for the generic version |
63 | * of char_traits. It defines int_type, off_type, pos_type, and | |
64 | * state_type. By default these are unsigned long, streamoff, | |
ed6814f7 | 65 | * streampos, and mbstate_t. Users who need a different set of |
d5ff4e3f MA |
66 | * types, but who don't need to change the definitions of any function |
67 | * defined in char_traits, can specialize __gnu_cxx::_Char_types | |
68 | * while leaving __gnu_cxx::char_traits alone. */ | |
65be6ddd | 69 | template<typename _CharT> |
d5ff4e3f MA |
70 | struct _Char_types |
71 | { | |
72 | typedef unsigned long int_type; | |
73 | typedef std::streampos pos_type; | |
74 | typedef std::streamoff off_type; | |
75 | typedef std::mbstate_t state_type; | |
76 | }; | |
77 | ||
78 | ||
79 | /** | |
80 | * @brief Base class used to implement std::char_traits. | |
81 | * | |
82 | * @note For any given actual character type, this definition is | |
83 | * probably wrong. (Most of the member functions are likely to be | |
84 | * right, but the int_type and state_type typedefs, and the eof() | |
85 | * member function, are likely to be wrong.) The reason this class | |
86 | * exists is so users can specialize it. Classes in namespace std | |
28dac70a | 87 | * may not be specialized for fundamental types, but classes in |
d5ff4e3f | 88 | * namespace __gnu_cxx may be. |
51122a42 PE |
89 | * |
90 | * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 | |
91 | * for advice on how to make use of this class for "unusual" character | |
6309eefc BK |
92 | * types. Also, check out include/ext/pod_char_traits.h. |
93 | */ | |
d5ff4e3f | 94 | template<typename _CharT> |
725dc051 BK |
95 | struct char_traits |
96 | { | |
d5ff4e3f MA |
97 | typedef _CharT char_type; |
98 | typedef typename _Char_types<_CharT>::int_type int_type; | |
99 | typedef typename _Char_types<_CharT>::pos_type pos_type; | |
100 | typedef typename _Char_types<_CharT>::off_type off_type; | |
101 | typedef typename _Char_types<_CharT>::state_type state_type; | |
ed6814f7 BI |
102 | |
103 | static void | |
d5ff4e3f MA |
104 | assign(char_type& __c1, const char_type& __c2) |
105 | { __c1 = __c2; } | |
725dc051 | 106 | |
ed6814f7 | 107 | static bool |
d5ff4e3f MA |
108 | eq(const char_type& __c1, const char_type& __c2) |
109 | { return __c1 == __c2; } | |
725dc051 | 110 | |
ed6814f7 | 111 | static bool |
d5ff4e3f MA |
112 | lt(const char_type& __c1, const char_type& __c2) |
113 | { return __c1 < __c2; } | |
725dc051 | 114 | |
ed6814f7 | 115 | static int |
d5ff4e3f | 116 | compare(const char_type* __s1, const char_type* __s2, std::size_t __n); |
725dc051 | 117 | |
d5ff4e3f | 118 | static std::size_t |
f13a69ec | 119 | length(const char_type* __s); |
725dc051 | 120 | |
ed6814f7 | 121 | static const char_type* |
d5ff4e3f | 122 | find(const char_type* __s, std::size_t __n, const char_type& __a); |
725dc051 | 123 | |
ed6814f7 | 124 | static char_type* |
d5ff4e3f | 125 | move(char_type* __s1, const char_type* __s2, std::size_t __n); |
725dc051 | 126 | |
ed6814f7 | 127 | static char_type* |
d5ff4e3f | 128 | copy(char_type* __s1, const char_type* __s2, std::size_t __n); |
725dc051 | 129 | |
ed6814f7 | 130 | static char_type* |
d5ff4e3f | 131 | assign(char_type* __s, std::size_t __n, char_type __a); |
725dc051 | 132 | |
ed6814f7 | 133 | static char_type |
d5ff4e3f MA |
134 | to_char_type(const int_type& __c) |
135 | { return static_cast<char_type>(__c); } | |
725dc051 | 136 | |
ed6814f7 | 137 | static int_type |
d5ff4e3f MA |
138 | to_int_type(const char_type& __c) |
139 | { return static_cast<int_type>(__c); } | |
725dc051 | 140 | |
ed6814f7 | 141 | static bool |
d5ff4e3f MA |
142 | eq_int_type(const int_type& __c1, const int_type& __c2) |
143 | { return __c1 == __c2; } | |
725dc051 | 144 | |
ed6814f7 | 145 | static int_type |
d5ff4e3f | 146 | eof() |
1814157e | 147 | { return static_cast<int_type>(_CHAR_TRAITS_EOF); } |
725dc051 | 148 | |
ed6814f7 | 149 | static int_type |
d5ff4e3f | 150 | not_eof(const int_type& __c) |
5a9ed693 | 151 | { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } |
725dc051 BK |
152 | }; |
153 | ||
d5ff4e3f MA |
154 | template<typename _CharT> |
155 | int | |
156 | char_traits<_CharT>:: | |
157 | compare(const char_type* __s1, const char_type* __s2, std::size_t __n) | |
158 | { | |
05a2763e | 159 | for (std::size_t __i = 0; __i < __n; ++__i) |
d5ff4e3f MA |
160 | if (lt(__s1[__i], __s2[__i])) |
161 | return -1; | |
162 | else if (lt(__s2[__i], __s1[__i])) | |
163 | return 1; | |
164 | return 0; | |
165 | } | |
166 | ||
167 | template<typename _CharT> | |
168 | std::size_t | |
169 | char_traits<_CharT>:: | |
170 | length(const char_type* __p) | |
171 | { | |
172 | std::size_t __i = 0; | |
173 | while (!eq(__p[__i], char_type())) | |
174 | ++__i; | |
175 | return __i; | |
176 | } | |
177 | ||
178 | template<typename _CharT> | |
ed6814f7 | 179 | const typename char_traits<_CharT>::char_type* |
d5ff4e3f MA |
180 | char_traits<_CharT>:: |
181 | find(const char_type* __s, std::size_t __n, const char_type& __a) | |
182 | { | |
183 | for (std::size_t __i = 0; __i < __n; ++__i) | |
184 | if (eq(__s[__i], __a)) | |
185 | return __s + __i; | |
186 | return 0; | |
187 | } | |
188 | ||
189 | template<typename _CharT> | |
190 | typename char_traits<_CharT>::char_type* | |
191 | char_traits<_CharT>:: | |
192 | move(char_type* __s1, const char_type* __s2, std::size_t __n) | |
193 | { | |
538075fe PC |
194 | return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, |
195 | __n * sizeof(char_type))); | |
d5ff4e3f MA |
196 | } |
197 | ||
198 | template<typename _CharT> | |
ed6814f7 | 199 | typename char_traits<_CharT>::char_type* |
d5ff4e3f MA |
200 | char_traits<_CharT>:: |
201 | copy(char_type* __s1, const char_type* __s2, std::size_t __n) | |
202 | { | |
c2ba9709 | 203 | // NB: Inline std::copy so no recursive dependencies. |
d5ff4e3f MA |
204 | std::copy(__s2, __s2 + __n, __s1); |
205 | return __s1; | |
206 | } | |
207 | ||
208 | template<typename _CharT> | |
ed6814f7 | 209 | typename char_traits<_CharT>::char_type* |
d5ff4e3f MA |
210 | char_traits<_CharT>:: |
211 | assign(char_type* __s, std::size_t __n, char_type __a) | |
212 | { | |
c2ba9709 | 213 | // NB: Inline std::fill_n so no recursive dependencies. |
d5ff4e3f MA |
214 | std::fill_n(__s, __n, __a); |
215 | return __s; | |
216 | } | |
d5ff4e3f | 217 | |
3cbc7af0 BK |
218 | _GLIBCXX_END_NAMESPACE |
219 | ||
220 | _GLIBCXX_BEGIN_NAMESPACE(std) | |
221 | ||
d5ff4e3f MA |
222 | // 21.1 |
223 | /** | |
224 | * @brief Basis for explicit traits specializations. | |
225 | * | |
226 | * @note For any given actual character type, this definition is | |
227 | * probably wrong. Since this is just a thin wrapper around | |
228 | * __gnu_cxx::char_traits, it is possible to achieve a more | |
229 | * appropriate definition by specializing __gnu_cxx::char_traits. | |
230 | * | |
231 | * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 | |
232 | * for advice on how to make use of this class for "unusual" character | |
233 | * types. Also, check out include/ext/pod_char_traits.h. | |
234 | */ | |
235 | template<class _CharT> | |
6309eefc | 236 | struct char_traits : public __gnu_cxx::char_traits<_CharT> |
d5ff4e3f MA |
237 | { }; |
238 | ||
97644827 | 239 | |
939759fc | 240 | /// 21.1.3.1 char_traits specializations |
725dc051 BK |
241 | template<> |
242 | struct char_traits<char> | |
243 | { | |
d5ff4e3f MA |
244 | typedef char char_type; |
245 | typedef int int_type; | |
246 | typedef streampos pos_type; | |
247 | typedef streamoff off_type; | |
248 | typedef mbstate_t state_type; | |
725dc051 | 249 | |
ed6814f7 | 250 | static void |
725dc051 BK |
251 | assign(char_type& __c1, const char_type& __c2) |
252 | { __c1 = __c2; } | |
253 | ||
ed6814f7 | 254 | static bool |
725dc051 | 255 | eq(const char_type& __c1, const char_type& __c2) |
462ec415 | 256 | { return __c1 == __c2; } |
725dc051 | 257 | |
ed6814f7 | 258 | static bool |
725dc051 BK |
259 | lt(const char_type& __c1, const char_type& __c2) |
260 | { return __c1 < __c2; } | |
261 | ||
ed6814f7 | 262 | static int |
725dc051 | 263 | compare(const char_type* __s1, const char_type* __s2, size_t __n) |
538075fe | 264 | { return __builtin_memcmp(__s1, __s2, __n); } |
725dc051 BK |
265 | |
266 | static size_t | |
267 | length(const char_type* __s) | |
538075fe | 268 | { return __builtin_strlen(__s); } |
725dc051 | 269 | |
ed6814f7 | 270 | static const char_type* |
725dc051 | 271 | find(const char_type* __s, size_t __n, const char_type& __a) |
538075fe | 272 | { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); } |
725dc051 | 273 | |
ed6814f7 | 274 | static char_type* |
725dc051 | 275 | move(char_type* __s1, const char_type* __s2, size_t __n) |
538075fe | 276 | { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); } |
725dc051 | 277 | |
ed6814f7 | 278 | static char_type* |
725dc051 | 279 | copy(char_type* __s1, const char_type* __s2, size_t __n) |
538075fe | 280 | { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); } |
725dc051 | 281 | |
ed6814f7 | 282 | static char_type* |
725dc051 | 283 | assign(char_type* __s, size_t __n, char_type __a) |
538075fe | 284 | { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); } |
725dc051 | 285 | |
ed6814f7 | 286 | static char_type |
725dc051 BK |
287 | to_char_type(const int_type& __c) |
288 | { return static_cast<char_type>(__c); } | |
289 | ||
290 | // To keep both the byte 0xff and the eof symbol 0xffffffff | |
291 | // from ending up as 0xffffffff. | |
ed6814f7 | 292 | static int_type |
725dc051 BK |
293 | to_int_type(const char_type& __c) |
294 | { return static_cast<int_type>(static_cast<unsigned char>(__c)); } | |
295 | ||
ed6814f7 | 296 | static bool |
725dc051 BK |
297 | eq_int_type(const int_type& __c1, const int_type& __c2) |
298 | { return __c1 == __c2; } | |
299 | ||
ed6814f7 | 300 | static int_type |
1814157e | 301 | eof() { return static_cast<int_type>(_CHAR_TRAITS_EOF); } |
725dc051 | 302 | |
ed6814f7 | 303 | static int_type |
725dc051 BK |
304 | not_eof(const int_type& __c) |
305 | { return (__c == eof()) ? 0 : __c; } | |
306 | }; | |
307 | ||
308 | ||
3d7c150e | 309 | #ifdef _GLIBCXX_USE_WCHAR_T |
939759fc | 310 | /// 21.1.3.2 char_traits specializations |
725dc051 BK |
311 | template<> |
312 | struct char_traits<wchar_t> | |
313 | { | |
d5ff4e3f MA |
314 | typedef wchar_t char_type; |
315 | typedef wint_t int_type; | |
316 | typedef streamoff off_type; | |
317 | typedef wstreampos pos_type; | |
318 | typedef mbstate_t state_type; | |
ed6814f7 BI |
319 | |
320 | static void | |
725dc051 BK |
321 | assign(char_type& __c1, const char_type& __c2) |
322 | { __c1 = __c2; } | |
323 | ||
ed6814f7 | 324 | static bool |
462ec415 JJ |
325 | eq(const char_type& __c1, const char_type& __c2) |
326 | { return __c1 == __c2; } | |
725dc051 | 327 | |
ed6814f7 | 328 | static bool |
725dc051 BK |
329 | lt(const char_type& __c1, const char_type& __c2) |
330 | { return __c1 < __c2; } | |
331 | ||
ed6814f7 | 332 | static int |
725dc051 BK |
333 | compare(const char_type* __s1, const char_type* __s2, size_t __n) |
334 | { return wmemcmp(__s1, __s2, __n); } | |
335 | ||
336 | static size_t | |
337 | length(const char_type* __s) | |
338 | { return wcslen(__s); } | |
339 | ||
ed6814f7 | 340 | static const char_type* |
725dc051 BK |
341 | find(const char_type* __s, size_t __n, const char_type& __a) |
342 | { return wmemchr(__s, __a, __n); } | |
343 | ||
ed6814f7 | 344 | static char_type* |
73a530bd | 345 | move(char_type* __s1, const char_type* __s2, size_t __n) |
725dc051 BK |
346 | { return wmemmove(__s1, __s2, __n); } |
347 | ||
ed6814f7 | 348 | static char_type* |
725dc051 BK |
349 | copy(char_type* __s1, const char_type* __s2, size_t __n) |
350 | { return wmemcpy(__s1, __s2, __n); } | |
351 | ||
ed6814f7 | 352 | static char_type* |
725dc051 BK |
353 | assign(char_type* __s, size_t __n, char_type __a) |
354 | { return wmemset(__s, __a, __n); } | |
355 | ||
ed6814f7 | 356 | static char_type |
725dc051 BK |
357 | to_char_type(const int_type& __c) { return char_type(__c); } |
358 | ||
ed6814f7 | 359 | static int_type |
725dc051 BK |
360 | to_int_type(const char_type& __c) { return int_type(__c); } |
361 | ||
ed6814f7 | 362 | static bool |
725dc051 BK |
363 | eq_int_type(const int_type& __c1, const int_type& __c2) |
364 | { return __c1 == __c2; } | |
365 | ||
ed6814f7 | 366 | static int_type |
725dc051 BK |
367 | eof() { return static_cast<int_type>(WEOF); } |
368 | ||
ed6814f7 | 369 | static int_type |
725dc051 BK |
370 | not_eof(const int_type& __c) |
371 | { return eq_int_type(__c, eof()) ? 0 : __c; } | |
372 | }; | |
3d7c150e | 373 | #endif //_GLIBCXX_USE_WCHAR_T |
725dc051 | 374 | |
3cbc7af0 | 375 | _GLIBCXX_END_NAMESPACE |
725dc051 | 376 | |
d32c94be | 377 | #endif |