From f5ef1937eafb3d96b3683d92639a193694210c70 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 19 Nov 2024 23:30:55 +0100 Subject: More work on asl::box --- asl/box.hpp | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'asl/box.hpp') diff --git a/asl/box.hpp b/asl/box.hpp index 0cab66b..d8ccd36 100644 --- a/asl/box.hpp +++ b/asl/box.hpp @@ -1,7 +1,10 @@ #pragma once #include "asl/allocator.hpp" +#include "asl/assert.hpp" #include "asl/annotations.hpp" +#include "asl/memory.hpp" +#include "asl/utility.hpp" namespace asl { @@ -13,7 +16,87 @@ class box ASL_NO_UNIQUE_ADDRESS Allocator m_alloc; public: + explicit constexpr box(T* ptr = nullptr) + requires default_constructible + : m_ptr{ptr} + {} + + constexpr box(T* ptr, Allocator alloc) + : m_ptr{ptr} + , m_alloc{ASL_MOVE(alloc)} + {} + + constexpr box(box&& other) + : m_ptr{exchange(other.m_ptr, nullptr)} + , m_alloc{ASL_MOVE(other.m_alloc)} + {} + + constexpr box& operator=(box&& other) + { + if (this == &other) { return *this; } + + if (m_ptr != nullptr) { reset(); } + + m_ptr = exchange(other.m_ptr, nullptr); + m_alloc = ASL_MOVE(other.m_alloc); + + return *this; + } + + box(const box&) = delete; + box& operator=(const box&) = delete; + + constexpr ~box() + { + reset(); + } + + constexpr void reset() + { + if (m_ptr != nullptr) + { + if constexpr (!trivially_destructible) + { + m_ptr->~T(); + } + m_alloc.dealloc(m_ptr, layout::of()); + m_ptr = nullptr; + } + } + + constexpr T* get() const { return m_ptr; } + + constexpr T& operator*() const + { + ASL_ASSERT(m_ptr != nullptr); + return *m_ptr; + } + + constexpr T* operator->() const + { + ASL_ASSERT(m_ptr != nullptr); + return m_ptr; + } }; +template +constexpr box make_box_in(Allocator allocator, Args&&... args) + requires constructible_from +{ + void* raw_ptr = allocator.alloc(layout::of()); + T* ptr = new (raw_ptr) T(ASL_FWD(args)...); + return box(ptr, ASL_MOVE(allocator)); +} + +template +constexpr box make_box(Args&&... args) + requires default_constructible && constructible_from +{ + Allocator allocator{}; + void* raw_ptr = allocator.alloc(layout::of()); + T* ptr = new (raw_ptr) T{ ASL_FWD(args)... }; + return box(ptr, ASL_MOVE(allocator)); +} + } // namespace asl -- cgit