|
|
@@ -13,7 +13,7 @@
|
|
|
#include <utility>
|
|
|
#include <vector>
|
|
|
|
|
|
-#include "iterator/join_iterator.hpp"
|
|
|
+#include "iterator/recursive_iterator.hpp"
|
|
|
|
|
|
template <typename K, typename Hash = std::hash<K>, typename KeyEqual = std::equal_to<K> >
|
|
|
class bucket_hash_set;
|
|
|
@@ -38,8 +38,8 @@ public: // typedefs
|
|
|
using impl_type = std::vector<bucket_type>;
|
|
|
|
|
|
template <typename It>
|
|
|
- using iter_wrap = iterator::joining_iterator<It>;
|
|
|
- using iterator = iter_wrap<typename impl_type::iterator>;
|
|
|
+ using iter_wrap = iterator::recursive_iterator<It>;
|
|
|
+ using iterator = iter_wrap<typename impl_type::const_iterator>;
|
|
|
using const_iterator = iter_wrap<typename impl_type::const_iterator>;
|
|
|
using local_iterator = typename bucket_type::const_iterator;
|
|
|
using local_const_iterator = typename bucket_type::const_iterator;
|
|
|
@@ -47,6 +47,8 @@ public: // typedefs
|
|
|
static const constexpr size_type default_buckets = 10;
|
|
|
static const constexpr float default_load_factor = 1.0F;
|
|
|
static const constexpr float growth_factor = 2.0F;
|
|
|
+private:
|
|
|
+ using internal_iterator = iter_wrap<typename impl_type::iterator>;
|
|
|
public:
|
|
|
// Construction
|
|
|
bucket_hash_set() : bucket_hash_set(default_buckets) {}
|
|
|
@@ -78,15 +80,13 @@ public:
|
|
|
size_type size() const { return size_; }
|
|
|
|
|
|
// Iterators
|
|
|
- iterator begin() { return make_end_aware_iterator(buckets_); }
|
|
|
const_iterator begin() const { return cbegin(); }
|
|
|
- const_iterator cbegin() const { return make_end_aware_iterator(buckets_); }
|
|
|
- iterator end() { return iterator{}; }
|
|
|
+ const_iterator cbegin() const { return make_recursive_iterator(buckets_); }
|
|
|
const_iterator end() const { return cend(); }
|
|
|
const_iterator cend() const { return const_iterator{}; }
|
|
|
|
|
|
// Create
|
|
|
- std::pair<iterator, bool> insert(value_type const & vt) {
|
|
|
+ std::pair<const_iterator, bool> insert(value_type const & vt) {
|
|
|
maybe_expand(1);
|
|
|
auto lookup = lookup_impl(buckets_, vt);
|
|
|
auto const end = lookup.first->end();
|
|
|
@@ -95,9 +95,9 @@ public:
|
|
|
++size_;
|
|
|
lookup.second = lookup.first->insert(end, vt);
|
|
|
}
|
|
|
- return { {{lookup.first, buckets_.end()}, {lookup.second, end}}, create };
|
|
|
+ return { {::iterator::in_place, make_end_aware_iterator(lookup.first, buckets_.end()), make_end_aware_iterator(lookup.second, end)}, create };
|
|
|
}
|
|
|
- iterator insert(const_iterator, value_type const & vt) {
|
|
|
+ const_iterator insert(const_iterator, value_type const & vt) {
|
|
|
return insert(vt).first;
|
|
|
}
|
|
|
template <typename InputIt>
|
|
|
@@ -108,13 +108,6 @@ public:
|
|
|
void insert(std::initializer_list<value_type> ilist) { insert(ilist.begin(), ilist.end()); }
|
|
|
|
|
|
// Access
|
|
|
- iterator find(key_type const & key) {
|
|
|
- return find_impl<iterator>(buckets_, key);
|
|
|
- }
|
|
|
- std::pair<iterator, iterator> equal_range(key_type const & key) {
|
|
|
- auto it = find(key);
|
|
|
- return { it, ++iterator(it) };
|
|
|
- }
|
|
|
const_iterator find(key_type const & key) const {
|
|
|
return find_impl<const_iterator>(buckets_, key);
|
|
|
}
|
|
|
@@ -125,11 +118,11 @@ public:
|
|
|
size_type count(key_type const & key) const { return find(key) != end(); }
|
|
|
|
|
|
// Remove
|
|
|
- iterator erase(const_iterator it) {
|
|
|
+ const_iterator erase(const_iterator it) {
|
|
|
return erase_impl(unconst_iterator(it));
|
|
|
}
|
|
|
- iterator erase(const_iterator first, const_iterator last) {
|
|
|
- iterator it = unconst_iterator(first);
|
|
|
+ const_iterator erase(const_iterator first, const_iterator last) {
|
|
|
+ internal_iterator it = unconst_iterator(first);
|
|
|
while (last != it) { it = erase_impl(it); }
|
|
|
return it;
|
|
|
}
|
|
|
@@ -141,10 +134,8 @@ public:
|
|
|
void clear() { erase(begin(), end()); }
|
|
|
|
|
|
// Bucket Interaction Functions
|
|
|
- local_iterator begin(size_type bkt) { return buckets_[bkt].begin(); }
|
|
|
local_const_iterator begin(size_type bkt) const { return buckets_[bkt].cbegin(); }
|
|
|
local_const_iterator cbegin(size_type bkt) const { return buckets_[bkt].cbegin(); }
|
|
|
- local_iterator end(size_type bkt) { return buckets_[bkt].end(); }
|
|
|
local_const_iterator end(size_type bkt) const { return buckets_[bkt].cend(); }
|
|
|
local_const_iterator cend(size_type bkt) const { return buckets_[bkt].cend(); }
|
|
|
size_type bucket_count() const { return buckets_.size(); }
|
|
|
@@ -203,27 +194,30 @@ private:
|
|
|
if (lookup.second == lookup.first->end()) {
|
|
|
return Iterator{};
|
|
|
} else {
|
|
|
- return { {lookup.first, bkt.end()}, {lookup.second, lookup.first->end()} };
|
|
|
+ return { ::iterator::in_place, make_end_aware_iterator(lookup.first, bkt.end()),
|
|
|
+ make_end_aware_iterator(lookup.second, lookup.first->end()) };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- iterator unconst_iterator(const_iterator it) {
|
|
|
- auto lit = it.join_iterator();
|
|
|
- auto iter = it.element_iterator();
|
|
|
+ internal_iterator unconst_iterator(const_iterator const & it) {
|
|
|
+ auto lit = std::get<0>(it);
|
|
|
+ auto iter = std::get<1>(it);
|
|
|
|
|
|
- if ( lit.done() ) { return end(); }
|
|
|
+ if ( lit.done() ) { return {}; }
|
|
|
auto nit = buckets_.begin();
|
|
|
std::advance(nit, std::distance(buckets_.cbegin(), lit.current()));
|
|
|
|
|
|
- return { {nit, buckets_.end()}, {nit->erase(iter.current(), iter.current()), nit->end()} };
|
|
|
+ return { ::iterator::in_place, make_end_aware_iterator(nit, buckets_.end()),
|
|
|
+ make_end_aware_iterator(nit->erase(iter.current(), iter.current()), nit->end()) };
|
|
|
}
|
|
|
|
|
|
- iterator erase_impl(iterator it) {
|
|
|
- auto b = it.join_iterator();
|
|
|
- auto l = it.element_iterator();
|
|
|
+ internal_iterator erase_impl(internal_iterator it) {
|
|
|
+ auto b = std::get<0>(it);
|
|
|
+ auto l = std::get<1>(it);
|
|
|
if ( b.done() || l.done() ) { return it; }
|
|
|
--size_;
|
|
|
- return { {b.current(), b.end()}, {b->erase(l.current()), l.end()}, true };
|
|
|
+ return { ::iterator::in_place, make_end_aware_iterator(b.current(), b.end()),
|
|
|
+ make_end_aware_iterator(b->erase(l.current()), l.end()) };
|
|
|
}
|
|
|
private: // members
|
|
|
impl_type buckets_{default_buckets};
|