valeri/src/result.hpp

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())