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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 = false; 53 const size_t __bitmasksize = 15; 54 size_t __bitcur = 0; // Lowest bitmask in ctype_base == 0 55 for (; __bitcur <= __bitmasksize; ++__bitcur) 56 { 57 const mask __bit = static_cast<mask>(1 << __bitcur); 58 if (__m & __bit) 59 { 60 bool __testis; 61 switch (__bit) 62 { 63 case space: 64 __testis = isspace(__c); 65 break; 66 case print: 67 __testis = isprint(__c); 68 break; 69 case cntrl: 70 __testis = iscntrl(__c); 71 break; 72 case upper: 73 __testis = isupper(__c); 74 break; 75 case lower: 76 __testis = islower(__c); 77 break; 78 case alpha: 79 __testis = isalpha(__c); 80 break; 81 case digit: 82 __testis = isdigit(__c); 83 break; 84 case punct: 85 __testis = ispunct(__c); 86 break; 87 case xdigit: 88 __testis = isxdigit(__c); 89 break; 90 case alnum: 91 __testis = isalnum(__c); 92 break; 93 case graph: 94 __testis = isgraph(__c); 95 break; 96 default: 97 __testis = false; 98 break; 99 } 100 __ret |= __testis; 101 } 102 } 103 return __ret; 104 } 105 } 106 107 const char* 108 ctype<char>:: 109 is(const char* __low, const char* __high, mask* __vec) const 110 { 111 if (_M_table) 112 while (__low < __high) 113 *__vec++ = _M_table[static_cast<unsigned char>(*__low++)]; 114 else 115 { 116 // Highest bitmask in ctype_base == 10. 117 const size_t __bitmasksize = 15; 118 for (;__low < __high; ++__vec, ++__low) 119 { 120 mask __m = 0; 121 // Lowest bitmask in ctype_base == 0 122 size_t __i = 0; 123 for (;__i <= __bitmasksize; ++__i) 124 { 125 const mask __bit = static_cast<mask>(1 << __i); 126 if (this->is(__bit, *__low)) 127 __m |= __bit; 128 } 129 *__vec = __m; 130 } 131 } 132 return __high; 133 } 134 135 const char* 136 ctype<char>:: 137 scan_is(mask __m, const char* __low, const char* __high) const 138 { 139 if (_M_table) 140 while (__low < __high 141 && !(_M_table[static_cast<unsigned char>(*__low)] & __m)) 142 ++__low; 143 else 144 while (__low < __high && !this->is(__m, *__low)) 145 ++__low; 146 return __low; 147 } 148 149 const char* 150 ctype<char>:: 151 scan_not(mask __m, const char* __low, const char* __high) const 152 { 153 if (_M_table) 154 while (__low < __high 155 && (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0) 156 ++__low; 157 else 158 while (__low < __high && this->is(__m, *__low) != 0) 159 ++__low; 160 return __low; 161 } 162