23#ifndef CPPINTEROP_ERROR_H
24#define CPPINTEROP_ERROR_H
40enum class Status : uint8_t {
48 const void* state =
nullptr;
50 [[nodiscard]]
bool isOk()
const {
return state ==
nullptr; }
70template <
typename T>
class [[nodiscard]] Result {
71 static_assert(!std::is_same<T, void>::value,
72 "Result<void> is provided via specialization below");
74 static constexpr size_t kStorageSize =
sizeof(T) >
sizeof(
void*)
77 static constexpr size_t kStorageAlign =
alignof(T) >
alignof(
void*)
82 alignas(kStorageAlign)
unsigned char m_ValueBytes[kStorageSize];
83 const void* m_ErrState;
85 bool m_HasError =
false;
88 mutable bool m_Unchecked =
true;
89 void markChecked()
const { m_Unchecked =
false; }
91 void markChecked()
const {}
96 T* valuePtr() {
return reinterpret_cast<T*
>(m_ValueBytes); }
97 const T* valuePtr()
const {
return reinterpret_cast<const T*
>(m_ValueBytes); }
100 Result() {
new (m_ValueBytes) T(); }
102 Result(T V) {
new (m_ValueBytes) T(std::move(V)); }
104 Result(ErrorRef E) : m_ErrState(E.state), m_HasError(true) {}
106 Result(
const Result& Other) : m_HasError(Other.m_HasError) {
108 m_ErrState = Other.m_ErrState;
110 new (m_ValueBytes) T(*Other.valuePtr());
112 m_Unchecked = Other.m_Unchecked;
113 Other.m_Unchecked =
false;
117 Result(Result&& Other) noexcept : m_HasError(Other.m_HasError) {
119 m_ErrState = Other.m_ErrState;
121 new (m_ValueBytes) T(std::move(*Other.valuePtr()));
123 m_Unchecked = Other.m_Unchecked;
124 Other.m_Unchecked =
false;
132 if (m_Unchecked && m_HasError)
139 Result& operator=(
const Result&) =
delete;
140 Result& operator=(Result&&) =
delete;
144 void ignore()
const { markChecked(); }
146 [[nodiscard]]
bool ok()
const {
150 explicit operator bool()
const {
return ok(); }
152 [[nodiscard]] Status status()
const {
154 return m_HasError ? Status::Failed : Status::Ok;
157 [[nodiscard]] ErrorRef error()
const {
159 return m_HasError ? ErrorRef{m_ErrState} : ErrorRef{};
170 T value_or(T fallback)
const {
172 return m_HasError ? std::move(fallback) : *valuePtr();
178template <>
class [[nodiscard]] Result<void> {
179 const void* m_ErrState =
nullptr;
181 mutable bool m_Unchecked =
true;
182 void markChecked()
const { m_Unchecked =
false; }
184 void markChecked()
const {}
189 Result(ErrorRef E) : m_ErrState(E.state) {}
191 Result& operator=(
const Result&) =
delete;
192 Result& operator=(Result&&) =
delete;
194 Result(
const Result& O) : m_ErrState(O.m_ErrState) {
196 m_Unchecked = O.m_Unchecked;
197 O.m_Unchecked =
false;
201 Result(Result&& O) noexcept : m_ErrState(O.m_ErrState) {
208 m_Unchecked = O.m_Unchecked;
209 O.m_Unchecked =
false;
211 O.m_ErrState =
nullptr;
216 if (m_Unchecked && m_ErrState)
221 void ignore()
const { markChecked(); }
223 [[nodiscard]]
bool ok()
const {
225 return m_ErrState ==
nullptr;
227 explicit operator bool()
const {
return ok(); }
229 [[nodiscard]] Status status()
const {
231 return m_ErrState ? Status::Failed : Status::Ok;
234 [[nodiscard]] ErrorRef error()
const {
236 return ErrorRef{m_ErrState};
void ResultAbort_UncheckedOnDtor(const ErrorRef &)
void ResultAbort_ValueOnError(const ErrorRef &)