char_traits.h

Go to the documentation of this file.
00001 // Character Traits for use by standard string and iostream -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 // 00032 // ISO C++ 14882: 21 Strings library 00033 // 00034 00035 /** @file char_traits.h 00036 * This is an internal header file, included by other library headers. 00037 * You should not attempt to use it directly. 00038 */ 00039 00040 #ifndef _CHAR_TRAITS_H 00041 #define _CHAR_TRAITS_H 1 00042 00043 #pragma GCC system_header 00044 00045 #include <cstring> // For memmove, memset, memchr 00046 #include <bits/stl_algobase.h>// For copy, lexicographical_compare, fill_n 00047 #include <bits/postypes.h> // For streampos 00048 00049 namespace __gnu_cxx 00050 { 00051 /** 00052 * @brief Mapping from character type to associated types. 00053 * 00054 * 00055 * @note This is an implementation class for the generic version 00056 * of char_traits. It defines int_type, off_type, pos_type, and 00057 * state_type. By default these are unsigned long, streamoff, 00058 * streampos, and mbstate_t. Users who need a different set of 00059 * types, but who don't need to change the definitions of any function 00060 * defined in char_traits, can specialize __gnu_cxx::_Char_types 00061 * while leaving __gnu_cxx::char_traits alone. */ 00062 template <class _CharT> 00063 struct _Char_types 00064 { 00065 typedef unsigned long int_type; 00066 typedef std::streampos pos_type; 00067 typedef std::streamoff off_type; 00068 typedef std::mbstate_t state_type; 00069 }; 00070 00071 00072 /** 00073 * @brief Base class used to implement std::char_traits. 00074 * 00075 * @note For any given actual character type, this definition is 00076 * probably wrong. (Most of the member functions are likely to be 00077 * right, but the int_type and state_type typedefs, and the eof() 00078 * member function, are likely to be wrong.) The reason this class 00079 * exists is so users can specialize it. Classes in namespace std 00080 * may not be specialized for fundamentl types, but classes in 00081 * namespace __gnu_cxx may be. 00082 * 00083 * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 00084 * for advice on how to make use of this class for "unusual" character 00085 * types. Also, check out include/ext/pod_char_traits.h. */ 00086 template<typename _CharT> 00087 struct char_traits 00088 { 00089 typedef _CharT char_type; 00090 typedef typename _Char_types<_CharT>::int_type int_type; 00091 typedef typename _Char_types<_CharT>::pos_type pos_type; 00092 typedef typename _Char_types<_CharT>::off_type off_type; 00093 typedef typename _Char_types<_CharT>::state_type state_type; 00094 00095 static void 00096 assign(char_type& __c1, const char_type& __c2) 00097 { __c1 = __c2; } 00098 00099 static bool 00100 eq(const char_type& __c1, const char_type& __c2) 00101 { return __c1 == __c2; } 00102 00103 static bool 00104 lt(const char_type& __c1, const char_type& __c2) 00105 { return __c1 < __c2; } 00106 00107 static int 00108 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 00109 00110 static std::size_t 00111 length(const char_type* __s); 00112 00113 static const char_type* 00114 find(const char_type* __s, std::size_t __n, const char_type& __a); 00115 00116 static char_type* 00117 move(char_type* __s1, const char_type* __s2, std::size_t __n); 00118 00119 static char_type* 00120 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 00121 00122 static char_type* 00123 assign(char_type* __s, std::size_t __n, char_type __a); 00124 00125 static char_type 00126 to_char_type(const int_type& __c) 00127 { return static_cast<char_type>(__c); } 00128 00129 static int_type 00130 to_int_type(const char_type& __c) 00131 { return static_cast<int_type>(__c); } 00132 00133 static bool 00134 eq_int_type(const int_type& __c1, const int_type& __c2) 00135 { return __c1 == __c2; } 00136 00137 static int_type 00138 eof() 00139 { return static_cast<int_type>(EOF); } 00140 00141 static int_type 00142 not_eof(const int_type& __c) 00143 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 00144 }; 00145 00146 template<typename _CharT> 00147 int 00148 char_traits<_CharT>:: 00149 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 00150 { 00151 for (size_t __i = 0; __i < __n; ++__i) 00152 if (lt(__s1[__i], __s2[__i])) 00153 return -1; 00154 else if (lt(__s2[__i], __s1[__i])) 00155 return 1; 00156 return 0; 00157 } 00158 00159 template<typename _CharT> 00160 std::size_t 00161 char_traits<_CharT>:: 00162 length(const char_type* __p) 00163 { 00164 std::size_t __i = 0; 00165 while (!eq(__p[__i], char_type())) 00166 ++__i; 00167 return __i; 00168 } 00169 00170 template<typename _CharT> 00171 const typename char_traits<_CharT>::char_type* 00172 char_traits<_CharT>:: 00173 find(const char_type* __s, std::size_t __n, const char_type& __a) 00174 { 00175 for (std::size_t __i = 0; __i < __n; ++__i) 00176 if (eq(__s[__i], __a)) 00177 return __s + __i; 00178 return 0; 00179 } 00180 00181 template<typename _CharT> 00182 typename char_traits<_CharT>::char_type* 00183 char_traits<_CharT>:: 00184 move(char_type* __s1, const char_type* __s2, std::size_t __n) 00185 { 00186 return static_cast<_CharT*>(std::memmove(__s1, __s2, 00187 __n * sizeof(char_type))); 00188 } 00189 00190 template<typename _CharT> 00191 typename char_traits<_CharT>::char_type* 00192 char_traits<_CharT>:: 00193 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 00194 { 00195 std::copy(__s2, __s2 + __n, __s1); 00196 return __s1; 00197 } 00198 00199 template<typename _CharT> 00200 typename char_traits<_CharT>::char_type* 00201 char_traits<_CharT>:: 00202 assign(char_type* __s, std::size_t __n, char_type __a) 00203 { 00204 std::fill_n(__s, __n, __a); 00205 return __s; 00206 } 00207 } 00208 00209 namespace std 00210 { 00211 // 21.1 00212 /** 00213 * @brief Basis for explicit traits specializations. 00214 * 00215 * @note For any given actual character type, this definition is 00216 * probably wrong. Since this is just a thin wrapper around 00217 * __gnu_cxx::char_traits, it is possible to achieve a more 00218 * appropriate definition by specializing __gnu_cxx::char_traits. 00219 * 00220 * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 00221 * for advice on how to make use of this class for "unusual" character 00222 * types. Also, check out include/ext/pod_char_traits.h. 00223 */ 00224 template<class _CharT> 00225 struct char_traits 00226 : public __gnu_cxx::char_traits<_CharT> 00227 { }; 00228 00229 00230 /// 21.1.3.1 char_traits specializations 00231 template<> 00232 struct char_traits<char> 00233 { 00234 typedef char char_type; 00235 typedef int int_type; 00236 typedef streampos pos_type; 00237 typedef streamoff off_type; 00238 typedef mbstate_t state_type; 00239 00240 static void 00241 assign(char_type& __c1, const char_type& __c2) 00242 { __c1 = __c2; } 00243 00244 static bool 00245 eq(const char_type& __c1, const char_type& __c2) 00246 { return __c1 == __c2; } 00247 00248 static bool 00249 lt(const char_type& __c1, const char_type& __c2) 00250 { return __c1 < __c2; } 00251 00252 static int 00253 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00254 { return memcmp(__s1, __s2, __n); } 00255 00256 static size_t 00257 length(const char_type* __s) 00258 { return strlen(__s); } 00259 00260 static const char_type* 00261 find(const char_type* __s, size_t __n, const char_type& __a) 00262 { return static_cast<const char_type*>(memchr(__s, __a, __n)); } 00263 00264 static char_type* 00265 move(char_type* __s1, const char_type* __s2, size_t __n) 00266 { return static_cast<char_type*>(memmove(__s1, __s2, __n)); } 00267 00268 static char_type* 00269 copy(char_type* __s1, const char_type* __s2, size_t __n) 00270 { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); } 00271 00272 static char_type* 00273 assign(char_type* __s, size_t __n, char_type __a) 00274 { return static_cast<char_type*>(memset(__s, __a, __n)); } 00275 00276 static char_type 00277 to_char_type(const int_type& __c) 00278 { return static_cast<char_type>(__c); } 00279 00280 // To keep both the byte 0xff and the eof symbol 0xffffffff 00281 // from ending up as 0xffffffff. 00282 static int_type 00283 to_int_type(const char_type& __c) 00284 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 00285 00286 static bool 00287 eq_int_type(const int_type& __c1, const int_type& __c2) 00288 { return __c1 == __c2; } 00289 00290 static int_type 00291 eof() { return static_cast<int_type>(EOF); } 00292 00293 static int_type 00294 not_eof(const int_type& __c) 00295 { return (__c == eof()) ? 0 : __c; } 00296 }; 00297 00298 00299 #ifdef _GLIBCXX_USE_WCHAR_T 00300 /// 21.1.3.2 char_traits specializations 00301 template<> 00302 struct char_traits<wchar_t> 00303 { 00304 typedef wchar_t char_type; 00305 typedef wint_t int_type; 00306 typedef streamoff off_type; 00307 typedef wstreampos pos_type; 00308 typedef mbstate_t state_type; 00309 00310 static void 00311 assign(char_type& __c1, const char_type& __c2) 00312 { __c1 = __c2; } 00313 00314 static bool 00315 eq(const char_type& __c1, const char_type& __c2) 00316 { return __c1 == __c2; } 00317 00318 static bool 00319 lt(const char_type& __c1, const char_type& __c2) 00320 { return __c1 < __c2; } 00321 00322 static int 00323 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00324 { return wmemcmp(__s1, __s2, __n); } 00325 00326 static size_t 00327 length(const char_type* __s) 00328 { return wcslen(__s); } 00329 00330 static const char_type* 00331 find(const char_type* __s, size_t __n, const char_type& __a) 00332 { return wmemchr(__s, __a, __n); } 00333 00334 static char_type* 00335 move(char_type* __s1, const char_type* __s2, size_t __n) 00336 { return wmemmove(__s1, __s2, __n); } 00337 00338 static char_type* 00339 copy(char_type* __s1, const char_type* __s2, size_t __n) 00340 { return wmemcpy(__s1, __s2, __n); } 00341 00342 static char_type* 00343 assign(char_type* __s, size_t __n, char_type __a) 00344 { return wmemset(__s, __a, __n); } 00345 00346 static char_type 00347 to_char_type(const int_type& __c) { return char_type(__c); } 00348 00349 static int_type 00350 to_int_type(const char_type& __c) { return int_type(__c); } 00351 00352 static bool 00353 eq_int_type(const int_type& __c1, const int_type& __c2) 00354 { return __c1 == __c2; } 00355 00356 static int_type 00357 eof() { return static_cast<int_type>(WEOF); } 00358 00359 static int_type 00360 not_eof(const int_type& __c) 00361 { return eq_int_type(__c, eof()) ? 0 : __c; } 00362 }; 00363 #endif //_GLIBCXX_USE_WCHAR_T 00364 00365 template<typename _CharT, typename _Traits> 00366 struct _Char_traits_match 00367 { 00368 _CharT _M_c; 00369 _Char_traits_match(_CharT const& __c) : _M_c(__c) { } 00370 00371 bool 00372 operator()(_CharT const& __a) { return _Traits::eq(_M_c, __a); } 00373 }; 00374 } // namespace std 00375 00376 #endif

Generated on Wed Jun 9 11:18:16 2004 for libstdc++-v3 Source by doxygen 1.3.7