From 46944ec98688e962e94dcfcf426215f252bf2a87 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Fri, 3 Jan 2025 12:13:34 +0100 Subject: Start work on status --- asl/allocator.hpp | 27 +++++++++++++++++ asl/integers.hpp | 2 ++ asl/status.cpp | 27 +++++++++++++++++ asl/status.hpp | 69 ++++++++++++++++++++++++++++++++++++++++++++ asl/tests/integers_tests.cpp | 2 ++ asl/tests/status_tests.cpp | 27 +++++++++++++++++ asl/utility.hpp | 8 +++++ 7 files changed, 162 insertions(+) (limited to 'asl') diff --git a/asl/allocator.hpp b/asl/allocator.hpp index 5f8f9b6..265378b 100644 --- a/asl/allocator.hpp +++ b/asl/allocator.hpp @@ -2,6 +2,7 @@ #include "asl/layout.hpp" #include "asl/meta.hpp" +#include "asl/memory.hpp" namespace asl { @@ -28,4 +29,30 @@ static_assert(allocator); using DefaultAllocator = GlobalHeap; +template +T* alloc_new(allocator auto& a, auto&&... args) +{ + void* ptr = a.alloc(layout::of()); + return construct_at(ptr, ASL_FWD(args)...); +} + +template +void alloc_delete(allocator auto& a, T* ptr) +{ + destroy(ptr); + a.dealloc(ptr, layout::of()); +} + +template +constexpr T* alloc_new_default(auto&&... args) +{ + return alloc_new(DefaultAllocator{}, ASL_FWD(args)...); +} + +template +void alloc_delete_default(T* ptr) +{ + alloc_delete(DefaultAllocator{}, ptr); +} + } // namespace asl diff --git a/asl/integers.hpp b/asl/integers.hpp index 65dadeb..5f6ad76 100644 --- a/asl/integers.hpp +++ b/asl/integers.hpp @@ -23,6 +23,8 @@ using uint32_t = unsigned int; using size_t = uint64_t; using isize_t = int64_t; +using uintptr_t = size_t; + namespace asl { diff --git a/asl/status.cpp b/asl/status.cpp index e69de29..ac0b29e 100644 --- a/asl/status.cpp +++ b/asl/status.cpp @@ -0,0 +1,27 @@ +#include "asl/status.hpp" +#include "asl/allocator.hpp" + +using Allocator = asl::DefaultAllocator; +static Allocator g_allocator{}; + +namespace +{ + +struct StatusInternal +{ + asl::string_view msg; + asl::status_code code; +}; + +} // anonymous namespace + +asl::status::status(status_code code, string_view msg) + : m_payload{alloc_new(g_allocator, msg, code)} +{} + +asl::status_code asl::status::code_internal() const +{ + ASL_ASSERT(m_payload && (bit_cast(m_payload) & 1) == 0); + return reinterpret_cast(m_payload)->code; +} + diff --git a/asl/status.hpp b/asl/status.hpp index 2e4bae5..4638493 100644 --- a/asl/status.hpp +++ b/asl/status.hpp @@ -6,8 +6,77 @@ namespace asl { +enum class status_code : uint8_t +{ + ok = 0, + unknown = 1, + internal = 2, + runtime = 3, + invalid_argument = 4, +}; + class status { + void* m_payload{}; + + static constexpr void* status_to_payload(status_code code) + { + return code == status_code::ok ? nullptr : bit_cast(((uintptr_t)code << 1) | 1); + } + + static constexpr status_code payload_to_status(void* payload) + { + return (status_code)(bit_cast(payload) >> 1); + } + + status_code code_internal() const; + +public: + constexpr status() = default; + + explicit constexpr status(status_code code) + : m_payload{status_to_payload(code)} + {} + + status(status_code code, string_view msg); + + constexpr status(status&& other) + : m_payload{exchange(other.m_payload, nullptr)} + {} + + constexpr status& operator=(status&& other) + { + if (&other != this) + { + swap(m_payload, other.m_payload); + } + return *this; + } + + // @Todo Copy constructor & assignment + + constexpr bool ok() const + { + return m_payload == nullptr || code() == status_code::ok; + } + + // NOLINTNEXTLINE(*-explicit-conversions) + constexpr operator bool() const { return ok(); } + + constexpr status_code code() const + { + if (m_payload == nullptr) + { + return status_code::ok; + } + + if ((bit_cast(m_payload) & 1) != 0) + { + return payload_to_status(m_payload); + } + + return code_internal(); + } }; } // namespace asl diff --git a/asl/tests/integers_tests.cpp b/asl/tests/integers_tests.cpp index fdfa0fc..cfc1200 100644 --- a/asl/tests/integers_tests.cpp +++ b/asl/tests/integers_tests.cpp @@ -11,3 +11,5 @@ static_assert(sizeof(uint32_t) == 4); static_assert(sizeof(uint64_t) == 8); static_assert(sizeof(asl::byte) == 1); + +static_assert(sizeof(uintptr_t) == sizeof(void*)); diff --git a/asl/tests/status_tests.cpp b/asl/tests/status_tests.cpp index e69de29..edfb65d 100644 --- a/asl/tests/status_tests.cpp +++ b/asl/tests/status_tests.cpp @@ -0,0 +1,27 @@ +#include "asl/status.hpp" +#include "asl/testing/testing.hpp" + +ASL_TEST(simple_ok) +{ + asl::status s; + ASL_TEST_ASSERT(s); + ASL_TEST_ASSERT(s.ok()); + ASL_TEST_ASSERT(s.code() == asl::status_code::ok); +} + +ASL_TEST(simple_code) +{ + asl::status s{asl::status_code::runtime}; + ASL_TEST_ASSERT(!s); + ASL_TEST_ASSERT(!s.ok()); + ASL_TEST_ASSERT(s.code() == asl::status_code::runtime); +} + +ASL_TEST(with_message) +{ + asl::status s{asl::status_code::internal, "We done goofed"}; + ASL_TEST_ASSERT(!s); + ASL_TEST_ASSERT(!s.ok()); + ASL_TEST_ASSERT(s.code() == asl::status_code::internal); + // @Todo test message +} diff --git a/asl/utility.hpp b/asl/utility.hpp index 2877447..69838e5 100644 --- a/asl/utility.hpp +++ b/asl/utility.hpp @@ -11,6 +11,14 @@ namespace asl { +template +constexpr void swap(T& a, T& b) +{ + T tmp{ASL_MOVE(a)}; + a = ASL_MOVE(b); + b = ASL_MOVE(tmp); +} + template T exchange(T& obj, U&& new_value) { -- cgit