summaryrefslogtreecommitdiff
path: root/asl
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2025-01-03 12:13:34 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2025-01-03 12:13:34 +0100
commit46944ec98688e962e94dcfcf426215f252bf2a87 (patch)
tree1fb08cbc3cd3dedfe8940dbebe8eb1bf5089ac21 /asl
parentc2d4216695b48dfe6bf7083c11e0a7fcbb671e2e (diff)
Start work on status
Diffstat (limited to 'asl')
-rw-r--r--asl/allocator.hpp27
-rw-r--r--asl/integers.hpp2
-rw-r--r--asl/status.cpp27
-rw-r--r--asl/status.hpp69
-rw-r--r--asl/tests/integers_tests.cpp2
-rw-r--r--asl/tests/status_tests.cpp27
-rw-r--r--asl/utility.hpp8
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)
{