Bitcoin Core  27.99.0
P2P Digital Currency
result.h
Go to the documentation of this file.
1 // Copyright (c) 2022 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_UTIL_RESULT_H
6 #define BITCOIN_UTIL_RESULT_H
7 
8 #include <attributes.h>
9 #include <util/translation.h>
10 
11 #include <variant>
12 
13 namespace util {
14 
15 struct Error {
17 };
18 
34 template <class M>
35 class Result
36 {
37 private:
38  using T = std::conditional_t<std::is_same_v<M, void>, std::monostate, M>;
39 
40  std::variant<bilingual_str, T> m_variant;
41 
43  Result(const Result&) = delete;
44 
49  Result& operator=(const Result&) = delete;
50  Result& operator=(Result&&) = delete;
51 
52  template <typename FT>
53  friend bilingual_str ErrorString(const Result<FT>& result);
54 
55 public:
56  Result() : m_variant{std::in_place_index_t<1>{}, std::monostate{}} {} // constructor for void
57  Result(T obj) : m_variant{std::in_place_index_t<1>{}, std::move(obj)} {}
58  Result(Error error) : m_variant{std::in_place_index_t<0>{}, std::move(error.message)} {}
59  Result(Result&&) = default;
60  ~Result() = default;
61 
64  bool has_value() const noexcept { return m_variant.index() == 1; }
65  const T& value() const LIFETIMEBOUND
66  {
67  assert(has_value());
68  return std::get<1>(m_variant);
69  }
71  {
72  assert(has_value());
73  return std::get<1>(m_variant);
74  }
75  template <class U>
76  T value_or(U&& default_value) const&
77  {
78  return has_value() ? value() : std::forward<U>(default_value);
79  }
80  template <class U>
81  T value_or(U&& default_value) &&
82  {
83  return has_value() ? std::move(value()) : std::forward<U>(default_value);
84  }
85  explicit operator bool() const noexcept { return has_value(); }
86  const T* operator->() const LIFETIMEBOUND { return &value(); }
87  const T& operator*() const LIFETIMEBOUND { return value(); }
88  T* operator->() LIFETIMEBOUND { return &value(); }
89  T& operator*() LIFETIMEBOUND { return value(); }
90 };
91 
92 template <typename T>
94 {
95  return result ? bilingual_str{} : std::get<0>(result.m_variant);
96 }
97 } // namespace util
98 
99 #endif // BITCOIN_UTIL_RESULT_H
#define LIFETIMEBOUND
Definition: attributes.h:16
T value_or(U &&default_value) const &
Definition: result.h:76
const T & value() const LIFETIMEBOUND
Definition: result.h:65
T & operator*() LIFETIMEBOUND
Definition: result.h:89
Result(Error error)
Definition: result.h:58
T & value() LIFETIMEBOUND
Definition: result.h:70
bool has_value() const noexcept
std::optional methods, so functions returning optional<T> can change to return Result<T> with minimal...
Definition: result.h:64
T * operator->() LIFETIMEBOUND
Definition: result.h:88
Result & operator=(Result &&)=delete
Result(const Result &)=delete
Disallow copy constructor, require Result to be moved for efficiency.
const T & operator*() const LIFETIMEBOUND
Definition: result.h:87
T value_or(U &&default_value) &&
Definition: result.h:81
Result(T obj)
Definition: result.h:57
friend bilingual_str ErrorString(const Result< FT > &result)
std::conditional_t< std::is_same_v< M, void >, std::monostate, M > T
Definition: result.h:38
std::variant< bilingual_str, T > m_variant
Definition: result.h:40
Result & operator=(const Result &)=delete
Disallow operator= to avoid confusion in the future when the Result class gains support for richer er...
const T * operator->() const LIFETIMEBOUND
Definition: result.h:86
Result(Result &&)=default
~Result()=default
bilingual_str ErrorString(const Result< T > &result)
Definition: result.h:93
Bilingual messages:
Definition: translation.h:18
bilingual_str message
Definition: result.h:16
assert(!tx.IsCoinBase())