From a141c401f78467bc15f62882fca5d55a007cacbb Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Mon, 17 Feb 2025 00:21:48 +0100 Subject: Reorganize everything --- asl/types/box.hpp | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 asl/types/box.hpp (limited to 'asl/types/box.hpp') diff --git a/asl/types/box.hpp b/asl/types/box.hpp new file mode 100644 index 0000000..d8577ec --- /dev/null +++ b/asl/types/box.hpp @@ -0,0 +1,134 @@ +#pragma once + +#include "asl/base/assert.hpp" +#include "asl/base/annotations.hpp" +#include "asl/base/utility.hpp" +#include "asl/memory/memory.hpp" +#include "asl/memory/allocator.hpp" +#include "asl/hashing/hash.hpp" + +namespace asl +{ + +template +class box +{ + T* m_ptr; + ASL_NO_UNIQUE_ADDRESS Allocator m_alloc; + +public: + explicit constexpr box(niche_t) + requires default_constructible + : m_ptr{nullptr} + , m_alloc{} + {} + + constexpr box(T* ptr, Allocator alloc) + : m_ptr{ptr} + , m_alloc{ASL_MOVE(alloc)} + { + ASL_ASSERT(m_ptr != nullptr); + } + + constexpr box(box&& other) + : m_ptr{exchange(other.m_ptr, nullptr)} + , m_alloc{ASL_MOVE(other.m_alloc)} + {} + + template + requires convertible_from + constexpr box(box&& other) // NOLINT(*-explicit-conversions) + : 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) + { + destroy(m_ptr); + 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; + } + + constexpr bool operator==(niche_t) const + { + return m_ptr == nullptr; + } + + template + requires hashable + friend H AslHashValue(H h, const box& b) + { + return H::combine(ASL_MOVE(h), *b); + } + + template + friend constexpr U* leak(box&&); + + template + friend class box; +}; + +template +constexpr box make_box_in(Allocator allocator, Args&&... args) + requires constructible_from +{ + void* raw_ptr = allocator.alloc(layout::of()); + auto* ptr = construct_at(raw_ptr, 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()); + auto* ptr = construct_at(raw_ptr, ASL_FWD(args)...); + return box(ptr, ASL_MOVE(allocator)); +} + +template +constexpr T* leak(box&& b) +{ + return exchange(b.m_ptr, nullptr); +} + +} // namespace asl + -- cgit