fixed_typemap.hpp: static allocation for m_init

This allows to safely call is_init<T>() at any time.
This commit is contained in:
Ivan Chikish 2023-02-21 18:59:45 +03:00 committed by Ivan
parent a9f399d6cc
commit 01ed8a07af

View file

@ -168,15 +168,15 @@ namespace stx
mutable uchar m_data[Size ? Size : 1]; mutable uchar m_data[Size ? Size : 1];
}; };
// Indicates whether object is created at given index
std::array<bool, (Size ? Size / Align : 65536)> m_init{};
// Creation order for each object (used to reverse destruction order) // Creation order for each object (used to reverse destruction order)
void** m_order = nullptr; void** m_order = nullptr;
// Helper for destroying in reverse order // Helper for destroying in reverse order
const typeinfo** m_info = nullptr; const typeinfo** m_info = nullptr;
// Indicates whether object is created at given index
bool* m_init = nullptr;
public: public:
manual_typemap() noexcept = default; manual_typemap() noexcept = default;
@ -186,19 +186,19 @@ namespace stx
~manual_typemap() ~manual_typemap()
{ {
ensure(!m_init); ensure(!m_info);
} }
void reset() void reset()
{ {
if (m_init) if (is_init())
{ {
clear(); clear();
} }
m_order = new void*[stx::typelist<typeinfo>().count() + 1]; m_order = new void*[stx::typelist<typeinfo>().count() + 1];
m_info = new const typeinfo*[stx::typelist<typeinfo>().count() + 1]; m_info = new const typeinfo*[stx::typelist<typeinfo>().count() + 1];
m_init = new bool[stx::typelist<typeinfo>().count()]{}; ensure(m_init.size() > stx::typelist<typeinfo>().count());
if constexpr (Size == 0) if constexpr (Size == 0)
{ {
@ -269,7 +269,7 @@ namespace stx
void clear() void clear()
{ {
if (!m_init) if (!is_init())
{ {
return; return;
} }
@ -295,7 +295,6 @@ namespace stx
// Pointers should be restored to their positions // Pointers should be restored to their positions
m_info--; m_info--;
m_order--; m_order--;
delete[] m_init;
delete[] m_info; delete[] m_info;
delete[] m_order; delete[] m_order;
@ -311,7 +310,7 @@ namespace stx
} }
} }
m_init = nullptr; m_init.fill(false);
m_info = nullptr; m_info = nullptr;
m_order = nullptr; m_order = nullptr;
@ -323,7 +322,7 @@ namespace stx
void save(utils::serial& ar) void save(utils::serial& ar)
{ {
if (!m_init) if (!is_init())
{ {
return; return;
} }
@ -412,6 +411,11 @@ namespace stx
return m_init[stx::typeindex<typeinfo, std::decay_t<T>>()]; return m_init[stx::typeindex<typeinfo, std::decay_t<T>>()];
} }
bool is_init() const noexcept
{
return m_info != nullptr;
}
// Obtain object pointer (may be uninitialized memory) // Obtain object pointer (may be uninitialized memory)
template <typename T> template <typename T>
T& get() const noexcept T& get() const noexcept