summaryrefslogtreecommitdiff
path: root/deimos/core
diff options
context:
space:
mode:
Diffstat (limited to 'deimos/core')
-rw-r--r--deimos/core/status.h134
-rw-r--r--deimos/core/std.h5
2 files changed, 137 insertions, 2 deletions
diff --git a/deimos/core/status.h b/deimos/core/status.h
index 6601ad7..912d4c8 100644
--- a/deimos/core/status.h
+++ b/deimos/core/status.h
@@ -46,7 +46,7 @@ public:
Ref();
}
- Status(Status&& other) : m_rep{std::exchange(other.m_rep, 0U)} {}
+ Status(Status&& other) : m_rep{std::exchange(other.m_rep, CodeToRep(StatusCode::kOk))} {}
Status& operator=(const Status& other)
{
@@ -64,7 +64,7 @@ public:
if (this != &other)
{
Unref();
- this->m_rep = std::exchange(other.m_rep, 0U);
+ this->m_rep = std::exchange(other.m_rep, CodeToRep(StatusCode::kOk));
}
return *this;
@@ -106,5 +106,135 @@ inline Status InternalError(StringView message = {})
return Status(StatusCode::kInternal, message);
}
+namespace statusor_internals
+{
+};
+
+template<typename T>
+class StatusOr
+{
+ deimos_StaticAssert(!std::is_constructible_v<T, Status>);
+
+ struct Dummy{};
+
+ Status m_status;
+
+ union {
+ Dummy m_dummy;
+ T m_value;
+ };
+
+ void Clear()
+ {
+ if constexpr (!std::is_trivially_destructible_v<T>)
+ {
+ if (m_status.ok())
+ {
+ (&m_value)->~T();
+ }
+ }
+ }
+
+public:
+ explicit StatusOr() requires std::is_default_constructible_v<T> :
+ m_value{}
+ {}
+
+ template<typename... Args>
+ StatusOr(Args&&... args) requires std::is_constructible_v<T, Args...> : // NOLINT
+ m_value{std::forward<Args>(args)...}
+ {}
+
+ StatusOr(const Status& status) : m_status{status} // NOLINT
+ {
+ if (m_status.ok())
+ {
+ deimos_Panic("Cannot construct a StatusOr from OK");
+ m_status = InternalError("StatusOr constructed from OK");
+ }
+ }
+
+ StatusOr(Status&& status) : m_status{std::move(status)} // NOLINT
+ {
+ if (m_status.ok())
+ {
+ deimos_Panic("Cannot construct a StatusOr from OK");
+ m_status = InternalError("StatusOr constructed from OK");
+ }
+ }
+
+ StatusOr(const StatusOr& other) requires std::is_copy_constructible_v<T> :
+ m_status{other.m_status}
+ {
+ if (m_status.ok())
+ {
+ new (&m_value) T(other.m_value);
+ }
+ }
+
+ StatusOr(StatusOr&& other) requires std::is_move_constructible_v<T> :
+ m_status{std::move(other.m_status)}
+ {
+ if (m_status.ok())
+ {
+ new (&m_value) T(std::move(other.m_value));
+ }
+ }
+
+ ~StatusOr()
+ {
+ Clear();
+ }
+
+ StatusOr& operator=(const StatusOr& other) requires std::is_copy_assignable_v<T>
+ {
+ if (this != &other)
+ {
+ if (m_status.ok() && other.m_status.ok())
+ {
+ m_value = other.m_value;
+ }
+ else if (!m_status.ok() && other.m_status.ok())
+ {
+ new (&m_value) T(other.m_value);
+ }
+ else if (m_status.ok() && !other.m_status.ok())
+ {
+ Clear();
+ }
+ m_status = other.m_status;
+ }
+ return *this;
+ }
+
+ StatusOr& operator=(StatusOr&& other) requires std::is_move_assignable_v<T>
+ {
+ if (this != &other)
+ {
+ if (m_status.ok() && other.m_status.ok())
+ {
+ m_value = std::move(other.m_value);
+ }
+ else if (!m_status.ok() && other.m_status.ok())
+ {
+ new (&m_value) T(std::move(other.m_value));
+ }
+ else if (m_status.ok() && !other.m_status.ok())
+ {
+ Clear();
+ }
+ m_status = other.m_status;
+ }
+ return *this;
+ }
+
+ constexpr bool ok() const { return m_status.ok(); }
+
+ friend void DeimosFormat(IWriter* writer, const StatusOr<T>& status)
+ {
+ DeimosFormat(writer, status.m_status);
+ }
+};
+
} // namespace deimos
diff --git a/deimos/core/std.h b/deimos/core/std.h
index 0e0336e..47f161a 100644
--- a/deimos/core/std.h
+++ b/deimos/core/std.h
@@ -25,6 +25,11 @@ template<typename T> concept unsigned_integral = integral<T> && __is_unsigned(T)
template<typename T> constexpr bool is_trivially_destructible_v = __is_trivially_destructible(T);
template<typename T, typename... Args> constexpr bool is_constructible_v = __is_constructible(T, Args...);
+template<typename T> constexpr bool is_default_constructible_v = __is_constructible(T);
+template<typename T> constexpr bool is_copy_constructible_v = __is_constructible(T, const T&);
+template<typename T> constexpr bool is_move_constructible_v = __is_constructible(T, T&&);
+template<typename T> constexpr bool is_copy_assignable_v = __is_assignable(T, const T&);
+template<typename T> constexpr bool is_move_assignable_v = __is_assignable(T, T&&);
template<typename T> constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T);
template<typename U, typename V> constexpr bool _is_same_helper = false;