diff --git a/octa/internal/hashtable.h b/octa/internal/hashtable.h index aa8fde4..3668845 100644 --- a/octa/internal/hashtable.h +++ b/octa/internal/hashtable.h @@ -50,6 +50,8 @@ public: HashRange(Chain **ch, octa::Size n): p_chains(ch), p_num(n) { advance(); } + HashRange(Chain **ch, Chain *node, octa::Size n): p_chains(ch), + p_node(node), p_num(n) {} HashRange(const HashRange &v): p_chains(v.p_chains), p_node(v.p_node), p_num(v.p_num) {} @@ -230,6 +232,27 @@ namespace detail { return (insert(h, key) = val); } + template + octa::Pair emplace(Args &&...args) { + E elem(octa::forward(args)...); + octa::Size h = get_hash()(B::get_key(elem)) & (p_size - 1); + Chain *found = nullptr; + bool ins = true; + for (Chain *c = p_data.first()[h]; c; c = c->next) { + if (get_eq()(B::get_key(elem), B::get_key(c->value))) { + found = c; + ins = false; + break; + } + } + if (!found) { + found = insert(h); + B::swap_elem(found->value, elem); + } + return octa::make_pair(Range(&p_data.first()[h + 1], found, + bucket_count() - h - 1), ins); + } + float load_factor() const { return float(p_len) / p_size; } float max_load_factor() const { return p_maxlf; } void max_load_factor(float lf) { p_maxlf = lf; } diff --git a/octa/map.h b/octa/map.h index a76071a..b99f30d 100644 --- a/octa/map.h +++ b/octa/map.h @@ -107,6 +107,11 @@ public: return p_table.insert(h, octa::move(key)); } + template + octa::Pair emplace(Args &&...args) { + return p_table.emplace(octa::forward(args)...); + } + octa::Size erase(const K &key) { if (p_table.remove(key)) return 1; return 0;