00001 #ifndef OffsetIndexVector_HPP
00002 #define OffsetIndexVector_HPP
00003
00004 #include "common.hpp"
00005 #include "common/Edge.hpp"
00006 #include <vector>
00007 #include <iterator>
00008
00009
00010 namespace Bodon
00011 {
00017 template < class VECTOR = std::vector<void*> >
00018 class OffsetIndexVector : private VECTOR
00019 {
00020 private:
00021 item_t offset;
00022
00023 public:
00024
00025 class iterator
00026 {
00027 friend class OffsetIndexVector;
00028 private:
00029 OffsetIndexVector* oiv;
00030 typename VECTOR::iterator it;
00031 public:
00032 iterator(){}
00033
00034 iterator( OffsetIndexVector* oiv,
00035 const typename VECTOR::iterator& it) :
00036 oiv(oiv), it(it){}
00037
00038 Edge operator*() const
00039 {
00040 return Edge( oiv->offset +
00041 it - static_cast<VECTOR*>(oiv)->begin(),
00042 *it );
00043 }
00044 iterator& operator++()
00045 {
00046 do ++it;
00047 while( it != static_cast<VECTOR*>(oiv)->end() &&
00048 *it == NULL );
00049 return *this;
00050 }
00051
00052 iterator& operator=(const iterator& an_it)
00053 {
00054 if( this != &an_it )
00055 {
00056 oiv = an_it.oiv;
00057 it = an_it.it;
00058 }
00059 return *this;
00060 }
00061 bool operator==(const iterator& an_it) const
00062 {
00063 return it == an_it.it;
00064 }
00065
00066 bool operator!=(const iterator& an_it) const
00067 {
00068 return it != an_it.it;
00069 }
00070 };
00071
00072 class const_iterator
00073 {
00074 friend class OffsetIndexVector;
00075 private:
00076 const OffsetIndexVector* oiv;
00077 typename VECTOR::const_iterator it;
00078 public:
00079 const_iterator(){}
00080
00081 const_iterator( const OffsetIndexVector* oiv,
00082 const typename VECTOR::const_iterator& it) :
00083 oiv(oiv), it(it){}
00084
00085 Edge operator*() const
00086 {
00087 return Edge( oiv->offset +
00088 it - static_cast<const VECTOR*>(oiv)->begin(),
00089 *it );
00090 }
00091 const_iterator& operator++()
00092 {
00093 do ++it;
00094 while( it != static_cast<const VECTOR*>(oiv)->end() &&
00095 *it == NULL );
00096 return *this;
00097 }
00098
00099 const_iterator& operator=(const iterator& an_it)
00100 {
00101 if( this != &an_it )
00102 {
00103 oiv = an_it.oiv;
00104 it = an_it.it;
00105 }
00106 return *this;
00107 }
00108 bool operator==(const iterator& an_it) const
00109 {
00110 return it == an_it.it;
00111 }
00112
00113 bool operator!=(const const_iterator& an_it) const
00114 {
00115 return it != an_it.it;
00116 }
00117 };
00118 public:
00119 OffsetIndexVector():VECTOR(){}
00120 iterator begin()
00121 {
00122 return iterator(this, VECTOR::begin());
00123 }
00124
00125 const_iterator begin() const
00126 {
00127 return const_iterator(this, VECTOR::begin());
00128 }
00129
00130 iterator end()
00131 {
00132 return iterator(this, VECTOR::end());
00133 }
00134 const_iterator end() const
00135 {
00136 return const_iterator(this, VECTOR::end());
00137 }
00138 void clear()
00139 {
00140 VECTOR::erase( VECTOR::begin(),
00141 VECTOR::end() );
00142 }
00143 bool empty() const
00144 {
00145 return VECTOR::begin() == VECTOR::end();
00146 }
00147 void*& getSubtrie(item_t label)
00148 {
00149 return VECTOR::operator[](label - offset);
00150 }
00151 void quickErase(item_t pos);
00152 iterator erase(iterator pos);
00153
00154
00155 void* find(const item_t label) const
00156 {
00157 if( label >= offset + VECTOR::size() || label < offset)
00158 return NULL;
00159 else
00160 return VECTOR::operator[](label - offset);
00161 }
00162
00163 void*& findOrCreate(item_t label);
00164 bool lookup(item_t label, void*& subtrie)
00165 {
00166 if( label >= offset + VECTOR::size() )
00167 return false;
00168 else
00169 {
00170 if( label < offset)
00171 subtrie = NULL;
00172 else subtrie = VECTOR::operator[](label - offset);
00173 return true;
00174 }
00175 }
00176 void lookupNocheck(item_t label, void*& subtrie) const
00177 {
00178 if( label < offset || label >= offset + VECTOR::size())
00179 subtrie = NULL;
00180 else subtrie = VECTOR::operator[](label - offset);
00181 }
00182 void lookupNoUppercheck(item_t label, void*& subtrie) const
00183 {
00184 if( label < offset )
00185 subtrie = NULL;
00186 else subtrie = VECTOR::operator[](label - offset);
00187 }
00188
00189 void insert(const std::vector<Edge>& new_edges);
00190
00191 item_t largestEdgelabel() const
00192 {
00193 return VECTOR::size() + offset - 1;
00194 }
00195 item_t smallestEdgelabel() const
00196 {
00197 return offset;
00198 }
00199 };
00200 template <class VECTOR>
00201 inline void OffsetIndexVector<VECTOR>::
00202 insert(const std::vector<Edge>& new_edges)
00203 {
00204 if(!new_edges.empty())
00205 {
00206 offset = new_edges.front().first;
00207 VECTOR::reserve(new_edges.back().first - offset +1 );
00208 VECTOR::resize(new_edges.back().first - offset +1, NULL);
00209 for(std::vector<Edge>::const_iterator it = new_edges.begin();
00210 it != new_edges.end(); ++it)
00211 VECTOR::operator[]((*it).first - offset) = (*it).second;
00212 }
00213 }
00214 template <class VECTOR>
00215 inline void OffsetIndexVector<VECTOR>::
00216 quickErase(item_t pos)
00217 {
00218 pos -= offset;
00219 if( pos == 0 )
00220 {
00221 do
00222 {
00223 VECTOR::erase(VECTOR::begin());
00224 ++offset;
00225 }
00226 while(!VECTOR::empty() && VECTOR::front() == NULL);
00227 }
00228 else if( pos == VECTOR::size() - 1 )
00229 {
00230 do
00231 {
00232 VECTOR::pop_back();
00233 }
00234 while( VECTOR::back() == NULL );
00235 }
00236 else
00237 VECTOR::operator[](pos) = NULL;
00238 }
00239
00240 template <class VECTOR>
00241 inline typename OffsetIndexVector<VECTOR>::iterator
00242 OffsetIndexVector<VECTOR>::erase(
00243 typename OffsetIndexVector<VECTOR>::iterator pos)
00244 {
00245 if( pos.it == VECTOR::begin() )
00246 {
00247 do
00248 {
00249 VECTOR::erase(VECTOR::begin());
00250 ++offset;
00251 }
00252 while(!VECTOR::empty() && VECTOR::front() == NULL);
00253 return begin();
00254 }
00255 else if(pos.it == VECTOR::end()-1)
00256 {
00257 do
00258 {
00259 VECTOR::pop_back();
00260 }
00261 while( VECTOR::back() == NULL );
00262 return end();
00263 }
00264 else
00265 {
00266 *(pos.it) = NULL;
00267 return ++pos;
00268 }
00269 }
00270 template <class VECTOR>
00271 inline void*& OffsetIndexVector<VECTOR>::findOrCreate(item_t label)
00272 {
00273 if(VECTOR::empty())
00274 {
00275 offset = label;
00276 VECTOR::push_back(NULL);
00277 }
00278 else if( label >= offset + VECTOR::size())
00279 {
00280 VECTOR::resize(label - offset + 1, NULL);
00281 }
00282 else if(label < offset)
00283 {
00284 VECTOR::insert(VECTOR::begin(), offset - label, NULL);
00285 offset = label;
00286 }
00287 return VECTOR::operator[](label - offset);
00288 }
00289
00290 }
00291
00292 #endif