35 ilist_item& operator=(
const ilist_item& other) {
36 GAIA_ASSERT(core::addressof(other) !=
this);
42 ilist_item(ilist_item&& other) {
46 other.idx = (uint32_t)-1;
47 other.data.gen = (uint32_t)-1;
49 ilist_item& operator=(ilist_item&& other) {
50 GAIA_ASSERT(core::addressof(other) !=
this);
54 other.idx = (uint32_t)-1;
55 other.data.gen = (uint32_t)-1;
77 using internal_storage = TInternalStorage;
79 using value_type = TListItem;
80 using reference = TListItem&;
81 using const_reference =
const TListItem&;
82 using pointer = TListItem*;
83 using const_pointer =
const TListItem*;
84 using difference_type =
typename internal_storage::difference_type;
85 using size_type =
typename internal_storage::size_type;
88 using iterator =
typename internal_storage::iterator;
89 using const_iterator =
typename internal_storage::const_iterator;
90 using iterator_category =
typename internal_storage::iterator_category;
92 static_assert(std::is_base_of<ilist_item_base, TListItem>::value);
100 GAIA_NODISCARD pointer data() noexcept {
101 return reinterpret_cast<pointer
>(
m_items.data());
104 GAIA_NODISCARD const_pointer data() const noexcept {
105 return reinterpret_cast<const_pointer
>(
m_items.data());
108 GAIA_NODISCARD reference operator[](size_type index) {
111 GAIA_NODISCARD const_reference operator[](size_type index)
const {
121 GAIA_NODISCARD size_type get_next_free_item() const noexcept {
125 GAIA_NODISCARD size_type get_free_items() const noexcept {
129 GAIA_NODISCARD size_type item_count() const noexcept {
133 GAIA_NODISCARD size_type size() const noexcept {
134 return (size_type)
m_items.size();
137 GAIA_NODISCARD
bool empty() const noexcept {
141 GAIA_NODISCARD size_type capacity() const noexcept {
142 return (size_type)
m_items.capacity();
145 GAIA_NODISCARD iterator begin() noexcept {
149 GAIA_NODISCARD const_iterator begin() const noexcept {
153 GAIA_NODISCARD const_iterator cbegin() const noexcept {
157 GAIA_NODISCARD iterator end() noexcept {
161 GAIA_NODISCARD const_iterator end() const noexcept {
165 GAIA_NODISCARD const_iterator cend() const noexcept {
169 void reserve(size_type cap) {
175 GAIA_NODISCARD TItemHandle
alloc(
void* ctx) {
178 const auto itemCnt = (size_type)
m_items.size();
179 GAIA_ASSERT(itemCnt < TItemHandle::IdMask &&
"Trying to allocate too many items!");
181 GAIA_GCC_WARNING_PUSH()
182 GAIA_CLANG_WARNING_PUSH()
183 GAIA_GCC_WARNING_DISABLE(
"-Wstringop-overflow");
184 GAIA_GCC_WARNING_DISABLE(
"-Wmissing-field-initializers");
185 GAIA_CLANG_WARNING_DISABLE(
"-Wmissing-field-initializers");
186 m_items.add_item(TListItem::create(itemCnt, 0U, ctx));
187 return TListItem::handle(
m_items.back());
188 GAIA_GCC_WARNING_POP()
189 GAIA_CLANG_WARNING_POP()
199 j = TListItem::create(index, j.data.gen, ctx);
200 return TListItem::handle(j);
205 GAIA_NODISCARD TItemHandle
alloc() {
208 const auto itemCnt = (size_type)
m_items.size();
209 GAIA_ASSERT(itemCnt < TItemHandle::IdMask &&
"Trying to allocate too many items!");
211 GAIA_GCC_WARNING_PUSH()
212 GAIA_CLANG_WARNING_PUSH()
213 GAIA_GCC_WARNING_DISABLE(
"-Wstringop-overflow");
214 GAIA_GCC_WARNING_DISABLE(
"-Wmissing-field-initializers");
215 GAIA_CLANG_WARNING_DISABLE(
"-Wmissing-field-initializers");
216 m_items.add_item(TListItem(itemCnt, 0U));
217 return {itemCnt, 0U};
218 GAIA_GCC_WARNING_POP()
219 GAIA_CLANG_WARNING_POP()
229 return {index,
m_items[index].data.gen};
235 TListItem&
free(TItemHandle handle) {
236 auto& item =
m_items[handle.id()];
241 item.idx = TItemHandle::IdMask;
255 if (!hasThingsToRemove)
263 while (freeItems > 0) {
264 GAIA_ASSERT(nextFreeItem <
m_items.size() &&
"Item recycle list broken!");
266 nextFreeItem =
m_items[nextFreeItem].idx;
272 GAIA_ASSERT(nextFreeItem == TItemHandle::IdMask);