|
Packit |
b27855 |
/* Inline Functions for positions.{h,cc}.
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
|
|
Packit |
b27855 |
Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
|
|
Packit |
b27855 |
and Bruno Haible <bruno@clisp.org>.
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
This file is part of GNU GPERF.
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
This program is free software: you can redistribute it and/or modify
|
|
Packit |
b27855 |
it under the terms of the GNU General Public License as published by
|
|
Packit |
b27855 |
the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
b27855 |
(at your option) any later version.
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
This program is distributed in the hope that it will be useful,
|
|
Packit |
b27855 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
b27855 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
b27855 |
GNU General Public License for more details.
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
You should have received a copy of the GNU General Public License
|
|
Packit |
b27855 |
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
// This needs:
|
|
Packit |
b27855 |
//#include <string.h>
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* ---------------------------- Class Positions ---------------------------- */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Constructors. */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
Positions::Positions ()
|
|
Packit |
b27855 |
: _useall (false),
|
|
Packit |
b27855 |
_size (0)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
Positions::Positions (int pos1)
|
|
Packit |
b27855 |
: _useall (false),
|
|
Packit |
b27855 |
_size (1)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
_positions[0] = pos1;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
Positions::Positions (int pos1, int pos2)
|
|
Packit |
b27855 |
: _useall (false),
|
|
Packit |
b27855 |
_size (2)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
_positions[0] = pos1;
|
|
Packit |
b27855 |
_positions[1] = pos2;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Copy constructor. */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
Positions::Positions (const Positions& src)
|
|
Packit |
b27855 |
: _useall (src._useall),
|
|
Packit |
b27855 |
_size (src._size)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
memcpy (_positions, src._positions, _size * sizeof (_positions[0]));
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Assignment operator. */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE Positions&
|
|
Packit |
b27855 |
Positions::operator= (const Positions& src)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
_useall = src._useall;
|
|
Packit |
b27855 |
_size = src._size;
|
|
Packit |
b27855 |
memcpy (_positions, src._positions, _size * sizeof (_positions[0]));
|
|
Packit |
b27855 |
return *this;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Accessors. */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE bool
|
|
Packit |
b27855 |
Positions::is_useall () const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return _useall;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE int
|
|
Packit |
b27855 |
Positions::operator[] (unsigned int index) const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return _positions[index];
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE unsigned int
|
|
Packit |
b27855 |
Positions::get_size () const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return _size;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Write access. */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE void
|
|
Packit |
b27855 |
Positions::set_useall (bool useall)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
_useall = useall;
|
|
Packit |
b27855 |
if (useall)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
/* The positions are 0, 1, ..., MAX_KEY_POS-1, in descending order. */
|
|
Packit |
b27855 |
_size = MAX_KEY_POS;
|
|
Packit |
b27855 |
int *ptr = _positions;
|
|
Packit |
b27855 |
for (int i = MAX_KEY_POS - 1; i >= 0; i--)
|
|
Packit |
b27855 |
*ptr++ = i;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE int *
|
|
Packit |
b27855 |
Positions::pointer ()
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return _positions;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
INLINE void
|
|
Packit |
b27855 |
Positions::set_size (unsigned int size)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
_size = size;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Sorts the array in reverse order.
|
|
Packit |
b27855 |
Returns true if there are no duplicates, false otherwise. */
|
|
Packit |
b27855 |
INLINE bool
|
|
Packit |
b27855 |
Positions::sort ()
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
if (_useall)
|
|
Packit |
b27855 |
return true;
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Bubble sort. */
|
|
Packit |
b27855 |
bool duplicate_free = true;
|
|
Packit |
b27855 |
int *base = _positions;
|
|
Packit |
b27855 |
unsigned int len = _size;
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
for (unsigned int i = 1; i < len; i++)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
unsigned int j;
|
|
Packit |
b27855 |
int tmp;
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
for (j = i, tmp = base[j]; j > 0 && tmp >= base[j - 1]; j--)
|
|
Packit |
b27855 |
if ((base[j] = base[j - 1]) == tmp) /* oh no, a duplicate!!! */
|
|
Packit |
b27855 |
duplicate_free = false;
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
base[j] = tmp;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
return duplicate_free;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Creates an iterator, returning the positions in descending order. */
|
|
Packit |
b27855 |
INLINE PositionIterator
|
|
Packit |
b27855 |
Positions::iterator () const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return PositionIterator (*this);
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Creates an iterator, returning the positions in descending order,
|
|
Packit |
b27855 |
that apply to strings of length <= maxlen. */
|
|
Packit |
b27855 |
INLINE PositionIterator
|
|
Packit |
b27855 |
Positions::iterator (int maxlen) const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return PositionIterator (*this, maxlen);
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Creates an iterator, returning the positions in ascending order. */
|
|
Packit |
b27855 |
INLINE PositionReverseIterator
|
|
Packit |
b27855 |
Positions::reviterator () const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return PositionReverseIterator (*this);
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Creates an iterator, returning the positions in ascending order,
|
|
Packit |
b27855 |
that apply to strings of length <= maxlen. */
|
|
Packit |
b27855 |
INLINE PositionReverseIterator
|
|
Packit |
b27855 |
Positions::reviterator (int maxlen) const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return PositionReverseIterator (*this, maxlen);
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* ------------------------- Class PositionIterator ------------------------ */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Initializes an iterator through POSITIONS. */
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
PositionIterator::PositionIterator (Positions const& positions)
|
|
Packit |
b27855 |
: _set (positions),
|
|
Packit |
b27855 |
_index (0)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Initializes an iterator through POSITIONS, ignoring positions >= maxlen. */
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
PositionIterator::PositionIterator (Positions const& positions, int maxlen)
|
|
Packit |
b27855 |
: _set (positions)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
if (positions._useall)
|
|
Packit |
b27855 |
_index = (maxlen <= Positions::MAX_KEY_POS ? Positions::MAX_KEY_POS - maxlen : 0);
|
|
Packit |
b27855 |
else
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
unsigned int index;
|
|
Packit |
b27855 |
for (index = 0;
|
|
Packit |
b27855 |
index < positions._size && positions._positions[index] >= maxlen;
|
|
Packit |
b27855 |
index++)
|
|
Packit |
b27855 |
;
|
|
Packit |
b27855 |
_index = index;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Retrieves the next position, or EOS past the end. */
|
|
Packit |
b27855 |
INLINE int
|
|
Packit |
b27855 |
PositionIterator::next ()
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return (_index < _set._size ? _set._positions[_index++] : EOS);
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Returns the number of remaining positions, i.e. how often next() will
|
|
Packit |
b27855 |
return a value != EOS. */
|
|
Packit |
b27855 |
INLINE unsigned int
|
|
Packit |
b27855 |
PositionIterator::remaining () const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return _set._size - _index;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Copy constructor. */
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
PositionIterator::PositionIterator (const PositionIterator& src)
|
|
Packit |
b27855 |
: _set (src._set),
|
|
Packit |
b27855 |
_index (src._index)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* --------------------- Class PositionReverseIterator --------------------- */
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Initializes an iterator through POSITIONS. */
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
PositionReverseIterator::PositionReverseIterator (Positions const& positions)
|
|
Packit |
b27855 |
: _set (positions),
|
|
Packit |
b27855 |
_index (_set._size),
|
|
Packit |
b27855 |
_minindex (0)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Initializes an iterator through POSITIONS, ignoring positions >= maxlen. */
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
PositionReverseIterator::PositionReverseIterator (Positions const& positions, int maxlen)
|
|
Packit |
b27855 |
: _set (positions),
|
|
Packit |
b27855 |
_index (_set._size)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
if (positions._useall)
|
|
Packit |
b27855 |
_minindex = (maxlen <= Positions::MAX_KEY_POS ? Positions::MAX_KEY_POS - maxlen : 0);
|
|
Packit |
b27855 |
else
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
unsigned int index;
|
|
Packit |
b27855 |
for (index = 0;
|
|
Packit |
b27855 |
index < positions._size && positions._positions[index] >= maxlen;
|
|
Packit |
b27855 |
index++)
|
|
Packit |
b27855 |
;
|
|
Packit |
b27855 |
_minindex = index;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Retrieves the next position, or EOS past the end. */
|
|
Packit |
b27855 |
INLINE int
|
|
Packit |
b27855 |
PositionReverseIterator::next ()
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return (_index > _minindex ? _set._positions[--_index] : EOS);
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Returns the number of remaining positions, i.e. how often next() will
|
|
Packit |
b27855 |
return a value != EOS. */
|
|
Packit |
b27855 |
INLINE unsigned int
|
|
Packit |
b27855 |
PositionReverseIterator::remaining () const
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
return _index - _minindex;
|
|
Packit |
b27855 |
}
|
|
Packit |
b27855 |
|
|
Packit |
b27855 |
/* Copy constructor. */
|
|
Packit |
b27855 |
INLINE
|
|
Packit |
b27855 |
PositionReverseIterator::PositionReverseIterator (const PositionReverseIterator& src)
|
|
Packit |
b27855 |
: _set (src._set),
|
|
Packit |
b27855 |
_index (src._index),
|
|
Packit |
b27855 |
_minindex (src._minindex)
|
|
Packit |
b27855 |
{
|
|
Packit |
b27855 |
}
|