1// Character Traits for use by standard string and iostream -*- C++ -*- 2 3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 2, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING. If not, write to the Free 19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20// USA. 21 22// As a special exception, you may use this file as part of a free software 23// library without restriction. Specifically, if other files instantiate 24// templates or use macros or inline functions from this file, or you compile 25// this file and link it with other files to produce an executable, this 26// file does not by itself cause the resulting executable to be covered by 27// the GNU General Public License. This exception does not however 28// invalidate any other reasons why the executable file might be covered by 29// the GNU General Public License. 30 31// 32// ISO C++ 14882: 21 Strings library 33// 34 35/** @file char_traits.h 36 * This is an internal header file, included by other library headers. 37 * You should not attempt to use it directly. 38 */ 39 40#ifndef _CPP_BITS_CHAR_TRAITS_H 41#define _CPP_BITS_CHAR_TRAITS_H 1 42 43#pragma GCC system_header 44 45#include <cstring> // For memmove, memset, memchr 46#include <bits/fpos.h> // For streampos 47 48namespace __gnu_cxx 49{ 50 template<typename _CharT> 51 struct _Char_types 52 { 53 typedef unsigned long int_type; 54 typedef std::streampos pos_type; 55 typedef std::streamoff off_type; 56 typedef std::mbstate_t state_type; 57 }; 58 59 template<typename _CharT> 60 struct char_traits 61 { 62 typedef _CharT char_type; 63 typedef typename _Char_types<_CharT>::int_type int_type; 64 typedef typename _Char_types<_CharT>::pos_type pos_type; 65 typedef typename _Char_types<_CharT>::off_type off_type; 66 typedef typename _Char_types<_CharT>::state_type state_type; 67 68 static void 69 assign(char_type& __c1, const char_type& __c2) 70 { __c1 = __c2; } 71 72 static bool 73 eq(const char_type& __c1, const char_type& __c2) 74 { return __c1 == __c2; } 75 76 static bool 77 lt(const char_type& __c1, const char_type& __c2) 78 { return __c1 < __c2; } 79 80 static int 81 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 82 83 static std::size_t 84 length(const char_type* __s); 85 86 static const char_type* 87 find(const char_type* __s, std::size_t __n, const char_type& __a); 88 89 static char_type* 90 move(char_type* __s1, const char_type* __s2, std::size_t __n); 91 92 static char_type* 93 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 94 95 static char_type* 96 assign(char_type* __s, std::size_t __n, char_type __a); 97 98 static char_type 99 to_char_type(const int_type& __c) 100 { return static_cast<char_type>(__c); } 101 102 static int_type 103 to_int_type(const char_type& __c) 104 { return static_cast<int_type>(__c); } 105 106 static bool 107 eq_int_type(const int_type& __c1, const int_type& __c2) 108 { return __c1 == __c2; } 109 110 static int_type 111 eof() 112 { return static_cast<int_type>(EOF); } 113 114 static int_type 115 not_eof(const int_type& __c) 116 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 117 }; 118 119 template<typename _CharT> 120 int 121 char_traits<_CharT>:: 122 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 123 { 124 for (std::size_t __i = 0; __i < __n; ++__i) 125 if (lt(__s1[__i], __s2[__i])) 126 return -1; 127 else if (lt(__s2[__i], __s1[__i])) 128 return 1; 129 return 0; 130 } 131 132 template<typename _CharT> 133 std::size_t 134 char_traits<_CharT>:: 135 length(const char_type* __p) 136 { 137 std::size_t __i = 0; 138 while (!eq(__p[__i], char_type())) 139 ++__i; 140 return __i; 141 } 142 143 template<typename _CharT> 144 const typename char_traits<_CharT>::char_type* 145 char_traits<_CharT>:: 146 find(const char_type* __s, std::size_t __n, const char_type& __a) 147 { 148 for (std::size_t __i = 0; __i < __n; ++__i) 149 if (eq(__s[__i], __a)) 150 return __s + __i; 151 return 0; 152 } 153 154 template<typename _CharT> 155 typename char_traits<_CharT>::char_type* 156 char_traits<_CharT>:: 157 move(char_type* __s1, const char_type* __s2, std::size_t __n) 158 { 159 return static_cast<_CharT*>(memmove(__s1, __s2, 160 __n * sizeof(char_type))); 161 } 162 163 template<typename _CharT> 164 typename char_traits<_CharT>::char_type* 165 char_traits<_CharT>:: 166 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 167 { 168 // NB: Inline std::copy so no recursive dependencies. 169 std::copy(__s2, __s2 + __n, __s1); 170 return __s1; 171 } 172 173 template<typename _CharT> 174 typename char_traits<_CharT>::char_type* 175 char_traits<_CharT>:: 176 assign(char_type* __s, std::size_t __n, char_type __a) 177 { 178 // NB: Inline std::fill_n so no recursive dependencies. 179 std::fill_n(__s, __n, __a); 180 return __s; 181 } 182} 183 184namespace std 185{ 186 // 21.1 187 /** 188 * @brief Basis for explicit traits specializations. 189 * 190 * @note For any given actual character type, this definition is 191 * probably wrong. 192 * 193 * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 194 * for advice on how to make use of this class for "unusual" character 195 * types. 196 */ 197 template<class _CharT> 198 struct char_traits: public __gnu_cxx::char_traits<_CharT> 199 {}; 200 201 /// 21.1.3.1 char_traits specializations 202 template<> 203 struct char_traits<char> 204 { 205 typedef char char_type; 206 typedef int int_type; 207 typedef streampos pos_type; 208 typedef streamoff off_type; 209 typedef mbstate_t state_type; 210 211 static void 212 assign(char_type& __c1, const char_type& __c2) 213 { __c1 = __c2; } 214 215 static bool 216 eq(const char_type& __c1, const char_type& __c2) 217 { return __c1 == __c2; } 218 219 static bool 220 lt(const char_type& __c1, const char_type& __c2) 221 { return __c1 < __c2; } 222 223 static int 224 compare(const char_type* __s1, const char_type* __s2, size_t __n) 225 { return memcmp(__s1, __s2, __n); } 226 227 static size_t 228 length(const char_type* __s) 229 { return strlen(__s); } 230 231 static const char_type* 232 find(const char_type* __s, size_t __n, const char_type& __a) 233 { return static_cast<const char_type*>(memchr(__s, __a, __n)); } 234 235 static char_type* 236 move(char_type* __s1, const char_type* __s2, size_t __n) 237 { return static_cast<char_type*>(memmove(__s1, __s2, __n)); } 238 239 static char_type* 240 copy(char_type* __s1, const char_type* __s2, size_t __n) 241 { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); } 242 243 static char_type* 244 assign(char_type* __s, size_t __n, char_type __a) 245 { return static_cast<char_type*>(memset(__s, __a, __n)); } 246 247 static char_type 248 to_char_type(const int_type& __c) 249 { return static_cast<char_type>(__c); } 250 251 // To keep both the byte 0xff and the eof symbol 0xffffffff 252 // from ending up as 0xffffffff. 253 static int_type 254 to_int_type(const char_type& __c) 255 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 256 257 static bool 258 eq_int_type(const int_type& __c1, const int_type& __c2) 259 { return __c1 == __c2; } 260 261 static int_type 262 eof() { return static_cast<int_type>(EOF); } 263 264 static int_type 265 not_eof(const int_type& __c) 266 { return (__c == eof()) ? 0 : __c; } 267 }; 268 269 270#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T) 271 /// 21.1.3.2 char_traits specializations 272 template<> 273 struct char_traits<wchar_t> 274 { 275 typedef wchar_t char_type; 276 typedef wint_t int_type; 277 typedef streamoff off_type; 278 typedef wstreampos pos_type; 279 typedef mbstate_t state_type; 280 281 static void 282 assign(char_type& __c1, const char_type& __c2) 283 { __c1 = __c2; } 284 285 static bool 286 eq(const char_type& __c1, const char_type& __c2) 287 { return __c1 == __c2; } 288 289 static bool 290 lt(const char_type& __c1, const char_type& __c2) 291 { return __c1 < __c2; } 292 293 static int 294 compare(const char_type* __s1, const char_type* __s2, size_t __n) 295 { return wmemcmp(__s1, __s2, __n); } 296 297 static size_t 298 length(const char_type* __s) 299 { return wcslen(__s); } 300 301 static const char_type* 302 find(const char_type* __s, size_t __n, const char_type& __a) 303 { return wmemchr(__s, __a, __n); } 304 305 static char_type* 306 move(char_type* __s1, const char_type* __s2, int_type __n) 307 { return wmemmove(__s1, __s2, __n); } 308 309 static char_type* 310 copy(char_type* __s1, const char_type* __s2, size_t __n) 311 { return wmemcpy(__s1, __s2, __n); } 312 313 static char_type* 314 assign(char_type* __s, size_t __n, char_type __a) 315 { return wmemset(__s, __a, __n); } 316 317 static char_type 318 to_char_type(const int_type& __c) { return char_type(__c); } 319 320 static int_type 321 to_int_type(const char_type& __c) { return int_type(__c); } 322 323 static bool 324 eq_int_type(const int_type& __c1, const int_type& __c2) 325 { return __c1 == __c2; } 326 327 static int_type 328 eof() { return static_cast<int_type>(WEOF); } 329 330 static int_type 331 not_eof(const int_type& __c) 332 { return eq_int_type(__c, eof()) ? 0 : __c; } 333 }; 334#endif //_GLIBCPP_USE_WCHAR_T 335 336 template<typename _CharT, typename _Traits> 337 struct _Char_traits_match 338 { 339 _CharT _M_c; 340 _Char_traits_match(_CharT const& __c) : _M_c(__c) { } 341 342 bool 343 operator()(_CharT const& __a) { return _Traits::eq(_M_c, __a); } 344 }; 345} // namespace std 346 347#endif 348