hashlist.h

Go to the documentation of this file.
00001 /* Hash list.
00002  *
00003  * Containers collection (c) 2005 PegSoft
00004  * Contact us at pegsoft@pegsoft.net
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program (see the file COPYING); if not, write to the
00018  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00024 #ifndef CONTAINERS_HASHLIST_H
00025 #define CONTAINERS_HASHLIST_H
00026 
00027 /*************************************************************************/
00028 
00029 #include <iterator>
00030 #include <list>
00031 
00032 /*************************************************************************/
00033 
00035 
00036 namespace containers
00037 {
00038 
00039 /*************************************************************************/
00040 
00042 
00053 template <class T, class KeyT>
00054 class Hash
00055 {
00056     public:
00058         virtual ~Hash() { }
00059 
00061 
00068         virtual int compare(KeyT const &key, T const &value) const = 0;
00069         
00071 
00078         virtual uint32_t hash(KeyT const &key, uint32_t max) const = 0;
00079         
00081 
00087         virtual bool match(KeyT const &key, T const &value) const = 0;
00088 };
00089 
00090 /*************************************************************************/
00091 
00093 
00104 template <class T, class KeyT, uint32_t SIZE>
00105 class HashList
00106 {
00107     private:
00108         typedef std::list<T> list_type;
00109     public:
00110     
00111         /* Typedefs */
00112         
00114         typedef T value_type;
00116         typedef T & reference;
00118         typedef T const & const_reference;
00120         typedef T * pointer;
00122         typedef T const * const_pointer;
00124         typedef typename list_type::size_type size_type;
00126         typedef typename list_type::difference_type difference_type;
00127         
00129         typedef KeyT key_type;
00131         typedef Hash<T, KeyT> hash_type;
00132     
00133         /* Classes */
00134         
00135         class ConstIterator;
00136         
00138         class Iterator;
00139         friend class Iterator;
00140         class Iterator : public 
00141                 std::iterator<std::bidirectional_iterator_tag, T,
00142                     typename HashList<T, KeyT, SIZE>::difference_type,
00143                     T *, T &>
00144         {
00145             private:
00147                 typedef HashList<T, KeyT, SIZE> container_type;
00149                 typedef Iterator iterator_type;
00151                 typedef typename container_type::list_type::iterator literator_type;
00152             public:
00153                 friend class ConstIterator;
00154                 friend class HashList<T, KeyT, SIZE>;
00155             
00156                 /* Typedefs */
00158                 typedef std::bidirectional_iterator_tag iterator_category;
00160                 typedef T value_type;
00162                 typedef typename container_type::difference_type difference_type;
00164                 typedef T & reference;
00166                 typedef T * pointer;
00167             
00168                 /* Functions */
00169             
00171                 enum
00172                 {
00174                     isBegin = 0,
00176                     isEnd = 1
00177                 };
00178             
00180                 Iterator() : m_container(0), m_index(0), m_iter() { }
00182                 Iterator(container_type &container, int state);
00184                 Iterator(container_type &container, uint32_t index,
00185                         literator_type const &iter) : m_container(&container),
00186                         m_index(index), m_iter(iter) { }
00188                 Iterator(iterator_type const &it) : m_container(it.m_container),
00189                         m_index(it.m_index), m_iter(it.m_iter) { }
00191                 Iterator &operator=(iterator_type const &right);
00192                 
00194                 reference operator*() const { return *m_iter; }
00196                 pointer operator->() const { return &(*m_iter); }
00197                 
00199                 bool operator==(iterator_type const &right) const;
00201                 bool operator!=(iterator_type const &right) const
00202                         { return !(*this == right); }
00203                 
00205                 iterator_type &operator++();
00207                 iterator_type operator++(int);
00208                 
00210                 iterator_type &operator--();
00212                 iterator_type operator--(int);
00213             private:
00214                 container_type *m_container;
00215                 uint32_t m_index;
00216                 literator_type m_iter;
00217         };
00218         
00220         class ConstIterator;
00221         friend class ConstIterator;
00222         class ConstIterator : public 
00223                 std::iterator<std::bidirectional_iterator_tag, T,
00224                     typename HashList<T, KeyT, SIZE>::difference_type,
00225                     T const *, T const &>
00226         {
00227             private:
00229                 typedef HashList<T, KeyT, SIZE> const container_type;
00231                 typedef ConstIterator iterator_type;
00233                 typedef typename container_type::list_type::const_iterator
00234                         literator_type;
00235             public:
00236                 /* Typedefs */
00238                 typedef std::bidirectional_iterator_tag iterator_category;
00240                 typedef T value_type;
00242                 typedef typename container_type::difference_type difference_type;
00244                 typedef T const & reference;
00246                 typedef T const * pointer;
00247             
00248                 /* Functions */
00249             
00251                 enum
00252                 {
00254                     isBegin = 0,
00256                     isEnd = 1
00257                 };
00258             
00260                 ConstIterator() : m_container(0), m_index(0), m_iter() { }
00262                 ConstIterator(container_type &container, int state);
00264                 ConstIterator(container_type &container, uint32_t index,
00265                         literator_type const &iter) : m_container(&container),
00266                         m_index(index), m_iter(iter) { }
00268                 ConstIterator(iterator_type const &it) : m_container(it.m_container),
00269                         m_index(it.m_index), m_iter(it.m_iter) { }
00271                 ConstIterator(typename container_type::iterator const &it) : 
00272                         m_container(it.m_container), m_index(it.m_index),
00273                         m_iter(it.m_iter) { }
00275                 ConstIterator &operator=(iterator_type const &right);
00276                 
00278                 reference operator*() const { return *m_iter; }
00280                 pointer operator->() const { return &(*m_iter); }
00281                 
00283                 bool operator==(iterator_type const &right) const;
00285                 bool operator!=(iterator_type const &right) const
00286                         { return !(*this == right); }
00287                 
00289                 iterator_type &operator++();
00291                 iterator_type operator++(int);
00292                 
00294                 iterator_type &operator--();
00296                 iterator_type operator--(int);
00297             private:
00298                 container_type *m_container;
00299                 uint32_t m_index;
00300                 literator_type m_iter;
00301         };
00302         
00303         /* Typedefs */
00304         
00306         typedef Iterator iterator;
00308         typedef ConstIterator const_iterator;
00310         typedef std::reverse_iterator<iterator> reverse_iterator;
00312         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00313         
00314         /* Constants */
00315         
00317         static int const hash_size = SIZE;
00318         
00319         /* Functions */
00320         
00322 
00329         explicit HashList(hash_type const &hash) : m_hash(&hash), m_lists() { }
00331         explicit HashList(HashList const &hl);
00333         HashList &operator=(HashList const &right);
00334         
00336 
00344         iterator add(KeyT const &key, T const &value);
00345 
00347 
00359         iterator add_sorted(KeyT const &key, T const &value);
00360         
00362         void clear();
00363         
00365 
00369         void erase(iterator it);
00370         
00372 
00376         void erase(iterator first, iterator last);
00377         
00379 
00384         iterator find(KeyT const &key);
00386         const_iterator find(KeyT const &key) const;
00387         
00389 
00399         iterator find_sorted(KeyT const &key);
00401         const_iterator find_sorted(KeyT const &key) const;
00402         
00404 
00409         bool remove(KeyT const &key);
00410         
00412 
00422         bool remove_sorted(KeyT const &key);
00423         
00425         iterator begin() { return iterator(*this, iterator::isBegin); }
00427         iterator end() { return iterator(*this, iterator::isEnd); }
00429         const_iterator begin() const 
00430                 { return const_iterator(*this, const_iterator::isBegin); }
00432         const_iterator end() const 
00433                 { return const_iterator(*this, const_iterator::isEnd); }
00434         
00436         reverse_iterator rbegin() { return reverse_iterator(end()); }
00438         reverse_iterator rend() { return reverse_iterator(begin()); }
00440         const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00442         const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00443         
00445         size_type size() const;
00447         bool empty() const;
00449         size_type max_size() const;
00450     private:
00451         hash_type const *m_hash;
00452         list_type m_lists[hash_size];
00453 };
00454 
00455 /*************************************************************************/
00456 
00457 template <class T, class KeyT, uint32_t SIZE>
00458 HashList<T, KeyT, SIZE>::HashList(HashList const &hl) : m_hash(hl.m_hash),
00459         m_lists() 
00460 { 
00461     for (int i = 0; i < hash_size; ++i)
00462         m_lists[i] = hl.m_lists[i];
00463 }
00464 
00465 /*************************************************************************/
00466 
00467 template <class T, class KeyT, uint32_t SIZE>
00468 HashList<T, KeyT, SIZE> &HashList<T, KeyT, SIZE>::operator=(HashList const &right)
00469 {
00470     if (this != &right)
00471     {
00472         m_hash = right.m_hash;
00473         for (int i = 0; i < hash_size; ++i)
00474             m_lists[i] = right.m_lists[i];
00475     }
00476     
00477     return *this;
00478 }
00479 
00480 /*************************************************************************/
00481 
00482 template <class T, class KeyT, uint32_t SIZE>
00483 typename HashList<T, KeyT, SIZE>::iterator
00484         HashList<T, KeyT, SIZE>::add(KeyT const &key, T const &value)
00485 {
00486     /* Ensure a value with the same key doesn't exist (yet). */
00487     if (find(key) != end())
00488         return end();
00489     
00490     uint32_t index = m_hash->hash(key, hash_size);
00491     return iterator(*this, index,
00492             m_lists[index].insert(m_lists[index].end(), value));
00493 }
00494 
00495 /*************************************************************************/
00496 
00497 template <class T, class KeyT, uint32_t SIZE>
00498 typename HashList<T, KeyT, SIZE>::iterator
00499         HashList<T, KeyT, SIZE>::add_sorted(KeyT const &key, T const &value)
00500 {
00501     /* Ensure a value with the same key doesn't exist (yet). */
00502     if (find_sorted(key) != end())
00503         return end();
00504     
00505     uint32_t index = m_hash->hash(key, hash_size);
00506     typename list_type::iterator it, end;
00507     
00508     /* Try to insert it at an appropriate place. */
00509     for (it = m_lists[index].begin(), end = m_lists[index].end();
00510             it != end; ++it)
00511         if (m_hash->compare(key, (*it)) < 0)
00512             return iterator(*this, index, m_lists[index].insert(it, value));
00513     
00514     /* When the list is empty OR this value should be the last,
00515      * we add it at the end. */
00516     return iterator(*this, index,
00517             m_lists[index].insert(m_lists[index].end(), value));
00518 }
00519 
00520 /*************************************************************************/
00521 
00522 template <class T, class KeyT, uint32_t SIZE>
00523 void HashList<T, KeyT, SIZE>::clear()
00524 {
00525     for (int i = 0; i < hash_size; ++i)
00526         m_lists[i].clear();
00527 }
00528 
00529 /*************************************************************************/
00530 
00531 
00532 template <class T, class KeyT, uint32_t SIZE>
00533 bool HashList<T, KeyT, SIZE>::empty() const
00534 {   
00535     for (int i = 0; i < hash_size; ++i)
00536         if (!m_lists[i].empty())
00537             return false;
00538     
00539     return true;
00540 }
00541 
00542 /*************************************************************************/
00543 
00544 template <class T, class KeyT, uint32_t SIZE>
00545 void HashList<T, KeyT, SIZE>::erase(iterator it)
00546 {   
00547     m_lists[it.m_index].erase(it.m_iter);
00548 }
00549 
00550 /*************************************************************************/
00551 
00552 template <class T, class KeyT, uint32_t SIZE>
00553 void HashList<T, KeyT, SIZE>::erase(iterator first, iterator last)
00554 {   
00555     for (iterator it = first; it != last; ++it)
00556         m_lists[it.m_index].erase(it.m_iter);
00557 }
00558 
00559 /*************************************************************************/
00560 
00561 template <class T, class KeyT, uint32_t SIZE>
00562 typename HashList<T, KeyT, SIZE>::iterator 
00563         HashList<T, KeyT, SIZE>::find(KeyT const &key)
00564 {
00565     uint32_t index = m_hash->hash(key, hash_size);
00566     typename list_type::iterator it, end;
00567     
00568     for (it = m_lists[index].begin(), end = m_lists[index].end(); it != end; ++it)
00569         if (m_hash->match(key, (*it)))
00570             return iterator(*this, index, it);
00571     
00572     return this->end(); 
00573 }
00574 
00575 /*************************************************************************/
00576 
00577 template <class T, class KeyT, uint32_t SIZE>
00578 typename HashList<T, KeyT, SIZE>::const_iterator 
00579         HashList<T, KeyT, SIZE>::find(KeyT const &key) const
00580 {
00581     uint32_t index = m_hash->hash(key, hash_size);
00582     typename list_type::const_iterator it, end;
00583     
00584     for (it = m_lists[index].begin(), end = m_lists[index].end(); it != end; ++it)
00585         if (m_hash->match(key, (*it)))
00586             return const_iterator(*this, index, it);
00587     
00588     return this->end(); 
00589 }
00590 
00591 /*************************************************************************/
00592 
00593 template <class T, class KeyT, uint32_t SIZE>
00594 typename HashList<T, KeyT, SIZE>::iterator 
00595         HashList<T, KeyT, SIZE>::find_sorted(KeyT const &key)
00596 {
00597     int result;
00598     uint32_t index = m_hash->hash(key, hash_size);
00599     typename list_type::iterator it, end;
00600     
00601     for (it = m_lists[index].begin(), end = m_lists[index].end(); it != end; ++it)
00602     {
00603         if ((result = m_hash->compare(key, (*it))) == 0)
00604             return iterator(*this, index, it);
00605         else if (result < 0)
00606             return this->end();
00607     }
00608     
00609     return this->end(); 
00610 }
00611 
00612 /*************************************************************************/
00613 
00614 template <class T, class KeyT, uint32_t SIZE>
00615 typename HashList<T, KeyT, SIZE>::const_iterator 
00616         HashList<T, KeyT, SIZE>::find_sorted(KeyT const &key) const
00617 {
00618     int result;
00619     uint32_t index = m_hash->hash(key, hash_size);
00620     typename list_type::const_iterator it, end;
00621     
00622     for (it = m_lists[index].begin(), end = m_lists[index].end(); it != end; ++it)
00623     {
00624         if ((result = m_hash->compare(key, (*it))) == 0)
00625             return const_iterator(*this, index, it);
00626         else if (result < 0)
00627             return this->end();
00628     }
00629     
00630     return this->end(); 
00631 }
00632 
00633 /*************************************************************************/
00634 
00635 template <class T, class KeyT, uint32_t SIZE>
00636 typename HashList<T, KeyT, SIZE>::size_type HashList<T, KeyT, SIZE>::max_size() const
00637 {
00638     size_type sz = 0, prev = 0;
00639     
00640     for (int i = 0; i < hash_size; ++i)
00641     {
00642         sz += m_lists[i].max_size();
00643         if (sz < prev)
00644             return prev;
00645         else
00646             prev = sz;
00647     }
00648     
00649     return sz;
00650 }
00651 
00652 /*************************************************************************/
00653 
00654 template <class T, class KeyT, uint32_t SIZE>
00655 bool HashList<T, KeyT, SIZE>::remove(KeyT const &key)
00656 {
00657     iterator it = find(key);
00658     
00659     if (it == end())
00660         return false;
00661     
00662     erase(it);
00663     return true;    
00664 }
00665 
00666 /*************************************************************************/
00667 
00668 template <class T, class KeyT, uint32_t SIZE>
00669 bool HashList<T, KeyT, SIZE>::remove_sorted(KeyT const &key)
00670 {
00671     iterator it = find_sorted(key);
00672     
00673     if (it == end())
00674         return false;
00675     
00676     erase(it);
00677     return true;    
00678 }
00679 
00680 /*************************************************************************/
00681 
00682 template <class T, class KeyT, uint32_t SIZE>
00683 typename HashList<T, KeyT, SIZE>::size_type HashList<T, KeyT, SIZE>::size() const
00684 {
00685     size_type sz = 0;
00686     
00687     for (int i = 0; i < hash_size; ++i)
00688         sz += m_lists[i].size();
00689     
00690     return sz;
00691 }
00692 
00693 /*************************************************************************/
00694 
00695 template <class T, class KeyT, uint32_t SIZE>
00696 HashList<T, KeyT, SIZE>::ConstIterator::ConstIterator(container_type &container,
00697         int state) : m_container(&container), m_index(0), m_iter()
00698 {
00699     switch (state)
00700     {
00701         case isBegin:
00702             for (int i = 0; i < container.hash_size; ++i)
00703             {
00704                 if (!container.m_lists[i].empty())
00705                 {
00706                     m_index = i;
00707                     m_iter = container.m_lists[m_index].begin();
00708                     return;
00709                 }
00710             }
00711             /* Fall through */
00712         case isEnd:
00713             m_index = (container.hash_size - 1);
00714             m_iter = container.m_lists[m_index].end();
00715             break;
00716         default:
00717             break;
00718     }
00719 }
00720 
00721 /*************************************************************************/
00722 
00723 template <class T, class KeyT, uint32_t SIZE>
00724 typename HashList<T, KeyT, SIZE>::ConstIterator &
00725         HashList<T, KeyT, SIZE>::ConstIterator::operator=(iterator_type const &right)
00726 {
00727     if (this != &right)
00728     {
00729         m_container = right.m_container;
00730         m_index = right.m_index;
00731         m_iter = right.m_iter;
00732     }
00733     
00734     return *this;
00735 }
00736 
00737 /*************************************************************************/
00738 
00739 template <class T, class KeyT, uint32_t SIZE>
00740 bool HashList<T, KeyT, SIZE>::ConstIterator::operator==(iterator_type const &right) const
00741 {
00742     if (this == &right)
00743         return true;
00744     
00745     return ((m_container == right.m_container) && (m_index == right.m_index) &&
00746             (m_iter == right.m_iter));
00747 }
00748 
00749 /*************************************************************************/
00750 
00751 template <class T, class KeyT, uint32_t SIZE>
00752 typename HashList<T, KeyT, SIZE>::ConstIterator &
00753         HashList<T, KeyT, SIZE>::ConstIterator::operator++()
00754 {
00755     if (m_container)
00756     {
00757         if (m_iter != m_container->m_lists[m_index].end())
00758             ++m_iter;
00759         
00760         /* If the current iterator is the end() of its list */
00761         if (m_iter == m_container->m_lists[m_index].end())
00762         {
00763             /* FIrst ensure we're not at the last index */
00764             if (m_index == (m_container->hash_size - 1))
00765                 return *this; /* Don't increment it further */
00766             
00767             /* Look for the next index */
00768             for (int i = m_index + 1; i < m_container->hash_size; ++i)
00769             {
00770                 if (!m_container->m_lists[i].empty())
00771                 {
00772                     m_index = i;
00773                     m_iter = m_container->m_lists[m_index].begin();
00774                     return *this;
00775                 }
00776             }
00777             
00778             /* If we fall there, we're at the end */
00779             m_index = (m_container->hash_size - 1);
00780             m_iter = m_container->m_lists[m_index].end();
00781         }
00782     }
00783     
00784     return *this;
00785 }
00786 
00787 /*************************************************************************/
00788 
00789 template <class T, class KeyT, uint32_t SIZE>
00790 typename HashList<T, KeyT, SIZE>::ConstIterator
00791         HashList<T, KeyT, SIZE>::ConstIterator::operator++(int)
00792 {
00793     ConstIterator before(*this);
00794     operator++();
00795     return before;
00796 }
00797 
00798 /*************************************************************************/
00799 
00800 template <class T, class KeyT, uint32_t SIZE>
00801 typename HashList<T, KeyT, SIZE>::ConstIterator &
00802         HashList<T, KeyT, SIZE>::ConstIterator::operator--()
00803 {
00804     if (m_container)
00805     {
00806         /* If the current iterator is the first of its list */
00807         if (m_iter == m_container->m_lists[m_index].begin())
00808         {
00809             /* FIrst ensure we're not at the first index */
00810             if (m_index == 0)
00811                 return *this; /* Don't decrement it further */
00812             
00813             /* Look for the next index */
00814             for (int i = m_index - 1; i > 0; --i)
00815             {
00816                 if (!m_container->m_lists[i].empty())
00817                 {
00818                     m_index = i;
00819                     m_iter = --(m_container->m_lists[m_index].end());
00820                     return *this;
00821                 }
00822             }
00823             
00824             /* If we fall there, we're at the beginning of the hash list -- 
00825              * don't do anything. */
00826         } else {
00827             --m_iter;
00828         }
00829     }
00830     
00831     return *this;
00832 }
00833 
00834 /*************************************************************************/
00835 
00836 template <class T, class KeyT, uint32_t SIZE>
00837 typename HashList<T, KeyT, SIZE>::ConstIterator
00838         HashList<T, KeyT, SIZE>::ConstIterator::operator--(int)
00839 {
00840     ConstIterator before(*this);
00841     operator--();
00842     return before;
00843 }
00844 
00845 /*************************************************************************/
00846 
00847 template <class T, class KeyT, uint32_t SIZE>
00848 HashList<T, KeyT, SIZE>::Iterator::Iterator(container_type &container,
00849         int state) : m_container(&container), m_index(0), m_iter()
00850 {
00851     switch (state)
00852     {
00853         case isBegin:
00854             for (int i = 0; i < container.hash_size; ++i)
00855             {
00856                 if (!container.m_lists[i].empty())
00857                 {
00858                     m_index = i;
00859                     m_iter = container.m_lists[m_index].begin();
00860                     return;
00861                 }
00862             }
00863             /* Fall through */
00864         case isEnd:
00865             m_index = (container.hash_size - 1);
00866             m_iter = container.m_lists[m_index].end();
00867             break;
00868         default:
00869             break;
00870     }
00871 }
00872 
00873 /*************************************************************************/
00874 
00875 template <class T, class KeyT, uint32_t SIZE>
00876 typename HashList<T, KeyT, SIZE>::Iterator &
00877         HashList<T, KeyT, SIZE>::Iterator::operator=(iterator_type const &right)
00878 {
00879     if (this != &right)
00880     {
00881         m_container = right.m_container;
00882         m_index = right.m_index;
00883         m_iter = right.m_iter;
00884     }
00885     
00886     return *this;
00887 }
00888 
00889 /*************************************************************************/
00890 
00891 template <class T, class KeyT, uint32_t SIZE>
00892 bool HashList<T, KeyT, SIZE>::Iterator::operator==(iterator_type const &right) const
00893 {
00894     if (this == &right)
00895         return true;
00896     
00897     return ((m_container == right.m_container) && (m_index == right.m_index) &&
00898             (m_iter == right.m_iter));
00899 }
00900 
00901 /*************************************************************************/
00902 
00903 template <class T, class KeyT, uint32_t SIZE>
00904 typename HashList<T, KeyT, SIZE>::Iterator &
00905         HashList<T, KeyT, SIZE>::Iterator::operator++()
00906 {
00907     if (m_container)
00908     {
00909         if (m_iter != m_container->m_lists[m_index].end())
00910             ++m_iter;
00911         
00912         /* If the current iterator is the end() of its list */
00913         if (m_iter == m_container->m_lists[m_index].end())
00914         {
00915             /* FIrst ensure we're not at the last index */
00916             if (m_index == (m_container->hash_size - 1))
00917                 return *this; /* Don't increment it further */
00918             
00919             /* Look for the next index */
00920             for (int i = m_index + 1; i < m_container->hash_size; ++i)
00921             {
00922                 if (!m_container->m_lists[i].empty())
00923                 {
00924                     m_index = i;
00925                     m_iter = m_container->m_lists[m_index].begin();
00926                     return *this;
00927                 }
00928             }
00929             
00930             /* If we fall there, we're at the end */
00931             m_index = (m_container->hash_size - 1);
00932             m_iter = m_container->m_lists[m_index].end();
00933         }
00934     }
00935     
00936     return *this;
00937 }
00938 
00939 /*************************************************************************/
00940 
00941 template <class T, class KeyT, uint32_t SIZE>
00942 typename HashList<T, KeyT, SIZE>::Iterator
00943         HashList<T, KeyT, SIZE>::Iterator::operator++(int)
00944 {
00945     Iterator before(*this);
00946     operator++();
00947     return before;
00948 }
00949 
00950 /*************************************************************************/
00951 
00952 template <class T, class KeyT, uint32_t SIZE>
00953 typename HashList<T, KeyT, SIZE>::Iterator &
00954         HashList<T, KeyT, SIZE>::Iterator::operator--()
00955 {
00956     if (m_container)
00957     {
00958         /* If the current iterator is the first of its list */
00959         if (m_iter == m_container->m_lists[m_index].begin())
00960         {
00961             /* FIrst ensure we're not at the first index */
00962             if (m_index == 0)
00963                 return *this; /* Don't decrement it further */
00964             
00965             /* Look for the next index */
00966             for (int i = m_index - 1; i > 0; --i)
00967             {
00968                 if (!m_container->m_lists[i].empty())
00969                 {
00970                     m_index = i;
00971                     m_iter = --(m_container->m_lists[m_index].end());
00972                     return *this;
00973                 }
00974             }
00975             
00976             /* If we fall there, we're at the beginning of the hash list -- 
00977              * don't do anything. */
00978         } else {
00979             --m_iter;
00980         }
00981     }
00982     
00983     return *this;
00984 }
00985 
00986 /*************************************************************************/
00987 
00988 template <class T, class KeyT, uint32_t SIZE>
00989 typename HashList<T, KeyT, SIZE>::Iterator
00990         HashList<T, KeyT, SIZE>::Iterator::operator--(int)
00991 {
00992     Iterator before(*this);
00993     operator--();
00994     return before;
00995 }
00996 
00997 /*************************************************************************/
00998 
00999 } /* namespace containers */
01000 
01001 /*************************************************************************/
01002 
01003 #endif /* CONTAINERS_HASHLIST_H */

Generated on Sun May 20 21:32:14 2007 for Epona API by  doxygen 1.4.6