Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

OffsetIndexVector.hpp

Go to the documentation of this file.
00001 #ifndef OffsetIndexVector_HPP
00002 #define OffsetIndexVector_HPP
00003 
00004 #include "common.hpp"
00005 #include "common/Edge.hpp"
00006 #include <vector>
00007 #include <iterator>     //for test
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

Generated on Sun Sep 17 17:50:39 2006 for FIM environment by  doxygen 1.4.4