ctype_members.cc revision 122182
1327Sjkh// std::ctype implementation details, GNU version -*- C++ -*- 2327Sjkh 3327Sjkh// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. 4327Sjkh// 5327Sjkh// This file is part of the GNU ISO C++ Library. This library is free 6327Sjkh// software; you can redistribute it and/or modify it under the 7327Sjkh// terms of the GNU General Public License as published by the 8327Sjkh// Free Software Foundation; either version 2, or (at your option) 9327Sjkh// any later version. 10327Sjkh 11327Sjkh// This library is distributed in the hope that it will be useful, 12327Sjkh// but WITHOUT ANY WARRANTY; without even the implied warranty of 13327Sjkh// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14327Sjkh// GNU General Public License for more details. 15327Sjkh 16327Sjkh// You should have received a copy of the GNU General Public License along 17327Sjkh// with this library; see the file COPYING. If not, write to the Free 18327Sjkh// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19327Sjkh// USA. 20327Sjkh 21327Sjkh// As a special exception, you may use this file as part of a free software 2293520Sobrien// library without restriction. Specifically, if other files instantiate 2393520Sobrien// templates or use macros or inline functions from this file, or you compile 2493520Sobrien// this file and link it with other files to produce an executable, this 25327Sjkh// file does not by itself cause the resulting executable to be covered by 26327Sjkh// the GNU General Public License. This exception does not however 271338Sjkh// invalidate any other reasons why the executable file might be covered by 28136643Sobrien// the GNU General Public License. 29327Sjkh 3017338Sjkh// 311338Sjkh// ISO C++ 14882: 22.2.1.1.2 ctype virtual functions. 32159554Sobrien// 33 34// Written by Benjamin Kosnik <bkoz@redhat.com> 35 36#include <locale> 37#include <bits/c++locale_internal.h> 38 39namespace std 40{ 41 // NB: The other ctype<char> specializations are in src/locale.cc and 42 // various /config/os/* files. 43 template<> 44 ctype_byname<char>::ctype_byname(const char* __s, size_t __refs) 45 : ctype<char>(0, false, __refs) 46 { 47 _S_destroy_c_locale(_M_c_locale_ctype); 48 _S_create_c_locale(_M_c_locale_ctype, __s); 49 _M_toupper = _M_c_locale_ctype->__ctype_toupper; 50 _M_tolower = _M_c_locale_ctype->__ctype_tolower; 51 _M_table = _M_c_locale_ctype->__ctype_b; 52 } 53 54#ifdef _GLIBCPP_USE_WCHAR_T 55 ctype<wchar_t>::__wmask_type 56 ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const 57 { 58 __wmask_type __ret; 59 switch (__m) 60 { 61 case space: 62 __ret = __wctype_l("space", _M_c_locale_ctype); 63 break; 64 case print: 65 __ret = __wctype_l("print", _M_c_locale_ctype); 66 break; 67 case cntrl: 68 __ret = __wctype_l("cntrl", _M_c_locale_ctype); 69 break; 70 case upper: 71 __ret = __wctype_l("upper", _M_c_locale_ctype); 72 break; 73 case lower: 74 __ret = __wctype_l("lower", _M_c_locale_ctype); 75 break; 76 case alpha: 77 __ret = __wctype_l("alpha", _M_c_locale_ctype); 78 break; 79 case digit: 80 __ret = __wctype_l("digit", _M_c_locale_ctype); 81 break; 82 case punct: 83 __ret = __wctype_l("punct", _M_c_locale_ctype); 84 break; 85 case xdigit: 86 __ret = __wctype_l("xdigit", _M_c_locale_ctype); 87 break; 88 case alnum: 89 __ret = __wctype_l("alnum", _M_c_locale_ctype); 90 break; 91 case graph: 92 __ret = __wctype_l("graph", _M_c_locale_ctype); 93 break; 94 default: 95 __ret = 0; 96 } 97 return __ret; 98 }; 99 100 wchar_t 101 ctype<wchar_t>::do_toupper(wchar_t __c) const 102 { return __towupper_l(__c, _M_c_locale_ctype); } 103 104 const wchar_t* 105 ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const 106 { 107 while (__lo < __hi) 108 { 109 *__lo = __towupper_l(*__lo, _M_c_locale_ctype); 110 ++__lo; 111 } 112 return __hi; 113 } 114 115 wchar_t 116 ctype<wchar_t>::do_tolower(wchar_t __c) const 117 { return __towlower_l(__c, _M_c_locale_ctype); } 118 119 const wchar_t* 120 ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const 121 { 122 while (__lo < __hi) 123 { 124 *__lo = __towlower_l(*__lo, _M_c_locale_ctype); 125 ++__lo; 126 } 127 return __hi; 128 } 129 130 bool 131 ctype<wchar_t>:: 132 do_is(mask __m, wchar_t __c) const 133 { 134 // Highest bitmask in ctype_base == 10, but extra in "C" 135 // library for blank. 136 bool __ret = false; 137 const size_t __bitmasksize = 11; 138 for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) 139 { 140 const mask __bit = static_cast<mask>(_ISbit(__bitcur)); 141 if (__m & __bit) 142 __ret |= __iswctype_l(__c, _M_convert_to_wmask(__bit), 143 _M_c_locale_ctype); 144 } 145 return __ret; 146 } 147 148 const wchar_t* 149 ctype<wchar_t>:: 150 do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const 151 { 152 for (;__lo < __hi; ++__vec, ++__lo) 153 { 154 // Highest bitmask in ctype_base == 10, but extra in "C" 155 // library for blank. 156 const size_t __bitmasksize = 11; 157 mask __m = 0; 158 for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) 159 { 160 const mask __bit = static_cast<mask>(_ISbit(__bitcur)); 161 if (__iswctype_l(*__lo, _M_convert_to_wmask(__bit), 162 _M_c_locale_ctype)) 163 __m |= __bit; 164 } 165 *__vec = __m; 166 } 167 return __hi; 168 } 169 170 const wchar_t* 171 ctype<wchar_t>:: 172 do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const 173 { 174 while (__lo < __hi && !this->do_is(__m, *__lo)) 175 ++__lo; 176 return __lo; 177 } 178 179 const wchar_t* 180 ctype<wchar_t>:: 181 do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const 182 { 183 while (__lo < __hi && this->do_is(__m, *__lo) != 0) 184 ++__lo; 185 return __lo; 186 } 187 188 wchar_t 189 ctype<wchar_t>:: 190 do_widen(char __c) const 191 { 192#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 193 __c_locale __old = __uselocale(_M_c_locale_ctype); 194#endif 195 wchar_t __ret = btowc(__c); 196#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 197 __uselocale(__old); 198#endif 199 return __ret; 200 } 201 202 const char* 203 ctype<wchar_t>:: 204 do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const 205 { 206#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 207 __c_locale __old = __uselocale(_M_c_locale_ctype); 208#endif 209 mbstate_t __state; 210 memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t)); 211 mbsrtowcs(__dest, &__lo, __hi - __lo, &__state); 212#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 213 __uselocale(__old); 214#endif 215 return __hi; 216 } 217 218 char 219 ctype<wchar_t>:: 220 do_narrow(wchar_t __wc, char __dfault) const 221 { 222#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 223 __c_locale __old = __uselocale(_M_c_locale_ctype); 224#endif 225 int __c = wctob(__wc); 226#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 227 __uselocale(__old); 228#endif 229 return (__c == EOF ? __dfault : static_cast<char>(__c)); 230 } 231 232 const wchar_t* 233 ctype<wchar_t>:: 234 do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, 235 char* __dest) const 236 { 237#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 238 __c_locale __old = __uselocale(_M_c_locale_ctype); 239#endif 240 size_t __offset = 0; 241 while (true) 242 { 243 const wchar_t* __start = __lo + __offset; 244 size_t __len = __hi - __start; 245 246 mbstate_t __state; 247 memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t)); 248 size_t __con = wcsrtombs(__dest + __offset, &__start, __len, &__state); 249 if (__con != __len && __start != 0) 250 { 251 __offset = __start - __lo; 252 __dest[__offset++] = __dfault; 253 } 254 else 255 break; 256 } 257#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 258 __uselocale(__old); 259#endif 260 return __hi; 261 } 262#endif // _GLIBCPP_USE_WCHAR_T 263} 264