{
switch (_tag) {
case Tag::Ok:
return on_ok(_value.ok);
case Tag::Err:
return on_err(_value.error);
default:
panic("[_tag] was left in an invalid state!");
}
}
template<typename OnOk, typename OnErr>
auto match(OnOk on_ok, OnErr on_err) & -> decltype(on_ok(declval<T &>())) {
switch (_tag) {
case Tag::Ok:
return on_ok(_value.ok);
case Tag::Err:
return on_err(_value.error);
default:
panic("[_tag] was left in an invalid state!");
}
}
template<typename F>
auto map(F f) && -> Result<decltype(f(declval<T>())), E> {
using M = decltype(f(declval<T>()));
using R = Result<M, E>;
switch (_tag) {
case Tag::Ok:
return R::ok(f(move(_value.ok)));
case Tag::Err:
return R::err(move(_value.error));
default:
panic("[_tag] was left in an invalid state!");
}
}
template<typename F>
auto map(F f) const & -> Result<decltype(f(declval<const T &>())), E> {
using M = decltype(f(declval<const T &>()));
using R = Result<M, E>;
switch (_tag) {
case Tag::Ok:
return R::ok(f(_value.ok));
case Tag::Err:
return R::err(_value.error);
default:
panic("[_tag] was left in an invalid state!");
}
}
constexpr bool is_ok() const noexcept {
return _tag == Tag::Ok;
}
constexpr bool is_err() const noexcept {
return _tag == Tag::Err;
}
template <typename M>
T &expect(M message) & {
if (is_err()) {
panic(message);
}
return _value.ok;
}
template <typename M>
const T &expect(M message) const & {
if (is_err()) {
panic(message);
}
return _value.ok;
}
template <typename M>
T &&expect(M message) && {
if (is_err()) {
panic(message);
}
return move(_value.ok);
}
template <typename M>
E &expect_err(M message) & {
if (is_ok()) {
panic(message);
}
return _value.error;
}
template <typename M>
const E &expect_err(M message) const & {
if (is_ok()) {
panic(message);
}
return _value.error;
}
template <typename M>
E &&expect_err(M message) && {
if (is_ok()) {
panic(message);
}
return move(_value.error);
}
T unwrap_or(const T &default_value) const & {
return is_ok() ? _value.ok : default_value;
}
T unwrap_or(T &&default_value) && {
return is_ok() ? move(_value.ok) : move(default_value);
}
~Result() noexcept {
destroy();
}
Result(const Result &other)
: _tag{ other._tag } {
switch (_tag) {
case Tag::Ok:
new (&_value.ok) T(other._value.ok);
break;
case Tag::Err:
new (&_value.error) E(other._value.error);
break;
default:
panic("[_tag] was left in an invalid state!");
}
}
Result(Result &&other) noexcept
: _tag{ other._tag } {
switch (_tag) {
case Tag::Ok:
new (&_value.ok) T(move(other._value.ok));
break;
case Tag::Err:
new (&_value.error) E(move(other._value.error));
break;
default:
panic("[_tag] was left in an invalid state!");
}
}
Result &operator=(const Result &other) {
if (this == &other) {
return *this;
}
if (_tag == other._tag) {
switch (_tag) {
case Tag::Ok: _value.ok = other._value.ok; break;
case Tag::Err: _value.error = other._value.error; break;
default:
panic("[_tag] was left in an invalid
Post #24149
12