22 #ifndef BM_BM_SIM_HANDLE_MGR_H_
23 #define BM_BM_SIM_HANDLE_MGR_H_
25 #include <bm/config.h>
28 #include <type_traits>
31 #include "dynamic_bitset.h"
35 using handle_t = uintptr_t;
39 using bitset = DynamicBitset;
40 using size_type = bitset::size_type;
41 static constexpr size_type npos = bitset::npos;
49 iterator(HandleMgr *handle_mgr, handle_t index)
50 : handle_mgr(handle_mgr), index(index) {}
53 iterator(
const iterator &other) =
default;
55 handle_t &operator*() {
return index;}
56 handle_t *operator->() {
return &index;}
58 bool operator==(
const iterator &other)
const {
59 return (handle_mgr == other.handle_mgr) && (index == other.index);
62 bool operator!=(
const iterator &other)
const {
63 return !(*
this == other);
66 iterator& operator++() {
67 auto pos =
static_cast<size_type
>(index);
68 pos = handle_mgr->handles.find_next(pos);
72 index =
static_cast<handle_t
>(pos);
76 iterator operator++(
int) {
78 const iterator old(*
this);
84 HandleMgr *handle_mgr;
88 class const_iterator {
90 const_iterator(
const HandleMgr *handle_mgr, handle_t index)
91 : handle_mgr(handle_mgr), index(index) {}
94 const_iterator(
const const_iterator &other) =
default;
96 const handle_t &operator*()
const {
return index;}
97 const handle_t *operator->()
const {
return &index;}
99 const_iterator& operator=(
const const_iterator &other) {
100 handle_mgr = other.handle_mgr;
105 bool operator==(
const const_iterator &other)
const {
106 return (handle_mgr == other.handle_mgr) && (index == other.index);
109 bool operator!=(
const const_iterator &other)
const {
110 return !(*
this == other);
113 const const_iterator& operator++() {
114 auto pos =
static_cast<size_type
>(index);
115 pos = handle_mgr->handles.find_next(pos);
119 index =
static_cast<handle_t
>(pos);
123 const const_iterator operator++(
int) {
125 const const_iterator old(*
this);
131 const HandleMgr *handle_mgr;
137 bool operator==(
const HandleMgr &other)
const {
138 return (handles == other.handles);
141 bool operator!=(
const HandleMgr &other)
const {
142 return !(*
this == other);
147 int get_handle(handle_t *handle) {
148 auto pos = first_unset;
149 *handle =
static_cast<handle_t
>(pos);
150 auto s = handles.size();
153 first_unset = handles.find_unset_next(first_unset);
154 first_unset = (first_unset == DynamicBitset::npos) ? s : first_unset;
158 handles.push_back(
true);
163 int release_handle(handle_t handle) {
164 auto pos =
static_cast<size_type
>(handle);
165 auto s = handles.size();
166 if (pos >= s || !handles.reset(pos))
return -1;
167 if (first_unset > pos) first_unset = pos;
171 int set_handle(handle_t handle) {
172 auto pos =
static_cast<size_type
>(handle);
173 auto s = handles.size();
175 handles.resize(pos + 1);
176 if (!handles.set(pos))
178 if (first_unset == pos) {
179 first_unset = handles.find_unset_next(pos);
180 first_unset = (first_unset == DynamicBitset::npos) ? s : first_unset;
185 size_t size()
const {
186 return static_cast<size_t>(handles.count());
189 bool valid_handle(handle_t handle)
const {
190 auto pos =
static_cast<size_type
>(handle);
191 auto s = handles.size();
192 if (pos >= s)
return false;
193 return handles.test(pos);
204 auto pos = handles.find_first();
206 return iterator(
this, -1);
208 return iterator(
this,
static_cast<handle_t
>(pos));
211 const_iterator begin()
const {
212 auto pos = handles.find_first();
214 return const_iterator(
this, -1);
216 return const_iterator(
this,
static_cast<handle_t
>(pos));
220 return iterator(
this, -1);
223 const_iterator end()
const {
224 return const_iterator(
this, -1);
229 size_type first_unset{0};
234 #endif // BM_BM_SIM_HANDLE_MGR_H_