Program Listing for File expected.hpp
↰ Return to documentation for file (include/utils/expected.hpp)
#pragma once
#include <stdexcept>
#include <string>
#include <tl/expected.hpp>
template <typename Expected> typename Expected::value_type handle_expected(Expected&& result) {
if (result.has_value()) {
if constexpr (std::is_void_v<typename Expected::value_type>) {
return; // Return nothing since it's a void type
} else {
return result.value();
}
} else {
// TODO: Consider wrapping with a streamable option.
if constexpr (std::is_convertible_v<typename Expected::error_type, std::string>) {
throw std::runtime_error(std::string(result.error()));
} else {
throw std::runtime_error("Unknown error occurred.");
}
}
};
template <typename Class, typename Ret, typename Err, typename... Args>
auto unwrap_expected(tl::expected<Ret, Err> (Class::*method)(Args...)) {
return [method](Class& self, Args... args) -> Ret {
return handle_expected((self.*method)(args...));
};
}
template <typename Class, typename Ret, typename Err, typename... Args>
auto unwrap_expected(tl::expected<Ret, Err> (Class::*method)(Args...) const) {
return [method](const Class& self, Args... args) -> Ret {
return handle_expected((self.*method)(args...));
};
}
template <typename Ret, typename Err, typename... Args>
auto unwrap_expected(tl::expected<Ret, Err> (*method)(Args...)) {
return [method](Args... args) -> Ret { return handle_expected((*method)(args...)); };
}