Sese Framework  2.3.0
A cross-platform framework
Loading...
Searching...
No Matches
Result.h
Go to the documentation of this file.
1// Copyright 2024 libsese
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
19
20#pragma once
21
22#include <cassert>
23#include <optional>
24#include <type_traits>
25#include <variant>
26
27namespace sese {
28
32template<class T, class E, class Enable = void>
33class Result;
34
35template<class T, class E>
36class Result<T, E, std::enable_if_t<std::is_same_v<T, E> && !std::is_void_v<T> && !std::is_void_v<E>>> {
37private:
40
41 Result() = default;
42
43public:
44 using ResultType = T;
45 using ErrorType = E;
46
47 static Result error(E error) noexcept {
48 Result<T, E> tmp;
49 tmp.is_success = false;
50 tmp.result = error;
51 return tmp;
52 }
53
54 static Result success(T result) noexcept {
55 Result<T, E> tmp;
56 tmp.is_success = true;
57 tmp.result = result;
58 return tmp;
59 }
60
63 explicit operator bool() const noexcept {
64 return !is_success;
65 }
66
69 bool has_error() const noexcept {
70 return !is_success;
71 }
72
75 E err() const noexcept {
76 assert(!is_success);
77 return result;
78 }
79
82 E &err() noexcept {
83 assert(!is_success);
84 return result;
85 }
86
89 T get() const noexcept {
90 assert(is_success);
91 return result;
92 }
93
96 T &get() noexcept {
97 assert(is_success);
98 return result;
99 }
100};
101
102template<class T, class E>
103class Result<T, E, std::enable_if_t<!std::is_same_v<T, E> && !std::is_void_v<T> && !std::is_void_v<E>>> final {
104private:
105 std::variant<T, E> result;
106
107public:
108 using ResultType = T;
109 using ErrorType = E;
110
111 static Result error(E error) noexcept {
112 Result<T, E> tmp;
113 tmp.result = std::forward<E>(error);
114 return tmp;
115 }
116
117 static Result success(T result) noexcept {
118 Result<T, E> tmp;
119 tmp.result = std::forward<T>(result);
120 return tmp;
121 }
122
125 explicit operator bool() const noexcept {
126 return std::holds_alternative<E>(result);
127 }
128
131 bool has_error() const noexcept {
132 return std::holds_alternative<E>(result);
133 }
134
137 [[nodiscard]] E &err() noexcept {
138 assert(std::holds_alternative<E>(result));
139 return std::get<E>(result);
140 }
141
144 E err() const noexcept {
145 assert(std::holds_alternative<E>(result));
146 return std::get<E>(result);
147 }
148
151 T &get() noexcept {
152 assert(std::holds_alternative<T>(result));
153 return std::get<T>(result);
154 }
155
158 T get() const noexcept {
159 assert(std::holds_alternative<T>(result));
160 return std::get<T>(result);
161 }
162};
163
164template<class T>
165class Result<T, void> {
166private:
167 std::optional<T> result;
168
169 Result() = default;
170
171public:
172 using ResultType = T;
173 using ErrorType = void;
174
175 static Result error() noexcept {
176 return {};
177 }
178
179 static Result success(T result) noexcept {
180 Result tmp;
181 tmp.result = std::forward<T>(result);
182 return tmp;
183 }
184
187 explicit operator bool() const noexcept {
188 return !result.has_value();
189 }
190
193 bool has_error() const noexcept {
194 return !result.has_value();
195 }
196
199 T &get() noexcept {
200 assert(result.has_value());
201 return result.value();
202 }
203
206 T get() const noexcept {
207 assert(result.has_value());
208 return result.value();
209 }
210};
211
212template<class E>
213class Result<void, E> {
214private:
215 std::optional<E> e;
216
217 Result() = default;
218
219public:
220 using ResultType = void;
221 using ErrorType = E;
222
223 static Result error(E error) noexcept {
224 Result tmp;
225 tmp.e = std::forward<E>(error);
226 return tmp;
227 }
228
229 static Result success() noexcept {
230 return {};
231 }
232
235 explicit operator bool() const noexcept {
236 return e.has_value();
237 }
238
241 bool has_error() const noexcept {
242 return e.has_value();
243 }
244
247 [[nodiscard]] E &err() noexcept {
248 assert(e.has_value());
249 return e.value();
250 }
251
254 E err() const noexcept {
255 assert(e.has_value());
256 return e.value();
257 }
258};
259
260template<>
261class Result<void, void> {
262private:
264
265 Result() = default;
266
267public:
268 using ResultType = void;
269 using ErrorType = void;
270
271 static Result error() noexcept {
272 Result tmp;
273 tmp.is_success = false;
274 return tmp;
275 }
276
277 static Result success() noexcept {
278 Result tmp;
279 tmp.is_success = true;
280 return tmp;
281 }
282
285 explicit operator bool() const noexcept {
286 return !is_success;
287 }
288
291 bool has_error() const noexcept {
292 return !is_success;
293 }
294};
295
296} // namespace sese