#include #include #include namespace detail { template struct hasher { size_t operator()(const K& k) const; }; template struct tagged_hasher { size_t operator()(const K& k) const; }; template struct eq_compare { bool operator()(const K& lhs, const K& rhs) const { return lhs == rhs; } }; template struct default_elem_ctor { V operator()(const K& k) const; }; // template , template typename Allocator = std::allocator> // struct flat_object_map { // using key_type = K; // using value_type = V; // using value_pointer_t = pointer_wrapper; // std::pair acquire(const K& key) // { // auto [iter, is_new] = data.try_emplace(key, object_with_refcount{}); // auto& value = iter->second; // if (is_new) { // value.refcount = 1; // V* new_value = static_cast(mi_aligned_alloc(alignof(V), sizeof(V))); // value.object_pointer = make_pointer_wrapper(new_value); // *value.object_pointer = std::move(default_elem_ctor{}(key)); // return {value.object_pointer, true}; // } else { // value.refcount++; // return {value.object_pointer, false}; // } // } // void release(const K& key) // { // if (auto iter = data.find(key); iter == data.end()) { // throw std::runtime_error("Key not found in refcount map."); // } else if (--iter->second.refcount == 0) { // data.erase(iter); // } // } // protected: // struct object_with_refcount { // size_t refcount{}; // value_pointer_t object_pointer{}; // }; // flat_hash_map_mp, Allocator>> // data{}; // }; template typename Allocator = std::allocator> struct flat_object_set { using value_pointer_t = pointer_wrapper; std::pair acquire(const K& key) { auto [iter, is_new] = data.try_emplace(key, size_t{1}); if (is_new) { return {make_pointer_wrapper(const_cast(iter->first)), true}; } else { auto& refcount = iter->second; refcount++; return {make_pointer_wrapper(const_cast(iter->first)), false}; } } void release(const K& key) { if (auto iter = data.find(key); iter == data.end()) { throw std::runtime_error("Key not found in refcount map."); } else if (--iter->second == 0) { data.erase(iter); } } protected: using element_hasher = hasher; node_hash_map_mp, eq_compare> data{}; }; } // namespace detail // template // using flat_object_map_mp = detail::flat_object_map, mi_stl_allocator>; template using flat_object_set_mp = detail::flat_object_set; // template // using tagged_flat_object_map_mp = detail::flat_object_map, mi_stl_allocator>;