peelo-result
result.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020-2024, peelo.net
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27#pragma once
28
29#include <utility>
30
31namespace peelo
32{
38 template<class T, class E>
39 class result final
40 {
41 public:
42 using value_type = T;
43 using error_type = E;
44
49 : m_value(new value_type(value))
50 , m_error(nullptr) {}
51
56 : m_value(new value_type(std::move(value)))
57 , m_error(nullptr) {}
58
62 template<class... Args>
63 static inline result<T, E> ok(Args&&... args)
64 {
65 return { new value_type(std::forward<Args>(args)...), nullptr };
66 }
67
71 static inline result<T, E> error(const error_type& error)
72 {
73 return { nullptr, new error_type(error) };
74 }
75
79 template<class... Args>
80 static inline result<T, E> error(Args&&... args)
81 {
82 return { nullptr, new error_type(std::forward<Args>(args)...) };
83 }
84
88 result(const result& that)
89 : m_value(that.m_value ? new value_type(*that.m_value) : nullptr)
90 , m_error(that.m_error ? new error_type(*that.m_error) : nullptr) {}
91
95 result(result&& that)
96 : m_value(std::move(that.m_value))
97 , m_error(std::move(that.m_error))
98 {
99 that.m_value = nullptr;
100 that.m_error = nullptr;
101 }
102
106 template<class U, class G>
107 result(const result<U, G>& that)
108 : m_value(that ? new value_type(that.value()) : nullptr)
109 , m_error(that ? nullptr : new error_type(that.error())) {}
110
115 {
116 if (m_value)
117 {
118 delete m_value;
119 }
120 if (m_error)
121 {
122 delete m_error;
123 }
124 }
125
129 result& operator=(const result& that)
130 {
131 if (this != &that)
132 {
133 if (m_value)
134 {
135 delete m_value;
136 m_value = nullptr;
137 }
138 if (m_error)
139 {
140 delete m_error;
141 m_error = nullptr;
142 }
143 if (that.m_value)
144 {
145 m_value = new value_type(*that.m_value);
146 }
147 if (that.m_error)
148 {
149 m_error = new error_type(*that.m_error);
150 }
151 }
152
153 return *this;
154 }
155
159 template<class U, class G>
161 {
162 if (m_value)
163 {
164 delete m_value;
165 m_value = nullptr;
166 }
167 if (m_error)
168 {
169 delete m_error;
170 m_error = nullptr;
171 }
172 if (that)
173 {
174 m_value = new value_type(that.value());
175 } else {
176 m_error = new error_type(that.error());
177 }
178
179 return *this;
180 }
181
186 {
187 if (this != &that)
188 {
189 if (m_value)
190 {
191 delete m_value;
192 }
193 if (m_error)
194 {
195 delete m_error;
196 }
197 m_value = std::move(that.m_value);
198 m_error = std::move(that.m_error);
199 that.m_value = nullptr;
200 that.m_error = nullptr;
201 }
202
203 return *this;
204 }
205
210 inline constexpr bool has_value() const noexcept
211 {
212 return !!m_value;
213 }
214
219 inline constexpr explicit operator bool() const noexcept
220 {
221 return has_value();
222 }
223
228 inline constexpr bool operator!() const noexcept
229 {
230 return !has_value();
231 }
232
237 inline constexpr value_type& value() noexcept
238 {
239 return *m_value;
240 }
241
246 inline const value_type& value() const noexcept
247 {
248 return *m_value;
249 }
250
255 inline constexpr value_type* operator->() noexcept
256 {
257 return m_value;
258 }
259
264 inline constexpr const value_type* operator->() const noexcept
265 {
266 return m_value;
267 }
268
273 inline constexpr value_type& operator*() noexcept
274 {
275 return *m_value;
276 }
277
282 inline constexpr const value_type& operator*() const noexcept
283 {
284 return *m_value;
285 }
286
291 inline constexpr error_type& error() noexcept
292 {
293 return *m_error;
294 }
295
300 inline constexpr const error_type& error() const noexcept
301 {
302 return *m_error;
303 }
304
309 template<class U>
310 inline value_type value_or(U&& default_value) const
311 {
312 return m_value
313 ? *m_value
314 : static_cast<value_type>(std::forward<U>(default_value));
315 }
316
321 template<class U>
322 inline error_type error_or(U&& default_error) const
323 {
324 return m_value
325 ? static_cast<error_type>(std::forward<U>(default_error))
326 : *m_error;
327 }
328
332 inline bool equals(const result& that) const
333 {
334 if (m_value)
335 {
336 if (!that)
337 {
338 return false;
339 }
340
341 return *m_value == *that.m_value;
342 }
343 else if (that)
344 {
345 return false;
346 }
347
348 return *m_error == *that.m_error;
349 }
350
354 inline bool operator==(const result& that) const
355 {
356 return equals(that);
357 }
358
362 inline bool operator!=(const result& that) const
363 {
364 return !equals(that);
365 }
366
370 template<class U, class G>
371 inline bool equals(const result<U, G>& that) const
372 {
373 if (m_value)
374 {
375 if (!that)
376 {
377 return false;
378 }
379
380 return *m_value == that.value();
381 }
382 else if (that)
383 {
384 return false;
385 }
386
387 return *m_error == that.error();
388 }
389
393 template<class U, class G>
394 inline bool operator==(const result<U, G>& that) const
395 {
396 return equals(that);
397 }
398
402 template<class U, class G>
403 inline bool operator!=(const result<U, G>& that) const
404 {
405 return !equals(that);
406 }
407
408 private:
410 : m_value(value)
411 , m_error(error) {}
412
413 private:
414 value_type* m_value;
415 error_type* m_error;
416 };
417}
constexpr const error_type & error() const noexcept
Definition result.hpp:300
static result< T, E > error(const error_type &error)
Definition result.hpp:71
error_type error_or(U &&default_error) const
Definition result.hpp:322
bool operator!=(const result &that) const
Definition result.hpp:362
bool operator!=(const result< U, G > &that) const
Definition result.hpp:403
result & operator=(const result< U, G > &that)
Definition result.hpp:160
bool operator==(const result &that) const
Definition result.hpp:354
result & operator=(const result &that)
Definition result.hpp:129
constexpr value_type & value() noexcept
Definition result.hpp:237
value_type value_or(U &&default_value) const
Definition result.hpp:310
result(result &&that)
Definition result.hpp:95
constexpr const value_type & operator*() const noexcept
Definition result.hpp:282
bool equals(const result< U, G > &that) const
Definition result.hpp:371
result & operator=(result &&that)
Definition result.hpp:185
~result()
Definition result.hpp:114
result(value_type &&value)
Definition result.hpp:55
constexpr const value_type * operator->() const noexcept
Definition result.hpp:264
result(const result< U, G > &that)
Definition result.hpp:107
static result< T, E > error(Args &&... args)
Definition result.hpp:80
constexpr error_type & error() noexcept
Definition result.hpp:291
result(const result &that)
Definition result.hpp:88
E error_type
Definition result.hpp:43
constexpr bool has_value() const noexcept
Definition result.hpp:210
static result< T, E > ok(Args &&... args)
Definition result.hpp:63
constexpr value_type & operator*() noexcept
Definition result.hpp:273
constexpr bool operator!() const noexcept
Definition result.hpp:228
result(const value_type &value)
Definition result.hpp:48
T value_type
Definition result.hpp:42
bool equals(const result &that) const
Definition result.hpp:332
const value_type & value() const noexcept
Definition result.hpp:246
constexpr value_type * operator->() noexcept
Definition result.hpp:255
bool operator==(const result< U, G > &that) const
Definition result.hpp:394
Definition result.hpp:32