diff --git a/src/Makefile.am b/src/Makefile.am index a354b9e6f5149..981c8928211d9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -328,6 +328,7 @@ BITCOIN_CORE_H = \ util/overflow.h \ util/ranges.h \ util/readwritefile.h \ + util/result.h \ util/underlying.h \ util/serfloat.h \ util/settings.h \ diff --git a/src/util/result.h b/src/util/result.h new file mode 100644 index 0000000000000..5641e75afca92 --- /dev/null +++ b/src/util/result.h @@ -0,0 +1,69 @@ +// Copyright (c) 2023 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_RESULT_H +#define BITCOIN_UTIL_RESULT_H + +#include +#include // for std::move() +#include + +template +struct Ok { + constexpr explicit Ok(T val) : val_(std::move(val)) {} + const T val_; +}; + +// Specialization of the Ok struct for void type +template<> +struct Ok { + constexpr Ok() = default; +}; + +template +struct Err { + constexpr explicit Err(E val) : val_(std::move(val)) {} + + template + constexpr explicit Err(Ts...t) : val_{t...} {} + + const E val_; +}; + +template +class Result { +public: + constexpr Result(Ok val) : result{val} {} + template + constexpr Result(Ts... t) : result{Ok{t...}} {} + constexpr Result(Err err) : result{err.val_} {} + + [[nodiscard]] constexpr bool is_ok() const { return std::holds_alternative>(result); } + [[nodiscard]] constexpr bool is_err() const { return !is_ok(); } + + [[nodiscard]] constexpr explicit operator bool() const { + return is_ok(); + } + + template + [[nodiscard]] constexpr const U& operator*() const { + return unwrap(); + } + + template + [[nodiscard]] constexpr const U& unwrap() const { + assert(is_ok()); + return std::get>(result).val_; + } + + [[nodiscard]] constexpr const E& err() const { + assert(is_err()); + return std::get(result); + } + +private: + std::variant, E> result; +}; + +#endif