libstdc++
|
00001 // Character Traits for use by standard string and iostream -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 00004 // 2006, 2007, 2008, 2009, 2010, 2011 00005 // Free Software Foundation, Inc. 00006 // 00007 // This file is part of the GNU ISO C++ Library. This library is free 00008 // software; you can redistribute it and/or modify it under the 00009 // terms of the GNU General Public License as published by the 00010 // Free Software Foundation; either version 3, or (at your option) 00011 // any later version. 00012 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU General Public License for more details. 00017 00018 // Under Section 7 of GPL version 3, you are granted additional 00019 // permissions described in the GCC Runtime Library Exception, version 00020 // 3.1, as published by the Free Software Foundation. 00021 00022 // You should have received a copy of the GNU General Public License and 00023 // a copy of the GCC Runtime Library Exception along with this program; 00024 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00025 // <http://www.gnu.org/licenses/>. 00026 00027 /** @file bits/char_traits.h 00028 * This is an internal header file, included by other library headers. 00029 * Do not attempt to use it directly. @headername{string} 00030 */ 00031 00032 // 00033 // ISO C++ 14882: 21 Strings library 00034 // 00035 00036 #ifndef _CHAR_TRAITS_H 00037 #define _CHAR_TRAITS_H 1 00038 00039 #pragma GCC system_header 00040 00041 #include <bits/stl_algobase.h> // std::copy, std::fill_n 00042 #include <bits/postypes.h> // For streampos 00043 #include <cwchar> // For WEOF, wmemmove, wmemset, etc. 00044 00045 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00046 { 00047 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00048 00049 /** 00050 * @brief Mapping from character type to associated types. 00051 * 00052 * @note This is an implementation class for the generic version 00053 * of char_traits. It defines int_type, off_type, pos_type, and 00054 * state_type. By default these are unsigned long, streamoff, 00055 * streampos, and mbstate_t. Users who need a different set of 00056 * types, but who don't need to change the definitions of any function 00057 * defined in char_traits, can specialize __gnu_cxx::_Char_types 00058 * while leaving __gnu_cxx::char_traits alone. */ 00059 template<typename _CharT> 00060 struct _Char_types 00061 { 00062 typedef unsigned long int_type; 00063 typedef std::streampos pos_type; 00064 typedef std::streamoff off_type; 00065 typedef std::mbstate_t state_type; 00066 }; 00067 00068 00069 /** 00070 * @brief Base class used to implement std::char_traits. 00071 * 00072 * @note For any given actual character type, this definition is 00073 * probably wrong. (Most of the member functions are likely to be 00074 * right, but the int_type and state_type typedefs, and the eof() 00075 * member function, are likely to be wrong.) The reason this class 00076 * exists is so users can specialize it. Classes in namespace std 00077 * may not be specialized for fundamental types, but classes in 00078 * namespace __gnu_cxx may be. 00079 * 00080 * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html 00081 * for advice on how to make use of this class for @a unusual character 00082 * types. Also, check out include/ext/pod_char_traits.h. 00083 */ 00084 template<typename _CharT> 00085 struct char_traits 00086 { 00087 typedef _CharT char_type; 00088 typedef typename _Char_types<_CharT>::int_type int_type; 00089 typedef typename _Char_types<_CharT>::pos_type pos_type; 00090 typedef typename _Char_types<_CharT>::off_type off_type; 00091 typedef typename _Char_types<_CharT>::state_type state_type; 00092 00093 static void 00094 assign(char_type& __c1, const char_type& __c2) 00095 { __c1 = __c2; } 00096 00097 static _GLIBCXX_CONSTEXPR bool 00098 eq(const char_type& __c1, const char_type& __c2) 00099 { return __c1 == __c2; } 00100 00101 static _GLIBCXX_CONSTEXPR bool 00102 lt(const char_type& __c1, const char_type& __c2) 00103 { return __c1 < __c2; } 00104 00105 static int 00106 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 00107 00108 static std::size_t 00109 length(const char_type* __s); 00110 00111 static const char_type* 00112 find(const char_type* __s, std::size_t __n, const char_type& __a); 00113 00114 static char_type* 00115 move(char_type* __s1, const char_type* __s2, std::size_t __n); 00116 00117 static char_type* 00118 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 00119 00120 static char_type* 00121 assign(char_type* __s, std::size_t __n, char_type __a); 00122 00123 static _GLIBCXX_CONSTEXPR char_type 00124 to_char_type(const int_type& __c) 00125 { return static_cast<char_type>(__c); } 00126 00127 static _GLIBCXX_CONSTEXPR int_type 00128 to_int_type(const char_type& __c) 00129 { return static_cast<int_type>(__c); } 00130 00131 static _GLIBCXX_CONSTEXPR bool 00132 eq_int_type(const int_type& __c1, const int_type& __c2) 00133 { return __c1 == __c2; } 00134 00135 static _GLIBCXX_CONSTEXPR int_type 00136 eof() 00137 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00138 00139 static _GLIBCXX_CONSTEXPR int_type 00140 not_eof(const int_type& __c) 00141 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 00142 }; 00143 00144 template<typename _CharT> 00145 int 00146 char_traits<_CharT>:: 00147 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 00148 { 00149 for (std::size_t __i = 0; __i < __n; ++__i) 00150 if (lt(__s1[__i], __s2[__i])) 00151 return -1; 00152 else if (lt(__s2[__i], __s1[__i])) 00153 return 1; 00154 return 0; 00155 } 00156 00157 template<typename _CharT> 00158 std::size_t 00159 char_traits<_CharT>:: 00160 length(const char_type* __p) 00161 { 00162 std::size_t __i = 0; 00163 while (!eq(__p[__i], char_type())) 00164 ++__i; 00165 return __i; 00166 } 00167 00168 template<typename _CharT> 00169 const typename char_traits<_CharT>::char_type* 00170 char_traits<_CharT>:: 00171 find(const char_type* __s, std::size_t __n, const char_type& __a) 00172 { 00173 for (std::size_t __i = 0; __i < __n; ++__i) 00174 if (eq(__s[__i], __a)) 00175 return __s + __i; 00176 return 0; 00177 } 00178 00179 template<typename _CharT> 00180 typename char_traits<_CharT>::char_type* 00181 char_traits<_CharT>:: 00182 move(char_type* __s1, const char_type* __s2, std::size_t __n) 00183 { 00184 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 00185 __n * sizeof(char_type))); 00186 } 00187 00188 template<typename _CharT> 00189 typename char_traits<_CharT>::char_type* 00190 char_traits<_CharT>:: 00191 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 00192 { 00193 // NB: Inline std::copy so no recursive dependencies. 00194 std::copy(__s2, __s2 + __n, __s1); 00195 return __s1; 00196 } 00197 00198 template<typename _CharT> 00199 typename char_traits<_CharT>::char_type* 00200 char_traits<_CharT>:: 00201 assign(char_type* __s, std::size_t __n, char_type __a) 00202 { 00203 // NB: Inline std::fill_n so no recursive dependencies. 00204 std::fill_n(__s, __n, __a); 00205 return __s; 00206 } 00207 00208 _GLIBCXX_END_NAMESPACE_VERSION 00209 } // namespace 00210 00211 namespace std _GLIBCXX_VISIBILITY(default) 00212 { 00213 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00214 00215 // 21.1 00216 /** 00217 * @brief Basis for explicit traits specializations. 00218 * 00219 * @note For any given actual character type, this definition is 00220 * probably wrong. Since this is just a thin wrapper around 00221 * __gnu_cxx::char_traits, it is possible to achieve a more 00222 * appropriate definition by specializing __gnu_cxx::char_traits. 00223 * 00224 * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html 00225 * for advice on how to make use of this class for @a unusual character 00226 * types. Also, check out include/ext/pod_char_traits.h. 00227 */ 00228 template<class _CharT> 00229 struct char_traits : public __gnu_cxx::char_traits<_CharT> 00230 { }; 00231 00232 00233 /// 21.1.3.1 char_traits specializations 00234 template<> 00235 struct char_traits<char> 00236 { 00237 typedef char char_type; 00238 typedef int int_type; 00239 typedef streampos pos_type; 00240 typedef streamoff off_type; 00241 typedef mbstate_t state_type; 00242 00243 static void 00244 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00245 { __c1 = __c2; } 00246 00247 static _GLIBCXX_CONSTEXPR bool 00248 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00249 { return __c1 == __c2; } 00250 00251 static _GLIBCXX_CONSTEXPR bool 00252 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00253 { return __c1 < __c2; } 00254 00255 static int 00256 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00257 { return __builtin_memcmp(__s1, __s2, __n); } 00258 00259 static size_t 00260 length(const char_type* __s) 00261 { return __builtin_strlen(__s); } 00262 00263 static const char_type* 00264 find(const char_type* __s, size_t __n, const char_type& __a) 00265 { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); } 00266 00267 static char_type* 00268 move(char_type* __s1, const char_type* __s2, size_t __n) 00269 { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); } 00270 00271 static char_type* 00272 copy(char_type* __s1, const char_type* __s2, size_t __n) 00273 { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); } 00274 00275 static char_type* 00276 assign(char_type* __s, size_t __n, char_type __a) 00277 { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); } 00278 00279 static _GLIBCXX_CONSTEXPR char_type 00280 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00281 { return static_cast<char_type>(__c); } 00282 00283 // To keep both the byte 0xff and the eof symbol 0xffffffff 00284 // from ending up as 0xffffffff. 00285 static _GLIBCXX_CONSTEXPR int_type 00286 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00287 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 00288 00289 static _GLIBCXX_CONSTEXPR bool 00290 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00291 { return __c1 == __c2; } 00292 00293 static _GLIBCXX_CONSTEXPR int_type 00294 eof() _GLIBCXX_NOEXCEPT 00295 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00296 00297 static _GLIBCXX_CONSTEXPR int_type 00298 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00299 { return (__c == eof()) ? 0 : __c; } 00300 }; 00301 00302 00303 #ifdef _GLIBCXX_USE_WCHAR_T 00304 /// 21.1.3.2 char_traits specializations 00305 template<> 00306 struct char_traits<wchar_t> 00307 { 00308 typedef wchar_t char_type; 00309 typedef wint_t int_type; 00310 typedef streamoff off_type; 00311 typedef wstreampos pos_type; 00312 typedef mbstate_t state_type; 00313 00314 static void 00315 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00316 { __c1 = __c2; } 00317 00318 static _GLIBCXX_CONSTEXPR bool 00319 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00320 { return __c1 == __c2; } 00321 00322 static _GLIBCXX_CONSTEXPR bool 00323 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00324 { return __c1 < __c2; } 00325 00326 static int 00327 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00328 { return wmemcmp(__s1, __s2, __n); } 00329 00330 static size_t 00331 length(const char_type* __s) 00332 { return wcslen(__s); } 00333 00334 static const char_type* 00335 find(const char_type* __s, size_t __n, const char_type& __a) 00336 { return wmemchr(__s, __a, __n); } 00337 00338 static char_type* 00339 move(char_type* __s1, const char_type* __s2, size_t __n) 00340 { return wmemmove(__s1, __s2, __n); } 00341 00342 static char_type* 00343 copy(char_type* __s1, const char_type* __s2, size_t __n) 00344 { return wmemcpy(__s1, __s2, __n); } 00345 00346 static char_type* 00347 assign(char_type* __s, size_t __n, char_type __a) 00348 { return wmemset(__s, __a, __n); } 00349 00350 static _GLIBCXX_CONSTEXPR char_type 00351 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00352 { return char_type(__c); } 00353 00354 static _GLIBCXX_CONSTEXPR int_type 00355 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00356 { return int_type(__c); } 00357 00358 static _GLIBCXX_CONSTEXPR bool 00359 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00360 { return __c1 == __c2; } 00361 00362 static _GLIBCXX_CONSTEXPR int_type 00363 eof() _GLIBCXX_NOEXCEPT 00364 { return static_cast<int_type>(WEOF); } 00365 00366 static _GLIBCXX_CONSTEXPR int_type 00367 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00368 { return eq_int_type(__c, eof()) ? 0 : __c; } 00369 }; 00370 #endif //_GLIBCXX_USE_WCHAR_T 00371 00372 _GLIBCXX_END_NAMESPACE_VERSION 00373 } // namespace 00374 00375 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) \ 00376 && defined(_GLIBCXX_USE_C99_STDINT_TR1)) 00377 00378 #include <cstdint> 00379 00380 namespace std _GLIBCXX_VISIBILITY(default) 00381 { 00382 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00383 00384 template<> 00385 struct char_traits<char16_t> 00386 { 00387 typedef char16_t char_type; 00388 typedef uint_least16_t int_type; 00389 typedef streamoff off_type; 00390 typedef u16streampos pos_type; 00391 typedef mbstate_t state_type; 00392 00393 static void 00394 assign(char_type& __c1, const char_type& __c2) noexcept 00395 { __c1 = __c2; } 00396 00397 static constexpr bool 00398 eq(const char_type& __c1, const char_type& __c2) noexcept 00399 { return __c1 == __c2; } 00400 00401 static constexpr bool 00402 lt(const char_type& __c1, const char_type& __c2) noexcept 00403 { return __c1 < __c2; } 00404 00405 static int 00406 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00407 { 00408 for (size_t __i = 0; __i < __n; ++__i) 00409 if (lt(__s1[__i], __s2[__i])) 00410 return -1; 00411 else if (lt(__s2[__i], __s1[__i])) 00412 return 1; 00413 return 0; 00414 } 00415 00416 static size_t 00417 length(const char_type* __s) 00418 { 00419 size_t __i = 0; 00420 while (!eq(__s[__i], char_type())) 00421 ++__i; 00422 return __i; 00423 } 00424 00425 static const char_type* 00426 find(const char_type* __s, size_t __n, const char_type& __a) 00427 { 00428 for (size_t __i = 0; __i < __n; ++__i) 00429 if (eq(__s[__i], __a)) 00430 return __s + __i; 00431 return 0; 00432 } 00433 00434 static char_type* 00435 move(char_type* __s1, const char_type* __s2, size_t __n) 00436 { 00437 return (static_cast<char_type*> 00438 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00439 } 00440 00441 static char_type* 00442 copy(char_type* __s1, const char_type* __s2, size_t __n) 00443 { 00444 return (static_cast<char_type*> 00445 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00446 } 00447 00448 static char_type* 00449 assign(char_type* __s, size_t __n, char_type __a) 00450 { 00451 for (size_t __i = 0; __i < __n; ++__i) 00452 assign(__s[__i], __a); 00453 return __s; 00454 } 00455 00456 static constexpr char_type 00457 to_char_type(const int_type& __c) noexcept 00458 { return char_type(__c); } 00459 00460 static constexpr int_type 00461 to_int_type(const char_type& __c) noexcept 00462 { return int_type(__c); } 00463 00464 static constexpr bool 00465 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00466 { return __c1 == __c2; } 00467 00468 static constexpr int_type 00469 eof() noexcept 00470 { return static_cast<int_type>(-1); } 00471 00472 static constexpr int_type 00473 not_eof(const int_type& __c) noexcept 00474 { return eq_int_type(__c, eof()) ? 0 : __c; } 00475 }; 00476 00477 template<> 00478 struct char_traits<char32_t> 00479 { 00480 typedef char32_t char_type; 00481 typedef uint_least32_t int_type; 00482 typedef streamoff off_type; 00483 typedef u32streampos pos_type; 00484 typedef mbstate_t state_type; 00485 00486 static void 00487 assign(char_type& __c1, const char_type& __c2) noexcept 00488 { __c1 = __c2; } 00489 00490 static constexpr bool 00491 eq(const char_type& __c1, const char_type& __c2) noexcept 00492 { return __c1 == __c2; } 00493 00494 static constexpr bool 00495 lt(const char_type& __c1, const char_type& __c2) noexcept 00496 { return __c1 < __c2; } 00497 00498 static int 00499 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00500 { 00501 for (size_t __i = 0; __i < __n; ++__i) 00502 if (lt(__s1[__i], __s2[__i])) 00503 return -1; 00504 else if (lt(__s2[__i], __s1[__i])) 00505 return 1; 00506 return 0; 00507 } 00508 00509 static size_t 00510 length(const char_type* __s) 00511 { 00512 size_t __i = 0; 00513 while (!eq(__s[__i], char_type())) 00514 ++__i; 00515 return __i; 00516 } 00517 00518 static const char_type* 00519 find(const char_type* __s, size_t __n, const char_type& __a) 00520 { 00521 for (size_t __i = 0; __i < __n; ++__i) 00522 if (eq(__s[__i], __a)) 00523 return __s + __i; 00524 return 0; 00525 } 00526 00527 static char_type* 00528 move(char_type* __s1, const char_type* __s2, size_t __n) 00529 { 00530 return (static_cast<char_type*> 00531 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00532 } 00533 00534 static char_type* 00535 copy(char_type* __s1, const char_type* __s2, size_t __n) 00536 { 00537 return (static_cast<char_type*> 00538 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00539 } 00540 00541 static char_type* 00542 assign(char_type* __s, size_t __n, char_type __a) 00543 { 00544 for (size_t __i = 0; __i < __n; ++__i) 00545 assign(__s[__i], __a); 00546 return __s; 00547 } 00548 00549 static constexpr char_type 00550 to_char_type(const int_type& __c) noexcept 00551 { return char_type(__c); } 00552 00553 static constexpr int_type 00554 to_int_type(const char_type& __c) noexcept 00555 { return int_type(__c); } 00556 00557 static constexpr bool 00558 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00559 { return __c1 == __c2; } 00560 00561 static constexpr int_type 00562 eof() noexcept 00563 { return static_cast<int_type>(-1); } 00564 00565 static constexpr int_type 00566 not_eof(const int_type& __c) noexcept 00567 { return eq_int_type(__c, eof()) ? 0 : __c; } 00568 }; 00569 00570 _GLIBCXX_END_NAMESPACE_VERSION 00571 } // namespace 00572 00573 #endif 00574 00575 #endif // _CHAR_TRAITS_H