From 8607772d4f9e21f53c1abfd9379737403b97f430 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sun, 5 Jan 2025 15:25:45 +0100 Subject: Fix a few mistakes in option, and make it trivial when possible --- asl/maybe_uninit.hpp | 82 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 35 deletions(-) (limited to 'asl/maybe_uninit.hpp') diff --git a/asl/maybe_uninit.hpp b/asl/maybe_uninit.hpp index e59cfe0..4f60e4d 100644 --- a/asl/maybe_uninit.hpp +++ b/asl/maybe_uninit.hpp @@ -1,60 +1,72 @@ #pragma once -#include "asl/layout.hpp" -#include "asl/memory.hpp" #include "asl/meta.hpp" #include "asl/utility.hpp" +#include "asl/memory.hpp" namespace asl { template -class maybe_uninit +union maybe_uninit { - union - { - alignas(align_of) char m_storage[size_of]; - T m_value; - }; +private: + T m_value; public: - constexpr maybe_uninit() {} // NOLINT(*-member-init) + constexpr maybe_uninit() requires trivially_default_constructible = default; + constexpr maybe_uninit() requires (!trivially_default_constructible) {} // NOLINT - maybe_uninit(const maybe_uninit&) = delete; - maybe_uninit(maybe_uninit&&) = delete; - - maybe_uninit& operator=(const maybe_uninit&) = delete; - maybe_uninit& operator=(maybe_uninit&&) = delete; + template + explicit constexpr maybe_uninit(in_place_t, Args&&... args) + requires constructible_from + : m_value{ASL_FWD(args)...} + {} - constexpr ~maybe_uninit() = default; - constexpr ~maybe_uninit() requires (!trivially_destructible) {} + constexpr maybe_uninit(const maybe_uninit&) requires trivially_copy_constructible = default; + constexpr maybe_uninit(const maybe_uninit&) requires (!trivially_copy_constructible) {} // NOLINT - constexpr void* uninit_ptr() && = delete; - constexpr const void* uninit_ptr() const& { return m_storage; } - constexpr void* uninit_ptr() & { return m_storage; } - - // @Safety Pointer must only be accessed when in initialized state. - constexpr T* init_ptr_unsafe() && = delete; - constexpr const T* init_ptr_unsafe() const& { return &m_value; } - constexpr T* init_ptr_unsafe() & { return &m_value; } - - // @Safety Reference must only be accessed when in initialized state. - constexpr T&& as_init_unsafe() && { return ASL_MOVE(m_value); } - constexpr const T& as_init_unsafe() const& { return m_value; } - constexpr T& as_init_unsafe() & { return m_value; } + constexpr maybe_uninit(maybe_uninit&&) requires trivially_move_constructible = default; + constexpr maybe_uninit(maybe_uninit&&) requires (!trivially_move_constructible) {} // NOLINT + + constexpr maybe_uninit& operator=(const maybe_uninit&) requires trivially_copy_assignable = default; + constexpr maybe_uninit& operator=(const maybe_uninit&) requires (!trivially_copy_assignable) {} + + constexpr maybe_uninit& operator=(maybe_uninit&&) requires trivially_move_assignable = default; + constexpr maybe_uninit& operator=(maybe_uninit&&) requires (!trivially_move_assignable) {} + + constexpr ~maybe_uninit() requires trivially_destructible = default; + constexpr ~maybe_uninit() requires (!trivially_destructible) {} // NOLINT - // @Safety Must be called only when in uninitialized state. + // @Safety Value must not have been initialized yet template - constexpr void init_unsafe(Args&&... args) & + constexpr void construct_unsafe(Args&&... args) + requires constructible_from { - construct_at(uninit_ptr(), ASL_FWD(args)...); + construct_at(&m_value, ASL_FWD(args)...); } - // @Safety Must be called only when in initialized state. - constexpr void uninit_unsafe() & + // @Safety Value must have been initialized + template + constexpr void assign_unsafe(U&& value) + requires assignable_from { - destroy(init_ptr_unsafe()); + m_value = ASL_FWD(value); } + + // @Safety Value must have been initialized + constexpr void destroy_unsafe() + { + if constexpr (!trivially_destructible) + { + destroy(&m_value); + } + } + + // @Safety Value must have been initialized + constexpr const T& as_init_unsafe() const& { return m_value; } + constexpr T& as_init_unsafe() & { return m_value; } + constexpr T&& as_init_unsafe() && { return ASL_MOVE(m_value); } }; } // namespace asl -- cgit