Files
Z3D/include/util/result.hpp
2024-12-22 16:58:40 +01:00

140 lines
3.1 KiB
C++

#pragma once
#include <variant>
#include <system_error>
#include <expected>
namespace ztu {
template<typename T>
using result = std::expected<T, std::error_code>;
/*
template<typename T>
class result {
static constexpr auto value_index = 0;
static constexpr auto error_index = 1;
public:
constexpr result(T value);
constexpr result(const std::error_code& error);
template<typename... Args>
void emplace(Args&&... args);
[[nodiscard]] constexpr bool ok() const;
[[nodiscard]] constexpr std::error_code error() const;
[[nodiscard]] constexpr const T& value() const;
[[nodiscard]] constexpr T& value();
[[nodiscard]] constexpr T&& value() &&;
[[nodiscard]] operator bool() const;
[[nodiscard]] const T& operator*() const;
[[nodiscard]] T& operator*();
[[nodiscard]] T&& operator*() &&;
[[nodiscard]] bool operator==(const T& rhs) const;
[[nodiscard]] bool operator==(const std::error_code& rhs) const;
template<typename Func>
auto map(Func&& func) const -> result<decltype(func(value()))>
{
if (ok()) return func(value());
return error();
}
private:
std::variant<T, std::error_code> m_data;
};
// Member function definitions
template<typename T>
constexpr result<T>::result(T value)
: m_data{ std::in_place_index_t<value_index>{}, std::move(value) }
{}
template<typename T>
constexpr result<T>::result(const std::error_code& error)
: m_data{ std::in_place_index_t<error_index>{}, error }
{}
template<typename T>
template<typename... Args>
void result<T>::emplace(Args&&... args) {
m_data.template emplace<value_index>(std::forward<Args>(args)...);
}
template<typename T>
template<typename Func>
auto result<T>::map(Func&& func) const -> result<decltype(func(value()))> {
if (ok()) return func(value());
return error();
}
template<typename T>
constexpr bool result<T>::ok() const {
return m_data.index() == value_index;
}
template<typename T>
constexpr std::error_code result<T>::error() const {
auto error_ptr = std::get_if<error_index>(m_data);
return error_ptr ? *error_ptr : std::error_code{};
}
template<typename T>
constexpr const T& result<T>::value() const {
return std::get<value_index>(m_data);
}
template<typename T>
constexpr T& result<T>::value() {
return std::get<value_index>(m_data);
}
template<typename T>
constexpr T&& result<T>::value() && {
return std::get<value_index>(std::move(m_data));
}
template<typename T>
constexpr result<T>::operator bool() const {
return ok();
}
template<typename T>
const T& result<T>::operator*() const {
return *std::get_if<value_index>(m_data);
}
template<typename T>
T& result<T>::operator*() {
return *std::get_if<value_index>(m_data);
}
template<typename T>
T&& result<T>::operator*() && {
return *std::get_if<value_index>(std::move(m_data));
}
template<typename T>
bool result<T>::operator==(const T& rhs) const {
return ok() and value() == rhs;
}
template<typename T>
bool result<T>::operator==(const std::error_code& rhs) const {
return not ok() and error() == rhs;
}*/
}