diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-01-03 12:13:34 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-01-03 12:13:34 +0100 |
commit | 46944ec98688e962e94dcfcf426215f252bf2a87 (patch) | |
tree | 1fb08cbc3cd3dedfe8940dbebe8eb1bf5089ac21 /asl | |
parent | c2d4216695b48dfe6bf7083c11e0a7fcbb671e2e (diff) |
Start work on status
Diffstat (limited to 'asl')
-rw-r--r-- | asl/allocator.hpp | 27 | ||||
-rw-r--r-- | asl/integers.hpp | 2 | ||||
-rw-r--r-- | asl/status.cpp | 27 | ||||
-rw-r--r-- | asl/status.hpp | 69 | ||||
-rw-r--r-- | asl/tests/integers_tests.cpp | 2 | ||||
-rw-r--r-- | asl/tests/status_tests.cpp | 27 | ||||
-rw-r--r-- | asl/utility.hpp | 8 |
7 files changed, 162 insertions, 0 deletions
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<GlobalHeap>); using DefaultAllocator = GlobalHeap;
+template<typename T>
+T* alloc_new(allocator auto& a, auto&&... args)
+{
+ void* ptr = a.alloc(layout::of<T>());
+ return construct_at<T>(ptr, ASL_FWD(args)...);
+}
+
+template<typename T>
+void alloc_delete(allocator auto& a, T* ptr)
+{
+ destroy(ptr);
+ a.dealloc(ptr, layout::of<T>());
+}
+
+template<typename T>
+constexpr T* alloc_new_default(auto&&... args)
+{
+ return alloc_new<T>(DefaultAllocator{}, ASL_FWD(args)...);
+}
+
+template<typename T>
+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<StatusInternal>(g_allocator, msg, code)} +{} + +asl::status_code asl::status::code_internal() const +{ + ASL_ASSERT(m_payload && (bit_cast<uintptr_t>(m_payload) & 1) == 0); + return reinterpret_cast<const StatusInternal*>(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<void*>(((uintptr_t)code << 1) | 1); + } + + static constexpr status_code payload_to_status(void* payload) + { + return (status_code)(bit_cast<uintptr_t>(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<uintptr_t>(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<moveable T>
+constexpr void swap(T& a, T& b)
+{
+ T tmp{ASL_MOVE(a)};
+ a = ASL_MOVE(b);
+ b = ASL_MOVE(tmp);
+}
+
template<typename T, typename U>
T exchange(T& obj, U&& new_value)
{
|