#pragma once #include "hive.hpp" #include "hashmap.hpp" namespace detail { template struct hasher { size_t operator()(const K& k) const; }; // template // struct eq_compare // { // bool operator()(const K& lhs, const K& rhs) const; // }; template struct default_elem_ctor { V operator()(const K& k) const; }; template > struct hashed_refcount_hive { using iterator = typename hive::iterator; public: std::pair acquire(const K& key) { size_t hash_key = hasher()(key); auto iter = refcount_data_map.find(hash_key); if (iter == refcount_data_map.end()) { auto data_iter = data.emplace(default_elem_ctor{}(key)); refcount_data_map.emplace(hash_key, std::make_pair(1, data_iter)); return {data_iter, true}; } else { iter->second.first += 1; return {iter->second.second, false}; } } void release(const K& key) { size_t hash_key = hasher()(key); auto iter = refcount_data_map.find(hash_key); if (iter == refcount_data_map.end()) throw std::runtime_error("Key not found in refcount map."); if (--iter->second.first == 0) { data.erase(iter->second.second); refcount_data_map.erase(iter); } } void release(const iterator& ptr) { for (auto iter = refcount_data_map.begin(); iter != refcount_data_map.end(); ++iter) { if (iter->second.second == ptr) { if (--iter->second.first == 0) { data.erase(iter->second.second); refcount_data_map.erase(iter); } return; } } throw std::runtime_error("Pointer not found in refcount map."); } protected: hive data{}; // manually calculate hash for the key, so that we do not need to store the key flat_hash_map> refcount_data_map{}; }; } // namespace detail template using hashed_refcount_hive_mp = detail::hashed_refcount_hive>;