From 8db26a7350aad53ed73a127f9b8eb6ef15bf0be1 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Thu, 11 Apr 2024 23:49:22 +0200 Subject: Implement Status --- deimos/core/status.h | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 deimos/core/status.h (limited to 'deimos/core/status.h') diff --git a/deimos/core/status.h b/deimos/core/status.h new file mode 100644 index 0000000..f866182 --- /dev/null +++ b/deimos/core/status.h @@ -0,0 +1,111 @@ +#pragma once + +#include "deimos/core/base.h" + +namespace deimos +{ + +enum class StatusCode : uint32_t +{ + kOk = 0, + kUnknown, + kInvalidArgument, + kUnimplemented, + kInternal, +}; + +struct StatusRep +{ + // @Todo Make this atomic + int32_t ref_count{}; + StatusCode code{}; + StringView message; +}; + +class Status +{ + uintptr_t m_rep; + + constexpr bool IsInline() const + { + return (m_rep & 1U) == 1U; + } + + static constexpr uintptr_t CodeToRep(StatusCode code) + { + return ((uint32_t)code << 1U) | 1U; + } + + void Ref() const; + void Unref() const; + +public: + constexpr Status() : Status(StatusCode::kOk) {} + constexpr explicit Status(StatusCode code) : m_rep{CodeToRep(code)} {} + Status(StatusCode code, StringView message); + + Status(const Status& other) : m_rep{other.m_rep} + { + Ref(); + } + + Status(Status&& other) : m_rep{std::exchange(other.m_rep, 0U)} {} + + Status& operator=(const Status& other) + { + if (this != &other) + { + Unref(); + this->m_rep = other.m_rep; + Ref(); + } + return *this; + } + + Status& operator=(Status&& other) + { + if (this != &other) + { + Unref(); + this->m_rep = std::exchange(other.m_rep, 0U); + + } + return *this; + } + + ~Status() + { + Unref(); + } + + constexpr bool ok() const { return m_rep == CodeToRep(StatusCode::kOk); } + + StatusCode code() const + { + if (IsInline()) { return (StatusCode)(m_rep >> 1U); } + return std::bit_cast(m_rep)->code; + } +}; + +inline Status UnknownError(StringView message = {}) +{ + return Status(StatusCode::kUnknown, message); +} + +inline Status InvalidArgumentError(StringView message = {}) +{ + return Status(StatusCode::kInvalidArgument, message); +} + +inline Status UnimplementedError(StringView message = {}) +{ + return Status(StatusCode::kUnimplemented, message); +} + +inline Status InternalError(StringView message = {}) +{ + return Status(StatusCode::kInternal, message); +} + +} // namespace deimos + -- cgit