Skip to content

Instantly share code, notes, and snippets.

@nekko1119
Created March 19, 2019 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nekko1119/5ad127794f718a17dc0d78ffb7fedde2 to your computer and use it in GitHub Desktop.
Save nekko1119/5ad127794f718a17dc0d78ffb7fedde2 to your computer and use it in GitHub Desktop.
#include <variant>
#include <memory>
#include <stdexcept>
#include <iostream>
template <typename T, typename E = std::exception>
struct result {
using value_type = T;
using error_type = std::shared_ptr<E>;
template <typename U>
/* no explicit */constexpr result(U&& value) : value_{std::forward<U>(value)} {}
result(result const&) = delete;
result& operator=(result const&) = delete;
result(result&&) = default;
result& operator=(result&&) = default;
~result() noexcept = default;
constexpr bool valid() const noexcept {
return value_.index() == 1U;
}
explicit constexpr operator bool() const noexcept {
return valid();
}
constexpr decltype(auto) value() {
return std::get<T>(value_);
}
constexpr decltype(auto) value() const {
return std::get<T>(value_);
}
constexpr decltype(auto) error() const {
return std::get<error_type>(value_);
}
constexpr decltype(auto) error() {
return std::get<error_type>(value_);
}
template <typename E2>
std::shared_ptr<E2> error_as() const {
return std::dynamic_pointer_cast<E2>(error());
}
template <typename E2>
std::shared_ptr<E2> error_as() {
return std::dynamic_pointer_cast<E2>(error());
}
std::variant<error_type, T> value_;
};
auto f(int a, int b) -> result<double> {
if (b == 0) {
return std::make_shared<std::runtime_error>("b must not be 0");
}
return a / static_cast<double>(b);
}
int main() {
if (auto const result = f(3, 2)) {
std::cout << "answer is " << result.value() << std::endl;
} else {
std::cout << result.error_as<std::runtime_error>()->what() << "\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment