I'm implementing an open address hash table like this:
template <typename K, typename V>
class open_addressing_map
{
public:
using key_type = K;
using mapped_type = V;
using value_type = std::pair<const key_type, mapped_type>;
using hasher = std::hash<K>;
using hash_code = std::size_t;
using allocator_type = std::allocator<value_type>;
value_type* buckets; //array of value, allocate at constructor
std::size_t capacity; //capacity buckets
hasher hash_func;
allocator_type allocator;
private:
std::pair<std::size_t, bool> find_internal(hash_code hash, const key_type& key);
std::size_t find_free_bucket(hash_code hash);
public:
template<typename ...Args>
std::pair<iterator, bool> emplace(Args&& ...args) {
//I need to construct a key_type in stack here to pass into find() and find_free_bucket
//I don't want to construct a value_type because it can be expensive.
key_type key = ...?; //how can I do this
hash_code hash;
hash = hash_func(key);
auto res = find(hash, key);
//if not found
if (!res.second) {
std::size_t free_idx = find_free_bucket(hash);
if (hash == capacity)
return {iterator(capacity), false};
else {
//need to rehash then insert a gain.
}
//construct value
allocator.construct(std::forward<Args&&>(args)...);
}
}
};
The problem is I use an with capacity which was pre-allocated at constructor to reduce allocation overhead. In emplace
function, I need to find correct position to construct the value, but need the key before I can get this position.
I can construct a value_type
here to get the key
but later, I have to move it to correct position in buckets
array.
The idea is construct only the key
in stack, but I don't know how to do this?