More work on asl::box
This commit is contained in:
14
MODULE.bazel.lock
generated
14
MODULE.bazel.lock
generated
@ -64,20 +64,20 @@
|
|||||||
"@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": {
|
"@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": {
|
||||||
"general": {
|
"general": {
|
||||||
"bzlTransitiveDigest": "PjIds3feoYE8SGbbIq2SFTZy3zmxeO2tQevJZNDo7iY=",
|
"bzlTransitiveDigest": "PjIds3feoYE8SGbbIq2SFTZy3zmxeO2tQevJZNDo7iY=",
|
||||||
"usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=",
|
"usagesDigest": "+hz7IHWN6A1oVJJWNDB6yZRG+RYhF76wAYItpAeIUIg=",
|
||||||
"recordedFileInputs": {},
|
"recordedFileInputs": {},
|
||||||
"recordedDirentsInputs": {},
|
"recordedDirentsInputs": {},
|
||||||
"envVariables": {},
|
"envVariables": {},
|
||||||
"generatedRepoSpecs": {
|
"generatedRepoSpecs": {
|
||||||
"local_config_apple_cc": {
|
|
||||||
"bzlFile": "@@apple_support~//crosstool:setup.bzl",
|
|
||||||
"ruleClassName": "_apple_cc_autoconf",
|
|
||||||
"attributes": {}
|
|
||||||
},
|
|
||||||
"local_config_apple_cc_toolchains": {
|
"local_config_apple_cc_toolchains": {
|
||||||
"bzlFile": "@@apple_support~//crosstool:setup.bzl",
|
"bzlFile": "@@apple_support~//crosstool:setup.bzl",
|
||||||
"ruleClassName": "_apple_cc_autoconf_toolchains",
|
"ruleClassName": "_apple_cc_autoconf_toolchains",
|
||||||
"attributes": {}
|
"attributes": {}
|
||||||
|
},
|
||||||
|
"local_config_apple_cc": {
|
||||||
|
"bzlFile": "@@apple_support~//crosstool:setup.bzl",
|
||||||
|
"ruleClassName": "_apple_cc_autoconf",
|
||||||
|
"attributes": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"recordedRepoMappingEntries": [
|
"recordedRepoMappingEntries": [
|
||||||
@ -92,7 +92,7 @@
|
|||||||
"@@platforms//host:extension.bzl%host_platform": {
|
"@@platforms//host:extension.bzl%host_platform": {
|
||||||
"general": {
|
"general": {
|
||||||
"bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=",
|
"bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=",
|
||||||
"usagesDigest": "meSzxn3DUCcYEhq4HQwExWkWtU4EjriRBQLsZN+Q0SU=",
|
"usagesDigest": "pCYpDQmqMbmiiPI1p2Kd3VLm5T48rRAht5WdW0X2GlA=",
|
||||||
"recordedFileInputs": {},
|
"recordedFileInputs": {},
|
||||||
"recordedDirentsInputs": {},
|
"recordedDirentsInputs": {},
|
||||||
"envVariables": {},
|
"envVariables": {},
|
||||||
|
@ -26,6 +26,11 @@ void* asl::GlobalHeap::alloc(const layout& layout)
|
|||||||
|
|
||||||
void* asl::GlobalHeap::realloc(void* old_ptr, const layout& old_layout, const layout& new_layout)
|
void* asl::GlobalHeap::realloc(void* old_ptr, const layout& old_layout, const layout& new_layout)
|
||||||
{
|
{
|
||||||
|
#if ASL_OS_WINDOWS
|
||||||
|
return ::_aligned_realloc(old_ptr,
|
||||||
|
static_cast<size_t>(new_layout.size),
|
||||||
|
static_cast<size_t>(new_layout.align));
|
||||||
|
#elif ASL_OS_LINUX
|
||||||
if (new_layout.align <= old_layout.align)
|
if (new_layout.align <= old_layout.align)
|
||||||
{
|
{
|
||||||
void* new_ptr = ::realloc(old_ptr, static_cast<size_t>(new_layout.size));
|
void* new_ptr = ::realloc(old_ptr, static_cast<size_t>(new_layout.size));
|
||||||
@ -36,9 +41,14 @@ void* asl::GlobalHeap::realloc(void* old_ptr, const layout& old_layout, const la
|
|||||||
void* new_ptr = alloc(new_layout);
|
void* new_ptr = alloc(new_layout);
|
||||||
asl::memcpy(new_ptr, old_ptr, asl::min(old_layout.size, new_layout.size));
|
asl::memcpy(new_ptr, old_ptr, asl::min(old_layout.size, new_layout.size));
|
||||||
return new_ptr;
|
return new_ptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void asl::GlobalHeap::dealloc(void* ptr, const layout&)
|
void asl::GlobalHeap::dealloc(void* ptr, const layout&)
|
||||||
{
|
{
|
||||||
|
#if ASL_OS_WINDOWS
|
||||||
|
::_aligned_free(ptr);
|
||||||
|
#elif ASL_OS_LINUX
|
||||||
::free(ptr);
|
::free(ptr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,13 @@ namespace asl
|
|||||||
{
|
{
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept allocator = requires(T& alloc, layout layout, void* ptr)
|
concept allocator = moveable<T> &&
|
||||||
{
|
requires(T& alloc, layout layout, void* ptr)
|
||||||
{ alloc.alloc(layout) } -> same_as<void*>;
|
{
|
||||||
{ alloc.realloc(ptr, layout, layout) } -> same_as<void*>;
|
{ alloc.alloc(layout) } -> same_as<void*>;
|
||||||
alloc.dealloc(ptr, layout);
|
{ alloc.realloc(ptr, layout, layout) } -> same_as<void*>;
|
||||||
};
|
alloc.dealloc(ptr, layout);
|
||||||
|
};
|
||||||
|
|
||||||
class GlobalHeap
|
class GlobalHeap
|
||||||
{
|
{
|
||||||
|
83
asl/box.hpp
83
asl/box.hpp
@ -1,7 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "asl/allocator.hpp"
|
#include "asl/allocator.hpp"
|
||||||
|
#include "asl/assert.hpp"
|
||||||
#include "asl/annotations.hpp"
|
#include "asl/annotations.hpp"
|
||||||
|
#include "asl/memory.hpp"
|
||||||
|
#include "asl/utility.hpp"
|
||||||
|
|
||||||
namespace asl
|
namespace asl
|
||||||
{
|
{
|
||||||
@ -13,7 +16,87 @@ class box
|
|||||||
ASL_NO_UNIQUE_ADDRESS Allocator m_alloc;
|
ASL_NO_UNIQUE_ADDRESS Allocator m_alloc;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
explicit constexpr box(T* ptr = nullptr)
|
||||||
|
requires default_constructible<Allocator>
|
||||||
|
: 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<T>)
|
||||||
|
{
|
||||||
|
m_ptr->~T();
|
||||||
|
}
|
||||||
|
m_alloc.dealloc(m_ptr, layout::of<T>());
|
||||||
|
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<is_object T, allocator Allocator = DefaultAllocator, typename... Args>
|
||||||
|
constexpr box<T, Allocator> make_box_in(Allocator allocator, Args&&... args)
|
||||||
|
requires constructible_from<T, Args&&...>
|
||||||
|
{
|
||||||
|
void* raw_ptr = allocator.alloc(layout::of<T>());
|
||||||
|
T* ptr = new (raw_ptr) T(ASL_FWD(args)...);
|
||||||
|
return box(ptr, ASL_MOVE(allocator));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<is_object T, allocator Allocator = DefaultAllocator, typename... Args>
|
||||||
|
constexpr box<T, Allocator> make_box(Args&&... args)
|
||||||
|
requires default_constructible<Allocator> && constructible_from<T, Args&&...>
|
||||||
|
{
|
||||||
|
Allocator allocator{};
|
||||||
|
void* raw_ptr = allocator.alloc(layout::of<T>());
|
||||||
|
T* ptr = new (raw_ptr) T{ ASL_FWD(args)... };
|
||||||
|
return box<T>(ptr, ASL_MOVE(allocator));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace asl
|
} // namespace asl
|
||||||
|
|
||||||
|
@ -69,6 +69,9 @@ template<typename T> concept trivially_destructible = __is_trivially_destructibl
|
|||||||
|
|
||||||
template<typename T> concept trivially_copyable = __is_trivially_copyable(T);
|
template<typename T> concept trivially_copyable = __is_trivially_copyable(T);
|
||||||
|
|
||||||
|
template<typename T> concept copyable = copy_constructible<T> && copy_assignable<T>;
|
||||||
|
template<typename T> concept moveable = move_constructible<T> && move_assignable<T>;
|
||||||
|
|
||||||
template<typename To, typename From>
|
template<typename To, typename From>
|
||||||
concept convertible_from = __is_convertible(From, To);
|
concept convertible_from = __is_convertible(From, To);
|
||||||
|
|
||||||
|
@ -1,6 +1,62 @@
|
|||||||
#include "asl/box.hpp"
|
#include "asl/box.hpp"
|
||||||
|
|
||||||
#include "asl/testing/testing.hpp"
|
#include "asl/testing/testing.hpp"
|
||||||
|
#include "asl/tests/test_types.hpp"
|
||||||
|
|
||||||
static_assert(sizeof(asl::box<int>) == sizeof(int*));
|
static_assert(sizeof(asl::box<int>) == sizeof(int*));
|
||||||
|
static_assert(asl::default_constructible<asl::box<int>>);
|
||||||
|
static_assert(!asl::copyable<asl::box<int>>);
|
||||||
|
static_assert(asl::moveable<asl::box<int>>);
|
||||||
|
static_assert(asl::default_constructible<asl::box<NonMoveConstructible>>);
|
||||||
|
|
||||||
|
ASL_TEST(destructor)
|
||||||
|
{
|
||||||
|
bool d = false;
|
||||||
|
|
||||||
|
{
|
||||||
|
asl::box<DestructorObserver> box2;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto box = asl::make_box<DestructorObserver>(&d);
|
||||||
|
ASL_TEST_ASSERT(!d);
|
||||||
|
|
||||||
|
|
||||||
|
auto box3 = ASL_MOVE(box);
|
||||||
|
ASL_TEST_ASSERT(!d);
|
||||||
|
|
||||||
|
box2 = ASL_MOVE(box3);
|
||||||
|
ASL_TEST_ASSERT(!d);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASL_TEST_ASSERT(!d);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASL_TEST_ASSERT(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASL_TEST(value)
|
||||||
|
{
|
||||||
|
auto b = asl::make_box<int>(24);
|
||||||
|
ASL_TEST_EXPECT(*b == 24);
|
||||||
|
|
||||||
|
auto b2 = ASL_MOVE(b);
|
||||||
|
ASL_TEST_EXPECT(*b2 == 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASL_TEST(ptr)
|
||||||
|
{
|
||||||
|
auto b = asl::make_box<int>(24);
|
||||||
|
auto* ptr1 = b.get();
|
||||||
|
|
||||||
|
auto b2 = ASL_MOVE(b);
|
||||||
|
auto* ptr2 = b2.get();
|
||||||
|
ASL_TEST_EXPECT(ptr1 == ptr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Struct { int a; };
|
||||||
|
|
||||||
|
ASL_TEST(arrow)
|
||||||
|
{
|
||||||
|
auto b = asl::make_box<Struct>(45);
|
||||||
|
ASL_TEST_EXPECT(b->a == 45);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user