00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
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
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
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
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
00315
00317 static int const hash_size = SIZE;
00318
00319
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
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
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
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
00515
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
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
00761 if (m_iter == m_container->m_lists[m_index].end())
00762 {
00763
00764 if (m_index == (m_container->hash_size - 1))
00765 return *this;
00766
00767
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
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
00807 if (m_iter == m_container->m_lists[m_index].begin())
00808 {
00809
00810 if (m_index == 0)
00811 return *this;
00812
00813
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
00825
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
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
00913 if (m_iter == m_container->m_lists[m_index].end())
00914 {
00915
00916 if (m_index == (m_container->hash_size - 1))
00917 return *this;
00918
00919
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
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
00959 if (m_iter == m_container->m_lists[m_index].begin())
00960 {
00961
00962 if (m_index == 0)
00963 return *this;
00964
00965
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
00977
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 }
01000
01001
01002
01003 #endif