70 lines
2.2 KiB
C++
70 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include <utility>
|
|
|
|
#include "error.hpp"
|
|
|
|
template <class T>
|
|
class Result {
|
|
public:
|
|
Result(const T& res) : _value(res), _error(ErrorCode::Success) {}
|
|
Result(T&& res) : _value(std::move(res)), _error(ErrorCode::Success) {}
|
|
Result(ErrorCode err) : _error(err) {}
|
|
|
|
bool has_error() const { return _error != ErrorCode::Success; }
|
|
bool has_value() const { return !has_error(); }
|
|
|
|
T& value() { return _value; }
|
|
T& operator*() { return _value; }
|
|
T release_value() { return std::move(_value); }
|
|
ErrorCode error() { return _error; }
|
|
|
|
private:
|
|
T _value;
|
|
ErrorCode _error;
|
|
};
|
|
|
|
template <>
|
|
class Result<void> {
|
|
public:
|
|
using ResultType = void;
|
|
|
|
Result(Result&& res) = default;
|
|
|
|
Result(ErrorCode err) : err(err) {}
|
|
Result() : err(ErrorCode::Success) {}
|
|
|
|
Result& operator=(Result&& res) = default;
|
|
|
|
bool has_error() const { return err != ErrorCode::Success; }
|
|
bool has_value() const { return !has_error(); }
|
|
|
|
void value() {}
|
|
void release_value() {}
|
|
|
|
ErrorCode error() { return err; }
|
|
|
|
private:
|
|
ErrorCode err;
|
|
};
|
|
|
|
#define TRY(m) \
|
|
(({ \
|
|
auto ___res = (m); \
|
|
if (!___res.has_value()) return ___res.error(); \
|
|
std::move(___res); \
|
|
}).release_value())
|
|
|
|
#define DIEX(m) \
|
|
(({ \
|
|
auto ___res = (m); \
|
|
if (!___res.has_value()) { \
|
|
const char* err = geterr(); \
|
|
if (err == 0) \
|
|
fprintf(stderr, "%s:%d assertion failed\n", __FILE__, __LINE__); \
|
|
else \
|
|
fprintf(stderr, "%s\n", err); \
|
|
exit(EXIT_FAILURE); \
|
|
} \
|
|
std::move(___res); \
|
|
}).release_value())
|