3#include "di/assert/prelude.h"
4#include "di/bit/bitset/prelude.h"
5#include "di/container/tree/tree_map.h"
6#include "di/types/prelude.h"
11 struct DefaultOpsImpl {
15 constexpr static auto get_key(
T const& t) ->
T const& {
return t; }
19 struct DefaultOpsT : di::meta::TypeConstant<DefaultOpsImpl<T>> {};
22 requires(
requires {
typename T::DefaultOps; })
23 struct DefaultOpsT<T> : di::meta::TypeConstant<typename
T::DefaultOps> {};
26 using DefaultOps = di::meta::Type<DefaultOpsT<T>>;
38template<
typename T,
typename Ops = detail::DefaultOps<T>>
42 using Key =
typename Ops::Key;
44 constexpr static auto max_id = di::NumericLimits<Id>::max;
48 template<
typename... Args>
49 explicit RefCounted(Args&&... args) : value(di::forward<Args>(args)...) {}
57 auto it = m_id_map.find(
id);
58 ASSERT_NOT_EQ(it, m_id_map.end());
60 return di::get<1>(*it).value;
64 auto it = m_id_lookup.find(key);
65 if (it == m_id_lookup.end()) {
69 return di::get<1>(*it);
73 requires(di::concepts::CopyConstructible<T>)
75 auto id = allocate_id();
80 auto const& key = get_key(value);
81 ASSERT(!m_id_lookup.contains(key));
82 m_id_lookup[key] = *id;
83 m_id_map.insert_or_assign(*
id, value);
88 auto id = allocate_id();
93 auto const& key = get_key(value);
94 ASSERT(!m_id_lookup.contains(key));
95 m_id_lookup[key] = *id;
96 m_id_map.insert_or_assign(*
id, di::move(value));
101 auto it = m_id_map.find(
id);
102 ASSERT_NOT_EQ(it, m_id_map.end());
104 di::get<1>(*it).ref_count++;
109 auto it = m_id_map.find(
id);
110 ASSERT_NOT_EQ(it, m_id_map.end());
112 auto& rc = di::get<1>(*it);
113 if (--rc.ref_count == 0) {
114 m_id_lookup.erase(get_key(rc.value));
115 m_ids_used[
id - 1] =
false;
121 auto get_key(
T const& value) ->
Key const& {
return Ops::get_key(value); }
123 auto allocate_id() -> di::Optional<Id> {
128 for (
auto id =
Id(1);
id != 0; ++id) {
129 if (!m_ids_used[
id - 1]) {
130 m_ids_used[
id - 1] =
true;
137 di::TreeMap<Id, RefCounted> m_id_map;
138 di::TreeMap<Key, Id> m_id_lookup;
139 di::BitSet<max_id> m_ids_used;
A two-way map between a numberic id and a value.
Definition id_map.h:39
auto allocate(T &&value) -> di::Optional< Id >
Definition id_map.h:87
auto lookup_key(Key const &key) const -> di::Optional< Id >
Definition id_map.h:63
u16 Id
Definition id_map.h:41
auto allocate(T const &value) -> di::Optional< Id > requires(di::concepts::CopyConstructible< T >)
Definition id_map.h:72
auto use_id(Id id) -> Id
Definition id_map.h:100
void drop_id(Id id)
Definition id_map.h:108
static constexpr auto max_id
Definition id_map.h:44
typename Ops::Key Key
Definition id_map.h:42
auto lookup_id(Id id) const -> T const &
Definition id_map.h:56
Definition capability.h:8