100 lines
1.8 KiB
C++
100 lines
1.8 KiB
C++
#pragma once
|
|
|
|
// system includes
|
|
#include <cassert>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
// local includes
|
|
#include "esputils.h"
|
|
|
|
namespace espcpputils {
|
|
template<typename T>
|
|
class DelayedConstruction
|
|
{
|
|
ESP_DISABLE_COPY_MOVE(DelayedConstruction)
|
|
|
|
public:
|
|
DelayedConstruction() = default;
|
|
~DelayedConstruction()
|
|
{
|
|
if (m_constructed)
|
|
destruct();
|
|
}
|
|
|
|
template<typename ...Targs>
|
|
void construct(Targs &&...args)
|
|
{
|
|
assert(!m_constructed);
|
|
new (&helper.value) T {std::forward<Targs>(args)...};
|
|
m_constructed = true;
|
|
}
|
|
|
|
void destruct()
|
|
{
|
|
assert(m_constructed);
|
|
helper.value.~T();
|
|
m_constructed = false;
|
|
}
|
|
|
|
T &get()
|
|
{
|
|
assert(m_constructed);
|
|
return helper.value;
|
|
}
|
|
|
|
const T &get() const
|
|
{
|
|
assert(m_constructed);
|
|
return helper.value;
|
|
}
|
|
|
|
T *operator->()
|
|
{
|
|
assert(m_constructed);
|
|
return &helper.value;
|
|
}
|
|
|
|
const T *operator->() const
|
|
{
|
|
assert(m_constructed);
|
|
return &helper.value;
|
|
}
|
|
|
|
T &operator*()
|
|
{
|
|
assert(m_constructed);
|
|
return helper.value;
|
|
}
|
|
|
|
const T &operator*() const
|
|
{
|
|
assert(m_constructed);
|
|
return helper.value;
|
|
}
|
|
|
|
//! allows for getting the address before the object has been constructed
|
|
T &getUnsafe()
|
|
{
|
|
return helper.value;
|
|
}
|
|
|
|
//! allows for getting the address before the object has been constructed
|
|
const T &getUnsafe() const
|
|
{
|
|
return helper.value;
|
|
}
|
|
|
|
bool constructed() const { return m_constructed; }
|
|
|
|
private:
|
|
bool m_constructed{};
|
|
union Helper
|
|
{
|
|
Helper() {}
|
|
~Helper() {}
|
|
T value;
|
|
} helper;
|
|
};
|
|
} // namespace espcpputils
|