I'm creating a generic AtomManager<T>
container that can store Atom<T>
objects.
enum State { Alive, Dead, Unused };
template<class T> struct Atom
{
T impl;
int index, counter;
State state;
};
I want impl
not to be on the heap, as I will store Atom<T>
instances contiguously in the manager.
AtomManager<T>
stores atoms in an std::vector<Atom<T>>
like this:
| A | A | A | A | A | A | U | U | U | U |
Where A
means alive, and U
means unused. When the user calls AtomManager<T>::refresh()
, all atoms with state
equal to State::Dead
will be moved at the end of the storage, and then they will be set to State::Unused
. Example:
| A | A | A | A | A | A | U | U | U | U |
// some atoms die
| A | D | A | D | A | A | U | U | U | U |
// user calls refresh()
| A | A | A | A | U | U | U | U | D | D |
// after refresh()
| A | A | A | A | U | U | U | U | U | U |
To create atoms, I have a function that matches the T
constructor signature thanks to variadic templates and constructs a T
in the first unused atom starting from the beginning of the storage.
The problem is that T
has to be default-constructible (because I call resize()
on the std::vector
). But that's something I don't require, as I only care about Atom<T>::impl
when the state is either State::Alive
or State::Dead
. And if the atom is alive or dead, it means that the user previously constructed it using the previously mentioned variadic function.
I do, however, care about Atom<T>::index
and Atom<T>::counter
when the atom is unused (and Atom<T>::impl
is garbage).
I do not care about the state of Atom<T>::impl
when the atom is unused.
The compiler, however, does. I cannot use AtomManager<T>
when T
is not default-constructible.
I tried using an union inside Atom<T>
:
union { T impl; char dummy; };
...but I couldn't get it to work properly.
How can I store a T
non-constructed uninitialized instance inside Atom<T>
?
I do not care about its state. I'm sure I will construct it properly before accessing it. But when the atom is unused, I want it to be in an undefined state.
What's the best way of achieving this? I don't want Atom<T>::impl
to be stored on the heap.
I don't want to introduce additional dependencies. I don't need to query the state of Atom<T>::impl
as I know when it's safe to access it.