1 // Copyright (c) 1997 James Clark 2 // See the file COPYING for copying permission. 3 4 #ifndef CharMap_DEF_INCLUDED 5 #define CharMap_DEF_INCLUDED 1 6 7 #ifdef SP_NAMESPACE 8 namespace SP_NAMESPACE { 9 #endif 10 11 #ifdef SP_MULTI_BYTE 12 13 template<class T> CharMap()14CharMap<T>::CharMap() 15 { 16 } 17 18 template<class T> CharMap(T dflt)19CharMap<T>::CharMap(T dflt) 20 { 21 for (size_t i = 0; i < (1 << CharMapBits::level1); i++) 22 pages_[i].value = dflt; 23 } 24 25 template<class T> setAll(T val)26void CharMap<T>::setAll(T val) 27 { 28 for (size_t i = 0; i < (1 << CharMapBits::level1); i++) { 29 pages_[i].value = val; 30 delete [] pages_[i].values; 31 pages_[i].values = 0; 32 } 33 } 34 35 template<class T> swap(CharMap<T> & map)36void CharMap<T>::swap(CharMap<T> &map) 37 { 38 for (size_t i = 0; i < (1 << CharMapBits::level1); i++) 39 pages_[i].swap(map.pages_[i]); 40 } 41 42 template<class T> setChar(Char c,T val)43void CharMap<T>::setChar(Char c, T val) 44 { 45 CharMapPage<T> &pg = pages_[c >> (CharMapBits::level2 + CharMapBits::level3)]; 46 if (pg.values) { 47 CharMapColumn<T> &column = pg.values[(c >> CharMapBits::level3) & ((1 << CharMapBits::level2) - 1)]; 48 if (column.values) 49 column.values[c & ((1 << CharMapBits::level3) - 1)] = val; 50 else if (val != column.value) { 51 column.values = new T[1 << CharMapBits::level3]; 52 for (size_t i = 0; i < (1 << CharMapBits::level3); i++) 53 column.values[i] = column.value; 54 column.values[c & ((1 << CharMapBits::level3) - 1)] = val; 55 } 56 } 57 else if (val != pg.value) { 58 pg.values = new CharMapColumn<T>[1 << CharMapBits::level2]; 59 for (size_t i = 0; i < (1 << CharMapBits::level2); i++) 60 pg.values[i].value = pg.value; 61 CharMapColumn<T> &column = pg.values[(c >> CharMapBits::level3) & ((1 << CharMapBits::level2) - 1)]; 62 column.values = new T[1 << CharMapBits::level3]; 63 for (size_t i = 0; i < (1 << CharMapBits::level3); i++) 64 column.values[i] = column.value; 65 column.values[c & ((1 << CharMapBits::level3) - 1)] = val; 66 } 67 } 68 69 template<class T> setRange(Char from,Char to,T val)70void CharMap<T>::setRange(Char from, Char to, T val) 71 { 72 do { 73 if ((from & ((1 << CharMapBits::level3) - 1)) == 0 74 && to - from >= (1 << CharMapBits::level3) - 1) { 75 if ((from & ((1 << (CharMapBits::level2 + CharMapBits::level3)) - 1)) == 0 76 && to - from >= (1 << (CharMapBits::level2 + CharMapBits::level3)) - 1) { 77 // Set a complete page. 78 CharMapPage<T> &pg = pages_[from >> (CharMapBits::level2 + CharMapBits::level3)]; 79 pg.value = val; 80 delete [] pg.values; 81 pg.values = 0; 82 from += (1 << (CharMapBits::level2 + CharMapBits::level3)) - 1; 83 } 84 else { 85 // Set a complete column. 86 CharMapPage<T> &pg = pages_[from >> (CharMapBits::level2 + CharMapBits::level3)]; 87 if (pg.values) { 88 CharMapColumn<T> &column = pg.values[(from >> CharMapBits::level3) & ((1 << CharMapBits::level2) - 1)]; 89 column.value = val; 90 delete [] column.values; 91 column.values = 0; 92 } 93 else if (val != pg.value) { 94 // split the page 95 pg.values = new CharMapColumn<T>[1 << CharMapBits::level2]; 96 for (size_t i = 0; i < (1 << CharMapBits::level2); i++) 97 pg.values[i].value = pg.value; 98 CharMapColumn<T> &column = pg.values[(from >> CharMapBits::level3) & ((1 << CharMapBits::level2) - 1)]; 99 column.value = val; 100 } 101 from += (1 << CharMapBits::level2) - 1; 102 } 103 } 104 else 105 setChar(from, val); 106 } while (from++ != to); 107 } 108 109 template<class T> CharMapPage()110CharMapPage<T>::CharMapPage() 111 : values(0) 112 { 113 } 114 115 template<class T> CharMapPage(const CharMapPage<T> & pg)116CharMapPage<T>::CharMapPage(const CharMapPage<T> &pg) 117 { 118 if (pg.values) { 119 values = new CharMapColumn<T>[1 << CharMapBits::level2]; 120 for (size_t i = 0; i < (1 << CharMapBits::level2); i++) 121 values[i] = pg.values[i]; 122 } 123 else { 124 value = pg.value; 125 values = 0; 126 } 127 } 128 129 template<class T> operator =(const CharMapPage<T> & pg)130void CharMapPage<T>::operator=(const CharMapPage<T> &pg) 131 { 132 if (pg.values) { 133 if (!values) 134 values = new CharMapColumn<T>[1 << CharMapBits::level2]; 135 for (size_t i = 0; i < (1 << CharMapBits::level2); i++) 136 values[i] = pg.values[i]; 137 } 138 else { 139 if (values) { 140 delete [] values; 141 values = 0; 142 } 143 value = pg.value; 144 } 145 } 146 147 template<class T> ~CharMapPage()148CharMapPage<T>::~CharMapPage() 149 { 150 delete [] values; 151 } 152 153 template<class T> swap(CharMapPage<T> & pg)154void CharMapPage<T>::swap(CharMapPage<T> &pg) 155 { 156 { 157 CharMapColumn<T> *tem = values; 158 values = pg.values; 159 pg.values = tem; 160 } 161 { 162 T tem(value); 163 value = pg.value; 164 pg.value = tem; 165 } 166 } 167 168 template<class T> CharMapColumn()169CharMapColumn<T>::CharMapColumn() 170 : values(0) 171 { 172 } 173 174 template<class T> CharMapColumn(const CharMapColumn<T> & col)175CharMapColumn<T>::CharMapColumn(const CharMapColumn<T> &col) 176 { 177 if (col.values) { 178 values = new T[1 << CharMapBits::level3]; 179 for (size_t i = 0; i < (1 << CharMapBits::level3); i++) 180 values[i] = col.values[i]; 181 } 182 else { 183 values = 0; 184 value = col.value; 185 } 186 } 187 188 template<class T> operator =(const CharMapColumn<T> & col)189void CharMapColumn<T>::operator=(const CharMapColumn<T> &col) 190 { 191 if (col.values) { 192 if (!values) 193 values = new T[1 << CharMapBits::level3]; 194 for (size_t i = 0; i < (1 << CharMapBits::level3); i++) 195 values[i] = col.values[i]; 196 } 197 else { 198 if (values) { 199 delete [] values; 200 values = 0; 201 } 202 value = col.value; 203 } 204 } 205 206 template<class T> ~CharMapColumn()207CharMapColumn<T>::~CharMapColumn() 208 { 209 delete [] values; 210 } 211 212 #else /* not SP_MULTI_BYTE */ 213 214 template<class T> 215 CharMap<T>::CharMap() 216 { 217 } 218 219 template<class T> 220 CharMap<T>::CharMap(T dflt) 221 { 222 for (int i = 0; i < 256; i++) 223 values_[i] = dflt; 224 } 225 226 template<class T> 227 void CharMap<T>::setAll(T val) 228 { 229 for (size_t i = 0; i < 256; i++) 230 values_[i] = val; 231 } 232 233 template<class T> 234 void CharMap<T>::setRange(Char from, Char to, T val) 235 { 236 do { 237 values_[from] = val; 238 } while (from++ != to); 239 } 240 241 template<class T> 242 void CharMap<T>::swap(CharMap<T> &map) 243 { 244 for (size_t i = 0; i < 256; i++) { 245 T tem(values_[i]); 246 values_[i] = map.values_[i]; 247 map.values_[i] = tem; 248 } 249 } 250 251 #endif /* not SP_MULTI_BYTE */ 252 253 #ifdef SP_NAMESPACE 254 } 255 #endif 256 257 #endif /* not CharMap_DEF_INCLUDED */ 258