Skip to content

Instantly share code, notes, and snippets.

@Warchant
Created September 21, 2017 17:09
Show Gist options
  • Select an option

  • Save Warchant/e261c100c61659cb5c61545d3f737bda to your computer and use it in GitHub Desktop.

Select an option

Save Warchant/e261c100c61659cb5c61545d3f737bda to your computer and use it in GitHub Desktop.
/**
* Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
* http://soramitsu.co.jp
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <boost/optional.hpp>
#include <boost/variant.hpp>
namespace iroha {
template <typename T>
struct Ok_t {
Ok_t(T&& v) : value{std::forward<T>(v)} {}
Ok_t<T>& operator=(T&& v) {
value = std::forward<T>(v);
return *this;
}
T value;
};
template <typename E>
struct Error_t {
Error_t(E&& e) : reason{std::forward<E>(e)} {}
Error_t<E>& operator=(E&& e) {
reason = std::forward<E>(e);
return *this;
}
E reason;
};
template <typename T>
auto Ok(T&& e) {
return Ok_t<T>{std::forward<T>(e)};
}
template <typename E>
auto Error(E&& e) {
return Error_t<E>{std::forward<E>(e)};
}
/**
* Represents "result of a function" type. Is either value, or error.
* @tparam V value type
* @tparam E error type
*/
template <typename V, typename E>
class result {
public:
using Et = Error_t<E>;
using Vt = Ok_t<V>;
result(const Vt& e) : _(e) {}
result(const Et& e) : _(e) {}
result(Vt&& e) : _(std::move(e)) {}
result(Et&& e) : _(std::move(e)) {}
explicit operator bool() const noexcept { return _.which() == 0; }
V operator*() { return _.value(); }
const V& operator*() const { return _.cvalue(); }
V& operator->() { return boost::get<Vt>(_); }
E error() { return boost::get<Et>(_).reason; }
V ok() { return boost::get<Vt>(_).value; }
const E& cerror() const { return std::cref(boost::get<Et>(_).reason); }
const V& cok() const { return std::cref(boost::get<Vt>(_).value); }
using bad_get = boost::bad_get;
private:
boost::variant<Vt, Et> _;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment