Skip to content

Instantly share code, notes, and snippets.

@W4RH4WK
Created January 7, 2025 21:42
Show Gist options
  • Save W4RH4WK/079515bb7b54b6068490d16c9ae31b12 to your computer and use it in GitHub Desktop.
Save W4RH4WK/079515bb7b54b6068490d16c9ae31b12 to your computer and use it in GitHub Desktop.
// The UnmanagedStorage wrapper is used to disable dynamic initialization and
// destructor calls for global variables. The wrapped object is stored inline
// and needs to be created and destroyed manually.
template <typename T>
class UnmanagedStorage {
public:
template <typename... Args>
T* emplace(Args&&... args) noexcept
{
reset();
new (m_instance) T(std::forward<Args>(args)...);
m_hasInstance = true;
return get();
}
void reset() noexcept
{
if (m_hasInstance) {
m_hasInstance = false;
get()->~T();
}
}
T* get() noexcept
{
if (!m_hasInstance) [[unlikely]] {
return nullptr;
}
return reinterpret_cast<T*>(&m_instance);
}
const T* get() const noexcept { const_cast<UnmanagedStorage<T>*>(this)->get(); }
T* operator->() noexcept { return get(); }
const T* operator->() const noexcept { return get(); }
explicit operator bool() const { return m_hasInstance; }
private:
bool m_hasInstance = false;
alignas(T) uint8_t m_instance[sizeof(T)] = {};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment