Skip to content

Instantly share code, notes, and snippets.

@dgski
Created March 7, 2021 21:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save dgski/df5d7dcfc77031f79675f3b50565a051 to your computer and use it in GitHub Desktop.
Save dgski/df5d7dcfc77031f79675f3b50565a051 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <variant>
#include <string>
#include <vector>
#include <tuple>
struct Error {
std::string message;
Error(std::string _message) : message(std::move(_message)) {}
};
Error operator+(const Error& a, const Error& b) {
return Error(a.message + ", " + b.message);
}
template<typename Type>
using Result = std::variant<Error, Type>;
template<typename Type>
bool is_error(const Result<Type>& value) {
return std::holds_alternative<Error>(value);
}
template<typename Type>
bool is_ok(const Result<Type>& value) {
return !is_error(value);
}
template<typename Type>
auto get_error(const Result<Type>& value) {
return std::get<0>(value);
}
template<typename Type>
auto get_ok(const Result<Type>& value) {
return std::get<1>(value);
}
template<typename Type>
auto get_all(Result<Type>& r) -> Result<std::tuple<Type>> {
if(is_error(r)) {
return get_error(r);
}
return std::make_tuple(get_ok(r));
}
template<typename Type, typename... Types>
auto get_all(Result<Type>& r, Types&... rest)
-> Result<decltype(std::tuple_cat(std::make_tuple(get_ok(r)), get_ok(get_all(rest...))))> {
auto restRes = get_all(rest...);
if(is_error(r) && is_error(restRes)) {
return get_error(r) + get_error(restRes);
} else if(is_error(r)) {
return get_error(r);
} else if(is_error(restRes)) {
return get_error(restRes);
}
return std::tuple_cat(std::make_tuple(get_ok(r)), get_ok(restRes));
}
int main() {
auto res1 = Result<int>(1);
auto res2 = Result<std::string>(Error("2: Source not valid"));
auto res3 = Result<std::vector<int>>(std::vector<int>{1,2,3,4,5});
auto res4 = Result<std::string>(Error("4: Request timed out"));
auto res_all = get_all(res1, res2, res3, res4);
if(is_error(res_all)) {
std::cout << "one or more errors ='" << get_error(res_all).message << "'" << std::endl;
return -1;
}
auto [value1, value2, value3, value4] = get_ok(res_all);
std::cout
<< "value1=" << value1
<< " value2=" << value2
<< " value3=" << value3.size()
<< " value4=" << value4 << '\n';
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment