197403Sobrien// Character Traits for use by standard string and iostream -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 4102782Skan// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien/** @file char_traits.h 3297403Sobrien * This is an internal header file, included by other library headers. 3397403Sobrien * You should not attempt to use it directly. 3497403Sobrien */ 3597403Sobrien 36169691Skan// 37169691Skan// ISO C++ 14882: 21 Strings library 38169691Skan// 39169691Skan 40132720Skan#ifndef _CHAR_TRAITS_H 41132720Skan#define _CHAR_TRAITS_H 1 4297403Sobrien 4397403Sobrien#pragma GCC system_header 4497403Sobrien 45117397Skan#include <cstring> // For memmove, memset, memchr 46132720Skan#include <bits/stl_algobase.h>// For copy, lexicographical_compare, fill_n 47132720Skan#include <bits/postypes.h> // For streampos 4897403Sobrien 49169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 50169691Skan 51117397Skan /** 52132720Skan * @brief Mapping from character type to associated types. 53117397Skan * 54132720Skan * @note This is an implementation class for the generic version 55132720Skan * of char_traits. It defines int_type, off_type, pos_type, and 56132720Skan * state_type. By default these are unsigned long, streamoff, 57132720Skan * streampos, and mbstate_t. Users who need a different set of 58132720Skan * types, but who don't need to change the definitions of any function 59132720Skan * defined in char_traits, can specialize __gnu_cxx::_Char_types 60132720Skan * while leaving __gnu_cxx::char_traits alone. */ 61132720Skan template <class _CharT> 62132720Skan struct _Char_types 63132720Skan { 64132720Skan typedef unsigned long int_type; 65132720Skan typedef std::streampos pos_type; 66132720Skan typedef std::streamoff off_type; 67132720Skan typedef std::mbstate_t state_type; 68132720Skan }; 69132720Skan 70132720Skan 71132720Skan /** 72132720Skan * @brief Base class used to implement std::char_traits. 73132720Skan * 74132720Skan * @note For any given actual character type, this definition is 75132720Skan * probably wrong. (Most of the member functions are likely to be 76132720Skan * right, but the int_type and state_type typedefs, and the eof() 77132720Skan * member function, are likely to be wrong.) The reason this class 78132720Skan * exists is so users can specialize it. Classes in namespace std 79132720Skan * may not be specialized for fundamentl types, but classes in 80132720Skan * namespace __gnu_cxx may be. 81132720Skan * 82117397Skan * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 83117397Skan * for advice on how to make use of this class for "unusual" character 84169691Skan * types. Also, check out include/ext/pod_char_traits.h. 85169691Skan */ 86132720Skan template<typename _CharT> 8797403Sobrien struct char_traits 8897403Sobrien { 89132720Skan typedef _CharT char_type; 90132720Skan typedef typename _Char_types<_CharT>::int_type int_type; 91132720Skan typedef typename _Char_types<_CharT>::pos_type pos_type; 92132720Skan typedef typename _Char_types<_CharT>::off_type off_type; 93132720Skan typedef typename _Char_types<_CharT>::state_type state_type; 9497403Sobrien 95132720Skan static void 96132720Skan assign(char_type& __c1, const char_type& __c2) 97132720Skan { __c1 = __c2; } 9897403Sobrien 99132720Skan static bool 100132720Skan eq(const char_type& __c1, const char_type& __c2) 101132720Skan { return __c1 == __c2; } 10297403Sobrien 103132720Skan static bool 104132720Skan lt(const char_type& __c1, const char_type& __c2) 105132720Skan { return __c1 < __c2; } 10697403Sobrien 107132720Skan static int 108132720Skan compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 109132720Skan 110132720Skan static std::size_t 111102782Skan length(const char_type* __s); 11297403Sobrien 113132720Skan static const char_type* 114132720Skan find(const char_type* __s, std::size_t __n, const char_type& __a); 11597403Sobrien 116132720Skan static char_type* 117132720Skan move(char_type* __s1, const char_type* __s2, std::size_t __n); 11897403Sobrien 119132720Skan static char_type* 120132720Skan copy(char_type* __s1, const char_type* __s2, std::size_t __n); 12197403Sobrien 122132720Skan static char_type* 123132720Skan assign(char_type* __s, std::size_t __n, char_type __a); 12497403Sobrien 125132720Skan static char_type 126132720Skan to_char_type(const int_type& __c) 127132720Skan { return static_cast<char_type>(__c); } 12897403Sobrien 129132720Skan static int_type 130132720Skan to_int_type(const char_type& __c) 131132720Skan { return static_cast<int_type>(__c); } 13297403Sobrien 133132720Skan static bool 134132720Skan eq_int_type(const int_type& __c1, const int_type& __c2) 135132720Skan { return __c1 == __c2; } 13697403Sobrien 137132720Skan static int_type 138132720Skan eof() 139132720Skan { return static_cast<int_type>(EOF); } 14097403Sobrien 141132720Skan static int_type 142132720Skan not_eof(const int_type& __c) 143132720Skan { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 14497403Sobrien }; 14597403Sobrien 146132720Skan template<typename _CharT> 147132720Skan int 148132720Skan char_traits<_CharT>:: 149132720Skan compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 150132720Skan { 151169691Skan for (std::size_t __i = 0; __i < __n; ++__i) 152132720Skan if (lt(__s1[__i], __s2[__i])) 153132720Skan return -1; 154132720Skan else if (lt(__s2[__i], __s1[__i])) 155132720Skan return 1; 156132720Skan return 0; 157132720Skan } 15897403Sobrien 159132720Skan template<typename _CharT> 160132720Skan std::size_t 161132720Skan char_traits<_CharT>:: 162132720Skan length(const char_type* __p) 163132720Skan { 164132720Skan std::size_t __i = 0; 165132720Skan while (!eq(__p[__i], char_type())) 166132720Skan ++__i; 167132720Skan return __i; 168132720Skan } 169132720Skan 170132720Skan template<typename _CharT> 171132720Skan const typename char_traits<_CharT>::char_type* 172132720Skan char_traits<_CharT>:: 173132720Skan find(const char_type* __s, std::size_t __n, const char_type& __a) 174132720Skan { 175132720Skan for (std::size_t __i = 0; __i < __n; ++__i) 176132720Skan if (eq(__s[__i], __a)) 177132720Skan return __s + __i; 178132720Skan return 0; 179132720Skan } 180132720Skan 181132720Skan template<typename _CharT> 182132720Skan typename char_traits<_CharT>::char_type* 183132720Skan char_traits<_CharT>:: 184132720Skan move(char_type* __s1, const char_type* __s2, std::size_t __n) 185132720Skan { 186132720Skan return static_cast<_CharT*>(std::memmove(__s1, __s2, 187132720Skan __n * sizeof(char_type))); 188132720Skan } 189132720Skan 190132720Skan template<typename _CharT> 191132720Skan typename char_traits<_CharT>::char_type* 192132720Skan char_traits<_CharT>:: 193132720Skan copy(char_type* __s1, const char_type* __s2, std::size_t __n) 194132720Skan { 195132720Skan std::copy(__s2, __s2 + __n, __s1); 196132720Skan return __s1; 197132720Skan } 198132720Skan 199132720Skan template<typename _CharT> 200132720Skan typename char_traits<_CharT>::char_type* 201132720Skan char_traits<_CharT>:: 202132720Skan assign(char_type* __s, std::size_t __n, char_type __a) 203132720Skan { 204132720Skan std::fill_n(__s, __n, __a); 205132720Skan return __s; 206132720Skan } 207132720Skan 208169691Skan_GLIBCXX_END_NAMESPACE 209169691Skan 210169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 211169691Skan 212132720Skan // 21.1 213132720Skan /** 214132720Skan * @brief Basis for explicit traits specializations. 215132720Skan * 216132720Skan * @note For any given actual character type, this definition is 217132720Skan * probably wrong. Since this is just a thin wrapper around 218132720Skan * __gnu_cxx::char_traits, it is possible to achieve a more 219132720Skan * appropriate definition by specializing __gnu_cxx::char_traits. 220132720Skan * 221132720Skan * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 222132720Skan * for advice on how to make use of this class for "unusual" character 223132720Skan * types. Also, check out include/ext/pod_char_traits.h. 224132720Skan */ 225132720Skan template<class _CharT> 226169691Skan struct char_traits : public __gnu_cxx::char_traits<_CharT> 227132720Skan { }; 228132720Skan 229132720Skan 230169691Skan /// @brief 21.1.3.1 char_traits specializations 23197403Sobrien template<> 23297403Sobrien struct char_traits<char> 23397403Sobrien { 234132720Skan typedef char char_type; 235132720Skan typedef int int_type; 236132720Skan typedef streampos pos_type; 237132720Skan typedef streamoff off_type; 238132720Skan typedef mbstate_t state_type; 23997403Sobrien 240132720Skan static void 24197403Sobrien assign(char_type& __c1, const char_type& __c2) 24297403Sobrien { __c1 = __c2; } 24397403Sobrien 244132720Skan static bool 24597403Sobrien eq(const char_type& __c1, const char_type& __c2) 24697403Sobrien { return __c1 == __c2; } 24797403Sobrien 248132720Skan static bool 24997403Sobrien lt(const char_type& __c1, const char_type& __c2) 25097403Sobrien { return __c1 < __c2; } 25197403Sobrien 252132720Skan static int 25397403Sobrien compare(const char_type* __s1, const char_type* __s2, size_t __n) 25497403Sobrien { return memcmp(__s1, __s2, __n); } 25597403Sobrien 25697403Sobrien static size_t 25797403Sobrien length(const char_type* __s) 25897403Sobrien { return strlen(__s); } 25997403Sobrien 260132720Skan static const char_type* 26197403Sobrien find(const char_type* __s, size_t __n, const char_type& __a) 26297403Sobrien { return static_cast<const char_type*>(memchr(__s, __a, __n)); } 26397403Sobrien 264132720Skan static char_type* 26597403Sobrien move(char_type* __s1, const char_type* __s2, size_t __n) 26697403Sobrien { return static_cast<char_type*>(memmove(__s1, __s2, __n)); } 26797403Sobrien 268132720Skan static char_type* 26997403Sobrien copy(char_type* __s1, const char_type* __s2, size_t __n) 270132720Skan { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); } 27197403Sobrien 272132720Skan static char_type* 27397403Sobrien assign(char_type* __s, size_t __n, char_type __a) 27497403Sobrien { return static_cast<char_type*>(memset(__s, __a, __n)); } 27597403Sobrien 276132720Skan static char_type 27797403Sobrien to_char_type(const int_type& __c) 27897403Sobrien { return static_cast<char_type>(__c); } 27997403Sobrien 28097403Sobrien // To keep both the byte 0xff and the eof symbol 0xffffffff 28197403Sobrien // from ending up as 0xffffffff. 282132720Skan static int_type 28397403Sobrien to_int_type(const char_type& __c) 28497403Sobrien { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 28597403Sobrien 286132720Skan static bool 28797403Sobrien eq_int_type(const int_type& __c1, const int_type& __c2) 28897403Sobrien { return __c1 == __c2; } 28997403Sobrien 290132720Skan static int_type 29197403Sobrien eof() { return static_cast<int_type>(EOF); } 29297403Sobrien 293132720Skan static int_type 29497403Sobrien not_eof(const int_type& __c) 29597403Sobrien { return (__c == eof()) ? 0 : __c; } 29697403Sobrien }; 29797403Sobrien 29897403Sobrien 299132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 300169691Skan /// @brief 21.1.3.2 char_traits specializations 30197403Sobrien template<> 30297403Sobrien struct char_traits<wchar_t> 30397403Sobrien { 304132720Skan typedef wchar_t char_type; 305132720Skan typedef wint_t int_type; 306132720Skan typedef streamoff off_type; 307132720Skan typedef wstreampos pos_type; 308132720Skan typedef mbstate_t state_type; 309132720Skan 310132720Skan static void 31197403Sobrien assign(char_type& __c1, const char_type& __c2) 31297403Sobrien { __c1 = __c2; } 31397403Sobrien 314132720Skan static bool 31597403Sobrien eq(const char_type& __c1, const char_type& __c2) 31697403Sobrien { return __c1 == __c2; } 31797403Sobrien 318132720Skan static bool 31997403Sobrien lt(const char_type& __c1, const char_type& __c2) 32097403Sobrien { return __c1 < __c2; } 32197403Sobrien 322132720Skan static int 32397403Sobrien compare(const char_type* __s1, const char_type* __s2, size_t __n) 32497403Sobrien { return wmemcmp(__s1, __s2, __n); } 32597403Sobrien 32697403Sobrien static size_t 32797403Sobrien length(const char_type* __s) 32897403Sobrien { return wcslen(__s); } 32997403Sobrien 330132720Skan static const char_type* 33197403Sobrien find(const char_type* __s, size_t __n, const char_type& __a) 33297403Sobrien { return wmemchr(__s, __a, __n); } 33397403Sobrien 334132720Skan static char_type* 335132720Skan move(char_type* __s1, const char_type* __s2, size_t __n) 33697403Sobrien { return wmemmove(__s1, __s2, __n); } 33797403Sobrien 338132720Skan static char_type* 33997403Sobrien copy(char_type* __s1, const char_type* __s2, size_t __n) 34097403Sobrien { return wmemcpy(__s1, __s2, __n); } 34197403Sobrien 342132720Skan static char_type* 34397403Sobrien assign(char_type* __s, size_t __n, char_type __a) 34497403Sobrien { return wmemset(__s, __a, __n); } 34597403Sobrien 346132720Skan static char_type 34797403Sobrien to_char_type(const int_type& __c) { return char_type(__c); } 34897403Sobrien 349132720Skan static int_type 35097403Sobrien to_int_type(const char_type& __c) { return int_type(__c); } 35197403Sobrien 352132720Skan static bool 35397403Sobrien eq_int_type(const int_type& __c1, const int_type& __c2) 35497403Sobrien { return __c1 == __c2; } 35597403Sobrien 356132720Skan static int_type 35797403Sobrien eof() { return static_cast<int_type>(WEOF); } 35897403Sobrien 359132720Skan static int_type 36097403Sobrien not_eof(const int_type& __c) 36197403Sobrien { return eq_int_type(__c, eof()) ? 0 : __c; } 36297403Sobrien }; 363132720Skan#endif //_GLIBCXX_USE_WCHAR_T 36497403Sobrien 365169691Skan_GLIBCXX_END_NAMESPACE 36697403Sobrien 36797403Sobrien#endif 368