1// Locale support -*- C++ -*- 2 3// Copyright (C) 2000, 2003 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 2, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// You should have received a copy of the GNU General Public License along 17// with this library; see the file COPYING. If not, write to the Free 18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19// USA. 20 21// As a special exception, you may use this file as part of a free software 22// library without restriction. Specifically, if other files instantiate 23// templates or use macros or inline functions from this file, or you compile 24// this file and link it with other files to produce an executable, this 25// file does not by itself cause the resulting executable to be covered by 26// the GNU General Public License. This exception does not however 27// invalidate any other reasons why the executable file might be covered by 28// the GNU General Public License. 29 30// 31// ISO C++ 14882: 22.1 Locales 32// 33 34// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*) 35// functions go in ctype.cc 36 37// The following definitions are portable, but insanely slow. If one 38// cares at all about performance, then specialized ctype 39// functionality should be added for the native os in question: see 40// the config/os/bits/ctype_*.h files. 41 42// Constructing a synthetic "C" table should be seriously considered... 43 44 bool 45 ctype<char>:: 46 is(mask __m, char __c) const 47 { 48 if (_M_table) 49 return _M_table[static_cast<unsigned char>(__c)] & __m; 50 else 51 { 52 bool __ret = true; 53 bool __any_match = false; 54 const size_t __bitmasksize = 10; 55 size_t __bitcur = 0; // Lowest bitmask in ctype_base == 0 56 for (;__ret && __bitcur <= __bitmasksize; ++__bitcur) 57 { 58 mask __bit = static_cast<mask>(1 << __bitcur); 59 if (__m & __bit) 60 { 61 __any_match = true; 62 bool __testis; 63 switch (__bit) 64 { 65 case space: 66 __testis = isspace(__c); 67 break; 68 case print: 69 __testis = isprint(__c); 70 break; 71 case cntrl: 72 __testis = iscntrl(__c); 73 break; 74 case upper: 75 __testis = isupper(__c); 76 break; 77 case lower: 78 __testis = islower(__c); 79 break; 80 case alpha: 81 __testis = isalpha(__c); 82 break; 83 case digit: 84 __testis = isdigit(__c); 85 break; 86 case punct: 87 __testis = ispunct(__c); 88 break; 89 case xdigit: 90 __testis = isxdigit(__c); 91 break; 92 case alnum: 93 __testis = isalnum(__c); 94 break; 95 case graph: 96 __testis = isgraph(__c); 97 break; 98 default: 99 __testis = false; 100 break; 101 } 102 __ret &= __testis; 103 } 104 } 105 return __ret & __any_match; 106 } 107 } 108 109 const char* 110 ctype<char>:: 111 is(const char* __low, const char* __high, mask* __vec) const 112 { 113 if (_M_table) 114 while (__low < __high) 115 *__vec++ = _M_table[static_cast<unsigned char>(*__low++)]; 116 else 117 { 118 // Highest bitmask in ctype_base == 10. 119 const size_t __bitmasksize = 10; 120 for (;__low < __high; ++__vec, ++__low) 121 { 122 mask __m = 0; 123 // Lowest bitmask in ctype_base == 0 124 size_t __i = 0; 125 for (;__i <= __bitmasksize; ++__i) 126 { 127 mask __bit = static_cast<mask>(1 << __i); 128 if (this->is(__bit, *__low)) 129 __m |= __bit; 130 } 131 *__vec = __m; 132 } 133 } 134 return __high; 135 } 136 137 const char* 138 ctype<char>:: 139 scan_is(mask __m, const char* __low, const char* __high) const 140 { 141 if (_M_table) 142 while (__low < __high 143 && !(_M_table[static_cast<unsigned char>(*__low)] & __m)) 144 ++__low; 145 else 146 while (__low < __high && !this->is(__m, *__low)) 147 ++__low; 148 return __low; 149 } 150 151 const char* 152 ctype<char>:: 153 scan_not(mask __m, const char* __low, const char* __high) const 154 { 155 if (_M_table) 156 while (__low < __high 157 && (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0) 158 ++__low; 159 else 160 while (__low < __high && this->is(__m, *__low) != 0) 161 ++__low; 162 return __low; 163 } 164