www.pudn.com > reacTIVision-1.3.rar > listhash.h
/***************************************************************************
listhash.h - description
-------------------
begin : Mon Dec 8 2003
copyright : (C) 2003 by Enrico Costanza
email : e.costanza@ieee.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330 *
* Boston, MA 02111-1307 USA *
* *
***************************************************************************/
/* Changes
Code optimization by Jorge M Santiago
*/
#ifndef EC_LISTHASH
#define EC_LISTHASH
#include "list.h"
// Warning: this is defined as a template, but in practice it will
// work only for integers! (which is all I need now)
// To make it work in general it is needed to define a method that
// "hashes" T to int, but this requires partial specialization
// which is problematic in MS Windows (...)
template
class ListHash : public List
{
protected:
using List::_first;
using List::_last;
using List::_current;
using List::_size;
ListItem **_toc;
int _capacity;
ListHash() {}
// moveTo moves the current pointer to the first element in the List with value equal to target
bool moveTo( const T target ){
_current = _toc[target];
return (_current != NULL);
}
// seek returns the pointer to the first element in the List with value equal to target
ListItem *seek( const T target ){
return _toc[target];
}
public:
// constuctors
ListHash( int initialSize ) : List(), _capacity(initialSize) {
//_toc = new (ListItem *)[_capacity];
_toc = new ListItem*[_capacity];
memset( _toc, 0, _capacity*sizeof(ListItem *) );
}
~ListHash(){
//std::cerr << "~ListHash called" << std::endl;
//if( _first != NULL ){ delete _first; }
_current = _first;
while( _current != NULL ){
ListItem *tmp = _current;
_current = _current->getNext();
delete tmp;
}
_current=_last=_first=NULL; _size=0;
delete [] _toc;
}
inline void empty() {
//memset( _toc, 0, _capacity*sizeof(ListItem *) );
for(this->reset();!(this->nullTest());this->fwd()){ _toc[this->getData()] = NULL; }
//if(_first!=NULL){ delete _first; }
_current = _first;
while( _current != NULL ){
ListItem *tmp = _current;
_current = _current->getNext();
delete tmp;
}
_current = _first = _last = NULL;
_size=0;
}
void expand(){
//ListItem **tmp = new (ListItem *)[_capacity+_capacity];
ListItem **tmp = new ListItem*[_capacity+_capacity];
memcpy( tmp, _toc, _capacity*sizeof(ListItem *) );
memset( tmp + _capacity, 0, _capacity*sizeof(ListItem *) );
delete [] _toc;
_toc = tmp;
_capacity*=2;
}
// i/o methods
inline void append( const T &in_data ){
if( _toc[in_data] != NULL ){
// data already in list
// do nothing
return;
}
if( _first == NULL ){
_first = new ListItem(in_data);
// double link:
_first->setPrev(NULL);
_current = _first;
_last = _first;
}else{
_last->setNext( new ListItem( in_data, NULL ) );
// double link:
_last->getNext()->setPrev( _last );
_last = _last->getNext();
}
_toc[in_data] = _last;
_size++;
return;
}
void append( ListHash *src ){
cout << "Appending a ListHash to another" << endl;
if( src->isEmpty() ){
// do nothing
return;
}
if( _first == NULL ){
_first = src->_first;
_current = _first;
_last = src->_last;
memcpy(_toc,src->_toc,_capacity*sizeof(ListItem *));
}
else{
_last->next = src->_first;
// double link:
_last->next->prev = _last;
_last = src->_last;
if(src->_size > _size){
for(ListItem *tmp = _first;tmp!=NULL;tmp=tmp->next){
src->_toc[tmp->data] = tmp;
}
memcpy(_toc,src->_toc,_capacity*sizeof(ListItem *));
}else{
for(ListItem *tmp = src->_first;tmp!=NULL;tmp=tmp->next){
_toc[tmp->data] = tmp;
}
}
}
_size += src->_size;
memset(src->_toc,NULL,src->_size);
src->_size = 0;
src->_first = NULL;
src->_current = NULL;
src->_last = NULL;
return;
}
/*inline*/ void remove( const T &data ){
ListItem *toBeDeleted = _toc[data];
if( toBeDeleted == NULL ){
return;
}
if( toBeDeleted->getPrev() == NULL ){
//if( toBeDeleted != _first ){cout << "There's a mess here!" << endl;}
_first = _first->getNext();
if( _first != NULL ){
_first->setPrev( NULL );
}
if( _last == toBeDeleted ){
_last = _first;
}
toBeDeleted->setNext( NULL );
delete toBeDeleted;
_size--;
_toc[data] = NULL;
return;
}
toBeDeleted->getPrev()->setNext( toBeDeleted->getNext() );
if( toBeDeleted->getNext() != NULL ){
toBeDeleted->getNext()->setPrev( toBeDeleted->getPrev() );
}
if( _last == toBeDeleted ){
_last = toBeDeleted->getPrev();
}
toBeDeleted->setNext( NULL );
delete toBeDeleted;
_toc[data] = NULL;
_size--;
return;
}
inline void replace( const T &data_in, const T &data_out ){
if( _toc[data_out] != NULL && _toc[data_in] == NULL ){
_toc[data_out]->setData( data_in );
_toc[data_in] = _toc[data_out];
_toc[data_out] = NULL;
}
}
inline bool dtcheck( const T &target ){
return (_toc[target] != NULL);
}
ListItem **getToc(){
return _toc;
}
};
#endif