Cluedo Solver v1.0
Cluedo game solver making deductions.
Loading...
Searching...
No Matches
Result.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4#include <optional>
5#include <variant>
6
9
10// NOTE: Marking these classes as [[nodiscard]] so that whenever we use them we
11// are warned if we don't call them with TRY or MUST.
12
27template<typename ValueType, typename ErrorType>
28class [[nodiscard]] Result {
29public:
32 Result(ValueType&& value)
33 : m_impl(std::forward<ValueType>(value)) {}
34
37 Result(ErrorType&& error)
38 : m_impl(std::forward<ErrorType>(error)) {}
39
41 Result(Result const&) = default;
43 Result(Result&&) = default;
45 ~Result() = default;
46
50 bool is_value() const { return std::holds_alternative<ValueType>(m_impl); }
51
55 bool is_error() const { return std::holds_alternative<ErrorType>(m_impl); }
56
61 ValueType& value() {
62 assert(is_value());
63 return std::get<ValueType>(m_impl);
64 }
65
70 ValueType&& release_value() {
71 assert(is_value());
72 return std::get<ValueType>(std::move(m_impl));
73 }
74
79 ErrorType& error() {
80 assert(is_error());
81 return std::get<ErrorType>(m_impl);
82 }
83
88 ErrorType&& release_error() {
89 assert(is_error());
90 return std::get<ErrorType>(std::move(m_impl));
91 }
92
93private:
94 std::variant<ValueType, ErrorType> m_impl;
95};
96
103template<typename ErrorType>
104class Result<void, ErrorType> {
105public:
107 Result() = default;
108
111 Result(ErrorType&& error)
112 : m_impl(std::forward<ErrorType>(error)) {}
113
115 Result(Result const&) = default;
117 Result(Result&&) = default;
119 ~Result() = default;
120
124 bool is_value() const { return !is_error(); }
128 bool is_error() const { return m_impl.has_value(); }
129
132 void value() { assert(is_value()); }
135 void release_value() { assert(is_value()); }
136
141 ErrorType& error() {
142 assert(is_error());
143 return *m_impl;
144 }
145
150 ErrorType&& release_error() {
151 assert(is_error());
152 return std::move(*m_impl);
153 }
154
155private:
156 std::optional<ErrorType> m_impl;
157};
158
165#define TRY(expr) \
166 ({ \
167 auto _tmp = (expr); \
168 if (_tmp.is_error()) \
169 return _tmp.release_error(); \
170 _tmp.release_value(); \
171 })
172
179#define MUST(expr) \
180 ({ \
181 auto _tmp = (expr); \
182 assert(_tmp.is_value()); \
183 _tmp.release_value(); \
184 })
~Result()=default
Destroys a Result object.
bool is_value() const
Definition Result.hpp:124
Result(ErrorType &&error)
Definition Result.hpp:111
ErrorType & error()
Definition Result.hpp:141
void value()
Definition Result.hpp:132
void release_value()
Definition Result.hpp:135
bool is_error() const
Definition Result.hpp:128
Result(Result &&)=default
Moves a Result object.
Result()=default
Construct a Result object without an error.
Result(Result const &)=default
Copies a Result object.
ErrorType && release_error()
Definition Result.hpp:150
Result(ValueType &&value)
Definition Result.hpp:32
bool is_value() const
Definition Result.hpp:50
ValueType & value()
Definition Result.hpp:61
ErrorType && release_error()
Definition Result.hpp:88
Result(Result &&)=default
Moves a Result object.
Result(Result const &)=default
Copies a Result object.
Result(ErrorType &&error)
Definition Result.hpp:37
ValueType && release_value()
Definition Result.hpp:70
~Result()=default
Destroys a Result object.
bool is_error() const
Definition Result.hpp:55
ErrorType & error()
Definition Result.hpp:79