revamped HashRange

master
Daniel Kolesa 2015-06-16 01:24:19 +01:00
parent aa2a0afcc1
commit 8324f5f9cc
1 changed files with 25 additions and 32 deletions

View File

@ -28,49 +28,41 @@ struct HashRange: octa::InputRange<HashRange<T>, octa::ForwardRangeTag, T> {
private: private:
using Chain = octa::detail::HashChain<T>; using Chain = octa::detail::HashChain<T>;
Chain **p_chains; Chain **p_beg;
Chain **p_end;
Chain *p_node; Chain *p_node;
octa::Size p_num;
void advance() { void advance() {
while (p_num > 0 && !p_chains[0]) { while ((p_beg != p_end) && !p_beg[0])
--p_num; ++p_beg;
++p_chains; if (p_beg != p_end) {
} p_node = p_beg[0];
if (p_num > 0) { ++p_beg;
p_node = p_chains[0];
--p_num;
++p_chains;
} else {
p_node = nullptr;
} }
} }
public: public:
HashRange(): p_chains(), p_num(0) {} HashRange(): p_beg(), p_end(), p_node() {}
HashRange(Chain **ch, octa::Size n): p_chains(ch), p_num(n) { HashRange(const HashRange &v): p_beg(v.p_beg), p_end(v.p_end),
p_node(v.p_node) {}
HashRange(Chain **beg, Chain **end): p_beg(beg), p_end(end), p_node() {
advance(); advance();
} }
HashRange(Chain **ch, Chain *node, octa::Size n): p_chains(ch), HashRange(Chain **beg, Chain **end, Chain *node): p_beg(beg), p_end(end),
p_node(node), p_num(n) {} p_node(node) {}
HashRange(const HashRange &v): p_chains(v.p_chains), p_node(v.p_node),
p_num(v.p_num) {}
HashRange &operator=(const HashRange &v) { HashRange &operator=(const HashRange &v) {
p_chains = v.p_chains; p_beg = v.p_beg;
p_end = v.p_end;
p_node = v.p_node; p_node = v.p_node;
p_num = v.p_num;
return *this; return *this;
} }
bool empty() const { return !p_node && p_num <= 0; } bool empty() const { return !p_node; }
bool pop_front() { bool pop_front() {
if (empty()) return false; if (!p_node) return false;
if (p_node->next) { p_node = p_node->next;
p_node = p_node->next; if (p_node) return true;
return true;
}
p_node = nullptr;
advance(); advance();
return true; return true;
} }
@ -281,8 +273,9 @@ namespace detail {
found = insert(h); found = insert(h);
B::swap_elem(found->value, elem); B::swap_elem(found->value, elem);
} }
return octa::make_pair(Range(&p_data.first()[h + 1], found, Chain **hch = p_data.first();
bucket_count() - h - 1), ins); return octa::make_pair(Range(hch + h + 1, hch + bucket_count(),
found), ins);
} }
float load_factor() const { return float(p_len) / p_size; } float load_factor() const { return float(p_len) / p_size; }
@ -340,13 +333,13 @@ namespace detail {
} }
Range each() { Range each() {
return Range(p_data.first(), bucket_count()); return Range(p_data.first(), p_data.first() + bucket_count());
} }
ConstRange each() const { ConstRange each() const {
return ConstRange(p_data.first(), bucket_count()); return ConstRange(p_data.first(), p_data.first() + bucket_count());
} }
ConstRange ceach() const { ConstRange ceach() const {
return ConstRange(p_data.first(), bucket_count()); return ConstRange(p_data.first(), p_data.first() + bucket_count());
} }
LocalRange each(octa::Size n) { LocalRange each(octa::Size n) {