1/* Inline Functions for positions.{h,cc}. 2 3 Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc. 4 Written by Douglas C. Schmidt <schmidt@ics.uci.edu> 5 and Bruno Haible <bruno@clisp.org>. 6 7 This file is part of GNU GPERF. 8 9 GNU GPERF is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2, or (at your option) 12 any later version. 13 14 GNU GPERF is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; see the file COPYING. 21 If not, write to the Free Software Foundation, Inc., 22 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 23 24// This needs: 25//#include <string.h> 26 27/* ---------------------------- Class Positions ---------------------------- */ 28 29/* Constructors. */ 30 31INLINE 32Positions::Positions () 33 : _useall (false), 34 _size (0) 35{ 36} 37 38INLINE 39Positions::Positions (int pos1) 40 : _useall (false), 41 _size (1) 42{ 43 _positions[0] = pos1; 44} 45 46INLINE 47Positions::Positions (int pos1, int pos2) 48 : _useall (false), 49 _size (2) 50{ 51 _positions[0] = pos1; 52 _positions[1] = pos2; 53} 54 55/* Copy constructor. */ 56 57INLINE 58Positions::Positions (const Positions& src) 59 : _useall (src._useall), 60 _size (src._size) 61{ 62 memcpy (_positions, src._positions, _size * sizeof (_positions[0])); 63} 64 65/* Assignment operator. */ 66 67INLINE Positions& 68Positions::operator= (const Positions& src) 69{ 70 _useall = src._useall; 71 _size = src._size; 72 memcpy (_positions, src._positions, _size * sizeof (_positions[0])); 73 return *this; 74} 75 76/* Accessors. */ 77 78INLINE bool 79Positions::is_useall () const 80{ 81 return _useall; 82} 83 84INLINE int 85Positions::operator[] (unsigned int index) const 86{ 87 return _positions[index]; 88} 89 90INLINE unsigned int 91Positions::get_size () const 92{ 93 return _size; 94} 95 96/* Write access. */ 97 98INLINE void 99Positions::set_useall (bool useall) 100{ 101 _useall = useall; 102 if (useall) 103 { 104 /* The positions are 0, 1, ..., MAX_KEY_POS-1, in descending order. */ 105 _size = MAX_KEY_POS; 106 int *ptr = _positions; 107 for (int i = MAX_KEY_POS - 1; i >= 0; i--) 108 *ptr++ = i; 109 } 110} 111 112INLINE int * 113Positions::pointer () 114{ 115 return _positions; 116} 117 118INLINE void 119Positions::set_size (unsigned int size) 120{ 121 _size = size; 122} 123 124/* Sorts the array in reverse order. 125 Returns true if there are no duplicates, false otherwise. */ 126INLINE bool 127Positions::sort () 128{ 129 if (_useall) 130 return true; 131 132 /* Bubble sort. */ 133 bool duplicate_free = true; 134 int *base = _positions; 135 unsigned int len = _size; 136 137 for (unsigned int i = 1; i < len; i++) 138 { 139 unsigned int j; 140 int tmp; 141 142 for (j = i, tmp = base[j]; j > 0 && tmp >= base[j - 1]; j--) 143 if ((base[j] = base[j - 1]) == tmp) /* oh no, a duplicate!!! */ 144 duplicate_free = false; 145 146 base[j] = tmp; 147 } 148 149 return duplicate_free; 150} 151 152/* Creates an iterator, returning the positions in descending order. */ 153INLINE PositionIterator 154Positions::iterator () const 155{ 156 return PositionIterator (*this); 157} 158 159/* Creates an iterator, returning the positions in descending order, 160 that apply to strings of length <= maxlen. */ 161INLINE PositionIterator 162Positions::iterator (int maxlen) const 163{ 164 return PositionIterator (*this, maxlen); 165} 166 167/* Creates an iterator, returning the positions in ascending order. */ 168INLINE PositionReverseIterator 169Positions::reviterator () const 170{ 171 return PositionReverseIterator (*this); 172} 173 174/* Creates an iterator, returning the positions in ascending order, 175 that apply to strings of length <= maxlen. */ 176INLINE PositionReverseIterator 177Positions::reviterator (int maxlen) const 178{ 179 return PositionReverseIterator (*this, maxlen); 180} 181 182/* ------------------------- Class PositionIterator ------------------------ */ 183 184/* Initializes an iterator through POSITIONS. */ 185INLINE 186PositionIterator::PositionIterator (Positions const& positions) 187 : _set (positions), 188 _index (0) 189{ 190} 191 192/* Initializes an iterator through POSITIONS, ignoring positions >= maxlen. */ 193INLINE 194PositionIterator::PositionIterator (Positions const& positions, int maxlen) 195 : _set (positions) 196{ 197 if (positions._useall) 198 _index = (maxlen <= Positions::MAX_KEY_POS ? Positions::MAX_KEY_POS - maxlen : 0); 199 else 200 { 201 unsigned int index; 202 for (index = 0; 203 index < positions._size && positions._positions[index] >= maxlen; 204 index++) 205 ; 206 _index = index; 207 } 208} 209 210/* Retrieves the next position, or EOS past the end. */ 211INLINE int 212PositionIterator::next () 213{ 214 return (_index < _set._size ? _set._positions[_index++] : EOS); 215} 216 217/* Returns the number of remaining positions, i.e. how often next() will 218 return a value != EOS. */ 219INLINE unsigned int 220PositionIterator::remaining () const 221{ 222 return _set._size - _index; 223} 224 225/* Copy constructor. */ 226INLINE 227PositionIterator::PositionIterator (const PositionIterator& src) 228 : _set (src._set), 229 _index (src._index) 230{ 231} 232 233/* --------------------- Class PositionReverseIterator --------------------- */ 234 235/* Initializes an iterator through POSITIONS. */ 236INLINE 237PositionReverseIterator::PositionReverseIterator (Positions const& positions) 238 : _set (positions), 239 _index (_set._size), 240 _minindex (0) 241{ 242} 243 244/* Initializes an iterator through POSITIONS, ignoring positions >= maxlen. */ 245INLINE 246PositionReverseIterator::PositionReverseIterator (Positions const& positions, int maxlen) 247 : _set (positions), 248 _index (_set._size) 249{ 250 if (positions._useall) 251 _minindex = (maxlen <= Positions::MAX_KEY_POS ? Positions::MAX_KEY_POS - maxlen : 0); 252 else 253 { 254 unsigned int index; 255 for (index = 0; 256 index < positions._size && positions._positions[index] >= maxlen; 257 index++) 258 ; 259 _minindex = index; 260 } 261} 262 263/* Retrieves the next position, or EOS past the end. */ 264INLINE int 265PositionReverseIterator::next () 266{ 267 return (_index > _minindex ? _set._positions[--_index] : EOS); 268} 269 270/* Returns the number of remaining positions, i.e. how often next() will 271 return a value != EOS. */ 272INLINE unsigned int 273PositionReverseIterator::remaining () const 274{ 275 return _index - _minindex; 276} 277 278/* Copy constructor. */ 279INLINE 280PositionReverseIterator::PositionReverseIterator (const PositionReverseIterator& src) 281 : _set (src._set), 282 _index (src._index), 283 _minindex (src._minindex) 284{ 285} 286