/* * This file is part of the program ltl2dstar (http://www.ltl2dstar.de/). * Copyright (C) 2005-2007 Joachim Klein * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 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 */ #ifndef INDEX_H #define INDEX_H /** @file * Providing an Index, a vector where contained objects know their index, * which allows efficient acces. */ #include "common/Exceptions.hpp" //include "common/Indexable.h" #include #include #include #include #include "common/BitSet.hpp" #include "common/BitSetIterator.hpp" #include #include #include //class Indexable; /** * An Index, a vector where the contained objects (which should define the * interface Indexable) know their index, which allows efficient acces. *

* If an object is removed from the index, the space is not reclaimed * automatically and the Index doesn't change size. Use compact() * to compact the Index. This will invalidate iterators and can change * the indizes of the contained objects. */ template class Index { public: Index(); ~Index(); unsigned int add(Indexable *obj); void remove(unsigned int index); unsigned int size() const; Indexable *get(unsigned int index); unsigned int get_index(const Indexable *obj) const; /** []-operator, get the object at index */ Indexable *operator[](unsigned int index) {return get(index);} /** Helper functor that checks if an object* is not null */ struct is_not_null{ bool operator()(Indexable *x) { return x!=0; }}; /** Type of an iterator over the object pointers in the Index that are not null. */ typedef typename boost::filter_iterator::iterator> ptr_iterator; /** Type of an iterator over the references of all contained objects. */ typedef typename boost::indirect_iterator ref_iterator; /** ptr_iterator that points to the first object pointer */ ptr_iterator begin_ptr() {return ptr_iterator(storage.begin(), storage.end());} /** ptr_iterator that points after the last object pointer */ ptr_iterator end_ptr() {return ptr_iterator(storage.end(), storage.end());} /** ref_iterator that points to the first object */ ref_iterator begin_ref() {return ref_iterator(begin_ptr());} /** ref_iterator that points after the last object */ ref_iterator end_ref() {return ref_iterator(end_ptr());} /** * Helper class for the IndexBitsetIterator */ struct index2indexed { public: typedef unsigned int argument_type; typedef Indexable * result_type; index2indexed(Index *index) : _index(index) {}; Indexable *operator()(unsigned int i) const { return _index->get(i); }; private: Index *_index; }; /** * Iterator that takes a BitSet and iterates over the * objects on the indizes that are set in the bit set. */ typedef typename boost::transform_iterator IndexBitSetIterator; /** IndexBitSetIterator that points to the first object */ IndexBitSetIterator begin(BitSet& bs) { return IndexBitSetIterator(BitSetIterator(bs), index2indexed(this)); } /** IndexBitSetIterator that points after the last object */ IndexBitSetIterator end(BitSet& bs) { return IndexBitSetIterator(BitSetIterator::end(bs), index2indexed(this)); } std::pair > compact(); private: /** The storage */ std::vector storage; }; /** * Constructor. */ template Index::Index() { } /** * Destructor. */ template Index::~Index() { typedef typename std::vector::iterator iterator; for (iterator it=storage.begin(); it!=storage.end(); ++it) { if (*it) { (*it)->idx_clearIndex(this); } } } /** * Add a new object to the index. * @return the new index of the object */ template unsigned int Index::add(Indexable *obj) { if (obj->idx_hasIndex(this)) { THROW_EXCEPTION(IllegalArgumentException, "Object already in index!"); } int new_index=storage.size(); storage.insert(storage.end(), obj); obj->idx_setIndex(this, new_index); return new_index; } /** * Removes the object with index from the Index. The resulting free * space is not reclaimed, a subsequent 'get(index)' will return 0 */ template void Index::remove(unsigned int index) { if (index>=size()) { THROW_EXCEPTION(IndexOutOfBoundsException, ""); } storage[index]->idx_clearIndex(this); storage[index]=0; } /** * Get size of the index (ie the highest used index-1) */ template unsigned int Index::size() const { return storage.size(); } /** * Get the object at index. * @return a pointer to the object, or NULL if the object was removed */ template Indexable *Index::get(unsigned int index) { if (index>=size()) { THROW_EXCEPTION(IndexOutOfBoundsException, ""); } return storage[index]; } /** * Get the index of an object contained in the index */ template unsigned int Index::get_index(const Indexable *obj) const { return obj->idx_getIndex(this); } /** * Compact the Index. */ template std::pair > Index::compact() { // Create mapping with enough room for the re-indexing std::vector mapping(size()); bool moved=false; unsigned int j=0; for (unsigned int i=0;iidx_setIndex(this, j); // move object in storage storage[j]=storage[i]; // clean old storage place storage[i]=0; } ++j; // increment } } // remove unneeded elements at the end storage.resize(j); // return the mapping std::pair > result(moved, mapping); return result; } #endif