diff --git a/furvm/include/furvm/thing.hpp b/furvm/include/furvm/thing.hpp index f0a916e..3b3247a 100644 --- a/furvm/include/furvm/thing.hpp +++ b/furvm/include/furvm/thing.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -73,7 +74,9 @@ public: m_data = m_allocator.allocate(thing_type_size(type)); } - ~thing() { m_allocator.deallocate(m_data, thing_type_size(thing_t::Int32)); } + ~thing() { + if (m_data != nullptr) m_allocator.deallocate(m_data, thing_type_size(thing_t::Int32)); + } /** * @brief Move constructor. @@ -203,7 +206,7 @@ public: } private: thing_t m_type{}; - std::byte* m_data = nullptr; + std::byte* m_data; allocator_type m_allocator; }; @@ -212,11 +215,13 @@ template class thing_allocator { template friend class thing_allocator; + + using dead_things = std::vector>; public: using value_type = T; public: explicit thing_allocator(furlang::arena& arena) noexcept - : m_arena(&arena) {} + : m_arena(&arena), m_deadThings(std::make_shared()) {} template thing_allocator(const thing_allocator& other) noexcept @@ -232,18 +237,26 @@ public: template thing_allocator(thing_allocator&& other) noexcept - : m_arena(std::move(other.m_arena)) {} + : m_arena(std::move(other.m_arena)), m_deadThings(std::move(other.m_deadThings)) {} template thing_allocator& operator=(thing_allocator&& other) noexcept { if (this == &other) return *this; - m_arena = std::move(other.m_arena); + m_arena = std::move(other.m_arena); + m_deadThings = std::move(other.m_deadThings); return *this; } public: - [[nodiscard]] T* allocate(std::size_t count = 1) { return m_arena->allocate(count); } + [[nodiscard]] T* allocate(std::size_t count = 1) { + for (auto it = m_deadThings->begin(); it != m_deadThings->end(); ++it) { + if (it->second != count) continue; + m_deadThings->erase(it); + return it->first; + } + return m_arena->allocate(count); + } - void deallocate(T* ptr, std::size_t count) noexcept { m_deadThings.emplace_back(ptr, count); } + void deallocate(T* ptr, std::size_t count) noexcept { m_deadThings->emplace_back(ptr, count); } public: template bool operator==(const thing_allocator& other) const noexcept { @@ -257,7 +270,7 @@ public: private: furlang::arena* m_arena; - std::vector> m_deadThings; + std::shared_ptr m_deadThings; }; } // namespace furvm