94 lines
2.2 KiB
C++
94 lines
2.2 KiB
C++
// Copyright 2023 The LightningBolt Authors
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
#include <optional>
|
|
#include <system_error>
|
|
#include <variant>
|
|
|
|
template <class T>
|
|
struct ErrorOr {
|
|
private:
|
|
using Variant = std::variant<T, std::error_code>;
|
|
|
|
public:
|
|
constexpr static auto IsVoid = false;
|
|
ErrorOr() = default;
|
|
ErrorOr(const ErrorOr&) = default;
|
|
ErrorOr(ErrorOr&&) = default;
|
|
|
|
ErrorOr(const T& v) : maybeVariant(v) {}
|
|
ErrorOr(const std::error_code& v) : maybeVariant(v) {}
|
|
|
|
ErrorOr& operator=(const T& value) {
|
|
maybeVariant = value;
|
|
return *this;
|
|
}
|
|
|
|
ErrorOr& operator=(const std::error_code& ec) {
|
|
maybeVariant = ec;
|
|
return *this;
|
|
}
|
|
|
|
bool HasValue() const {
|
|
if(maybeVariant)
|
|
return std::holds_alternative<T>(*maybeVariant);
|
|
|
|
// No value.
|
|
return false;
|
|
}
|
|
|
|
bool HasError() const {
|
|
if(maybeVariant)
|
|
return std::holds_alternative<std::error_code>(*maybeVariant);
|
|
|
|
// No error. Possibly in the default constructed state
|
|
return false;
|
|
}
|
|
|
|
// ASSERT TODO
|
|
|
|
T& Value() { return std::get<T>(maybeVariant.value()); }
|
|
|
|
const T& Value() const { return std::get<T>(maybeVariant.value()); }
|
|
|
|
operator T&() { return Value(); }
|
|
operator const T&() { return Value(); }
|
|
|
|
std::error_code& Error() { return std::get<std::error_code>(maybeVariant.value()); }
|
|
|
|
const std::error_code& Error() const { return std::get<std::error_code>(maybeVariant.value()); }
|
|
|
|
operator std::error_code&() { return Error(); }
|
|
operator const std::error_code&() const { return Error(); }
|
|
|
|
private:
|
|
std::optional<Variant> maybeVariant;
|
|
};
|
|
|
|
template <>
|
|
struct ErrorOr<void> {
|
|
constexpr static auto IsVoid = true;
|
|
ErrorOr() = default;
|
|
ErrorOr(const ErrorOr&) = default;
|
|
ErrorOr(ErrorOr&&) = default;
|
|
ErrorOr(const std::error_code& v) : maybeEc(v) {}
|
|
|
|
ErrorOr& operator=(const std::error_code& ec) {
|
|
maybeEc = ec;
|
|
return *this;
|
|
}
|
|
|
|
bool HasError() const { return maybeEc.has_value(); }
|
|
|
|
std::error_code& Error() { return maybeEc.value(); }
|
|
|
|
const std::error_code& Error() const { return maybeEc.value(); }
|
|
|
|
operator std::error_code&() { return Error(); }
|
|
operator const std::error_code&() const { return Error(); }
|
|
|
|
private:
|
|
std::optional<std::error_code> maybeEc;
|
|
};
|