From def67bba57e7cfdf9942bc2c88a4ce484963f9d2 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Fri, 6 Sep 2024 23:22:18 +0200 Subject: maybe_uninit --- asl/maybe_uninit.hpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 asl/maybe_uninit.hpp (limited to 'asl/maybe_uninit.hpp') diff --git a/asl/maybe_uninit.hpp b/asl/maybe_uninit.hpp new file mode 100644 index 0000000..ffbbb1c --- /dev/null +++ b/asl/maybe_uninit.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "asl/annotations.hpp" +#include "asl/layout.hpp" +#include "asl/memory.hpp" +#include "asl/meta.hpp" + +namespace asl +{ + +template +class alignas(align_of) maybe_uninit +{ + char m_storage[size_of]; + +public: + constexpr void* uninit_ptr() const { return m_storage; } + + // @Safety Pointer must only be accessed when in initialized state. + constexpr const T* init_ptr(unsafe) const { return reinterpret_cast(m_storage); } + constexpr T* init_ptr(unsafe) { return reinterpret_cast< T*>(m_storage); } + + // @Safety Reference must only be accessed when in initialized state. + constexpr const T& as_init(unsafe) const { return *reinterpret_cast(m_storage); } + constexpr T& as_init(unsafe) { return *reinterpret_cast< T*>(m_storage); } + + // @Safety Must be called only when in uninitialized state. + template + inline void init(unsafe, Args&&... args) + { + new(uninit_ptr()) T(ASL_FWD(args)...); + } + + // @Safety Must be called only when in initialized state. + inline void uninit(unsafe) + { + if constexpr (!trivially_destructible) + { + init_ptr(unsafe("Caller has checked init state"))->~T(); + } + } +}; + +} // namespace asl -- cgit