1// Locale support -*- C++ -*- 2 3// Copyright (C) 2000-2015 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 3, 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// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/** @file bits/ctype_inline.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{locale} 28 */ 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 44namespace std _GLIBCXX_VISIBILITY(default) 45{ 46_GLIBCXX_BEGIN_NAMESPACE_VERSION 47 48 bool 49 ctype<char>:: 50 is(mask __m, char __c) const 51 { 52 if (_M_table) 53 return _M_table[static_cast<unsigned char>(__c)] & __m; 54 else 55 { 56 bool __ret = false; 57 const size_t __bitmasksize = 15; 58 size_t __bitcur = 0; // Lowest bitmask in ctype_base == 0 59 for (; __bitcur <= __bitmasksize; ++__bitcur) 60 { 61 const mask __bit = static_cast<mask>(1 << __bitcur); 62 if (__m & __bit) 63 { 64 bool __testis; 65 switch (__bit) 66 { 67 case space: 68 __testis = isspace(__c); 69 break; 70 case print: 71 __testis = isprint(__c); 72 break; 73 case cntrl: 74 __testis = iscntrl(__c); 75 break; 76 case upper: 77 __testis = isupper(__c); 78 break; 79 case lower: 80 __testis = islower(__c); 81 break; 82 case alpha: 83 __testis = isalpha(__c); 84 break; 85 case digit: 86 __testis = isdigit(__c); 87 break; 88 case punct: 89 __testis = ispunct(__c); 90 break; 91 case xdigit: 92 __testis = isxdigit(__c); 93 break; 94 case alnum: 95 __testis = isalnum(__c); 96 break; 97 case graph: 98 __testis = isgraph(__c); 99 break; 100#ifdef _GLIBCXX_USE_C99_CTYPE_TR1 101 case blank: 102 __testis = isblank(__c); 103 break; 104#endif 105 default: 106 __testis = false; 107 break; 108 } 109 __ret |= __testis; 110 } 111 } 112 return __ret; 113 } 114 } 115 116 const char* 117 ctype<char>:: 118 is(const char* __low, const char* __high, mask* __vec) const 119 { 120 if (_M_table) 121 while (__low < __high) 122 *__vec++ = _M_table[static_cast<unsigned char>(*__low++)]; 123 else 124 { 125 // Highest bitmask in ctype_base == 11. 126 const size_t __bitmasksize = 15; 127 for (;__low < __high; ++__vec, ++__low) 128 { 129 mask __m = 0; 130 // Lowest bitmask in ctype_base == 0 131 size_t __i = 0; 132 for (;__i <= __bitmasksize; ++__i) 133 { 134 const mask __bit = static_cast<mask>(1 << __i); 135 if (this->is(__bit, *__low)) 136 __m |= __bit; 137 } 138 *__vec = __m; 139 } 140 } 141 return __high; 142 } 143 144 const char* 145 ctype<char>:: 146 scan_is(mask __m, const char* __low, const char* __high) const 147 { 148 if (_M_table) 149 while (__low < __high 150 && !(_M_table[static_cast<unsigned char>(*__low)] & __m)) 151 ++__low; 152 else 153 while (__low < __high && !this->is(__m, *__low)) 154 ++__low; 155 return __low; 156 } 157 158 const char* 159 ctype<char>:: 160 scan_not(mask __m, const char* __low, const char* __high) const 161 { 162 if (_M_table) 163 while (__low < __high 164 && (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0) 165 ++__low; 166 else 167 while (__low < __high && this->is(__m, *__low) != 0) 168 ++__low; 169 return __low; 170 } 171 172_GLIBCXX_END_NAMESPACE_VERSION 173} // namespace 174