00001 #ifndef IndexVector_HPP
00002 #define IndexVector_HPP
00003
00004 #include "common.hpp"
00005 #include "common/Edge.hpp"
00006 #include <vector>
00007 #include <iterator>
00008
00009
00010 namespace Bodon
00011 {
00012 class IndexVector : private std::vector<void*>
00013 {
00014 public:
00015
00016 class iterator
00017 {
00018 friend class IndexVector;
00019 private:
00020 IndexVector* oiv;
00021 std::vector<void*>::iterator it;
00022 public:
00023 iterator(){}
00024
00025 iterator( IndexVector* oiv,
00026 const std::vector<void*>::iterator& it) :
00027 oiv(oiv), it(it){}
00028
00029 Edge operator*() const
00030 {
00031 return Edge( it - static_cast< std::vector<void*>* >(oiv)->begin(),
00032 *it );
00033 }
00034 iterator& operator++()
00035 {
00036 do ++it;
00037 while( it != static_cast< std::vector<void*>* >(oiv)->end() &&
00038 *it == NULL );
00039 return *this;
00040 }
00041
00042 iterator& operator=(const iterator& an_it)
00043 {
00044 if( this != &an_it )
00045 {
00046 oiv = an_it.oiv;
00047 it = an_it.it;
00048 }
00049 return *this;
00050 }
00051 bool operator==(const iterator& an_it) const
00052 {
00053 return it == an_it.it;
00054 }
00055
00056 bool operator!=(const iterator& an_it) const
00057 {
00058 return it != an_it.it;
00059 }
00060 };
00061
00062 public:
00063 IndexVector() : std::vector<void*>(){}
00064 iterator begin()
00065 {
00066 std::vector<void*>::iterator it(std::vector<void*>::begin());
00067 while(it != std::vector<void*>::end() && *it == NULL)
00068 ++it;
00069 return iterator(this, it);
00070 }
00071
00072 iterator end()
00073 {
00074 return iterator(this, std::vector<void*>::end());
00075 }
00076 void clear()
00077 {
00078 std::vector<void*>::erase( std::vector<void*>::begin(),
00079 std::vector<void*>::end() );
00080 }
00081 bool empty() const
00082 {
00083 return std::vector<void*>::begin() == std::vector<void*>::end();
00084 }
00085 void*& getSubtrie(item_t label)
00086 {
00087 return operator[](label);
00088 }
00089 void quickErase(item_t pos);
00090 iterator erase(iterator pos);
00091
00092 void* find(item_t label) const
00093 {
00094 if( label >= size() )
00095 return NULL;
00096 else
00097 return operator[](label);
00098 }
00099
00100 void*& findOrCreate(item_t label)
00101 {
00102 if( label >= size() )
00103 resize(label+1, NULL);
00104 return operator[](label);
00105 }
00106 bool lookup(item_t label, void*& subtrie) const
00107 {
00108 if( label >= size() )
00109 return false;
00110 else
00111 {
00112 subtrie = operator[](label);
00113 return true;
00114 }
00115 }
00116 void insert(const std::vector<Edge>& new_edges);
00117
00118 static bool isLookupPreferred()
00119 {
00120 return true;
00121 }
00122 };
00123 inline void IndexVector::insert(const std::vector<Edge>& new_edges)
00124 {
00125 if(!new_edges.empty())
00126 {
00127 reserve(new_edges.back().first + 1 );
00128 resize(new_edges.back().first + 1, NULL);
00129 for( std::vector<Edge>::const_iterator it = new_edges.begin();
00130 it != new_edges.end(); ++it)
00131 operator[]((*it).first) = (*it).second;
00132 }
00133 }
00134
00135 inline void IndexVector::quickErase(item_t pos)
00136 {
00137 if( pos == size() - 1 )
00138 {
00139 do
00140 {
00141 pop_back();
00142 }
00143 while( !empty() && back() == NULL );
00144 }
00145 else
00146 operator[](pos) = NULL;
00147 }
00148
00149 inline IndexVector::iterator IndexVector::
00150 erase(IndexVector::iterator pos)
00151 {
00152 if(pos.it == --std::vector<void*>::end())
00153 {
00154 do
00155 {
00156 pop_back();
00157 }
00158 while( !empty() && back() == NULL );
00159 return end();
00160 }
00161 else
00162 {
00163 *(pos.it) = NULL;
00164 return ++pos;
00165 }
00166 }
00167 }
00168
00169 #endif