diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-04-11 23:49:22 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-04-13 00:04:48 +0200 |
commit | 8db26a7350aad53ed73a127f9b8eb6ef15bf0be1 (patch) | |
tree | 5fd5f331d61e20ba89b6ae00c4b387b1e72796f1 /deimos/core/status.h | |
parent | a2671839daddfaaec63f43132854c606c556558a (diff) |
Implement Status
Diffstat (limited to 'deimos/core/status.h')
-rw-r--r-- | deimos/core/status.h | 111 |
1 files changed, 111 insertions, 0 deletions
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<StatusRep*>(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
+
|