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