#pragma once #include "deimos/core/base.h" namespace deimos { // NOLINTNEXTLINE(performance-enum-size) enum class StatusCode : uint32_t { kOk = 0, kUnknown, kInvalidArgument, kUnimplemented, kInternal, }; 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; StatusCode RepCode() 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 RepCode(); } }; 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