diff --git a/BAN/include/BAN/HashMap.h b/BAN/include/BAN/HashMap.h index 4fd15354..d739c8a7 100644 --- a/BAN/include/BAN/HashMap.h +++ b/BAN/include/BAN/HashMap.h @@ -57,6 +57,8 @@ namespace BAN T& operator[](const Key&); const T& operator[](const Key&) const; + iterator find(const Key& key); + const_iterator find(const Key& key) const; bool contains(const Key&) const; bool empty() const; @@ -66,6 +68,8 @@ namespace BAN ErrorOr rebucket(size_type); LinkedList& get_bucket(const Key&); const LinkedList& get_bucket(const Key&) const; + Vector>::iterator get_bucket_iterator(const Key&); + Vector>::const_iterator get_bucket_iterator(const Key&) const; private: Vector> m_buckets; @@ -187,15 +191,34 @@ namespace BAN ASSERT(false); } + template + typename HashMap::iterator HashMap::find(const Key& key) + { + if (empty()) + return end(); + auto bucket_it = get_bucket_iterator(key); + for (auto it = bucket_it->begin(); it != bucket_it->end(); it++) + if (it->key == key) + return iterator(m_buckets.end(), bucket_it, it); + return end(); + } + + template + typename HashMap::const_iterator HashMap::find(const Key& key) const + { + if (empty()) + return end(); + auto bucket_it = get_bucket_iterator(key); + for (auto it = bucket_it->begin(); it != bucket_it->end(); it++) + if (it->key == key) + return const_iterator(m_buckets.end(), bucket_it, it); + return end(); + } + template bool HashMap::contains(const Key& key) const { - if (empty()) return false; - const auto& bucket = get_bucket(key); - for (const Entry& entry : bucket) - if (entry.key == key) - return true; - return false; + return find(key) != end(); } template @@ -236,17 +259,29 @@ namespace BAN template LinkedList::Entry>& HashMap::get_bucket(const Key& key) { - ASSERT(!m_buckets.empty()); - auto index = HASH()(key) % m_buckets.size(); - return m_buckets[index]; + return *get_bucket_iterator(key); } template const LinkedList::Entry>& HashMap::get_bucket(const Key& key) const + { + return *get_bucket_iterator(key); + } + + template + Vector::Entry>>::iterator HashMap::get_bucket_iterator(const Key& key) { ASSERT(!m_buckets.empty()); auto index = HASH()(key) % m_buckets.size(); - return m_buckets[index]; + return next(m_buckets.begin(), index); + } + + template + Vector::Entry>>::const_iterator HashMap::get_bucket_iterator(const Key& key) const + { + ASSERT(!m_buckets.empty()); + auto index = HASH()(key) % m_buckets.size(); + return next(m_buckets.begin(), index); } } diff --git a/BAN/include/BAN/Iterators.h b/BAN/include/BAN/Iterators.h index 5d38a24b..3c6473c5 100644 --- a/BAN/include/BAN/Iterators.h +++ b/BAN/include/BAN/Iterators.h @@ -284,6 +284,14 @@ namespace BAN } } + IteratorDoubleGeneral(const OuterIterator& outer_end, const OuterIterator& outer_current, const InnerIterator& inner_current) + : m_outer_end(outer_end) + , m_outer_current(outer_current) + , m_inner_current(inner_current) + { + find_valid_or_end(); + } + void find_valid_or_end() { while (m_inner_current == m_outer_current->end())