Created
March 7, 2021 21:57
-
-
Save dgski/df5d7dcfc77031f79675f3b50565a051 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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