Bitcoin Core 31.99.0
P2P Digital Currency
expected.h
Go to the documentation of this file.
1// Copyright (c) The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or https://opensource.org/license/mit.
4
5#ifndef BITCOIN_UTIL_EXPECTED_H
6#define BITCOIN_UTIL_EXPECTED_H
7
8#include <attributes.h>
9#include <util/check.h>
10
11#include <exception>
12#include <utility>
13#include <variant>
14
15namespace util {
16
19template <class E>
21{
22public:
23 constexpr explicit Unexpected(E e) : m_error(std::move(e)) {}
24
25 constexpr const E& error() const& noexcept LIFETIMEBOUND { return m_error; }
26 constexpr E& error() & noexcept LIFETIMEBOUND { return m_error; }
27 constexpr E&& error() && noexcept LIFETIMEBOUND { return std::move(m_error); }
28
29private:
31};
32
33struct BadExpectedAccess : std::exception {
34 const char* what() const noexcept override { return "Bad util::Expected access"; }
35};
36
42template <class T, class E>
44{
45private:
46 std::variant<T, E> m_data;
47
48public:
49 constexpr Expected() : m_data{std::in_place_index<0>, T{}} {}
50 constexpr Expected(T v) : m_data{std::in_place_index<0>, std::move(v)} {}
51 template <class Err>
52 constexpr Expected(Unexpected<Err> u) : m_data{std::in_place_index<1>, std::move(u).error()}
53 {
54 }
55
56 constexpr bool has_value() const noexcept { return m_data.index() == 0; }
57 constexpr explicit operator bool() const noexcept { return has_value(); }
58
59 constexpr const T& value() const& LIFETIMEBOUND
60 {
61 if (!has_value()) {
62 throw BadExpectedAccess{};
63 }
64 return std::get<0>(m_data);
65 }
66 constexpr T& value() & LIFETIMEBOUND
67 {
68 if (!has_value()) {
69 throw BadExpectedAccess{};
70 }
71 return std::get<0>(m_data);
72 }
73 constexpr T&& value() && LIFETIMEBOUND { return std::move(value()); }
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
86 constexpr const E& error() const& noexcept LIFETIMEBOUND { return *Assert(std::get_if<1>(&m_data)); }
87 constexpr E& error() & noexcept LIFETIMEBOUND { return *Assert(std::get_if<1>(&m_data)); }
88 constexpr E&& error() && noexcept LIFETIMEBOUND { return std::move(error()); }
89
90 constexpr void swap(Expected& other) noexcept { m_data.swap(other.m_data); }
91
92 constexpr T& operator*() & noexcept LIFETIMEBOUND { return value(); }
93 constexpr const T& operator*() const& noexcept LIFETIMEBOUND { return value(); }
94 constexpr T&& operator*() && noexcept LIFETIMEBOUND { return std::move(value()); }
95
96 constexpr T* operator->() noexcept LIFETIMEBOUND { return &value(); }
97 constexpr const T* operator->() const noexcept LIFETIMEBOUND { return &value(); }
98};
99
100template <class E>
101class Expected<void, E>
102{
103private:
104 std::variant<std::monostate, E> m_data;
105
106public:
107 constexpr Expected() : m_data{std::in_place_index<0>, std::monostate{}} {}
108 template <class Err>
109 constexpr Expected(Unexpected<Err> u) : m_data{std::in_place_index<1>, std::move(u).error()}
110 {
111 }
112
113 constexpr bool has_value() const noexcept { return m_data.index() == 0; }
114 constexpr explicit operator bool() const noexcept { return has_value(); }
115
116 constexpr void operator*() const noexcept { return value(); }
117 constexpr void value() const
118 {
119 if (!has_value()) {
120 throw BadExpectedAccess{};
121 }
122 }
123
124 constexpr const E& error() const& noexcept LIFETIMEBOUND { return *Assert(std::get_if<1>(&m_data)); }
125 constexpr E& error() & noexcept LIFETIMEBOUND { return *Assert(std::get_if<1>(&m_data)); }
126 constexpr E&& error() && noexcept LIFETIMEBOUND { return std::move(error()); }
127};
128
129} // namespace util
130
131#endif // BITCOIN_UTIL_EXPECTED_H
#define LIFETIMEBOUND
Definition: attributes.h:16
#define Assert(val)
Identity function.
Definition: check.h:116
constexpr bool has_value() const noexcept
Definition: expected.h:113
constexpr void value() const
Definition: expected.h:117
constexpr Expected(Unexpected< Err > u)
Definition: expected.h:109
std::variant< std::monostate, E > m_data
Definition: expected.h:104
constexpr const E & error() const &noexcept LIFETIMEBOUND
Definition: expected.h:124
constexpr void operator*() const noexcept
Definition: expected.h:116
constexpr E & error() &noexcept LIFETIMEBOUND
Definition: expected.h:125
constexpr E && error() &&noexcept LIFETIMEBOUND
Definition: expected.h:126
The util::Expected class provides a standard way for low-level functions to return either error value...
Definition: expected.h:44
constexpr T & operator*() &noexcept LIFETIMEBOUND
Definition: expected.h:92
T value_or(U &&default_value) const &
Definition: expected.h:76
constexpr const T * operator->() const noexcept LIFETIMEBOUND
Definition: expected.h:97
constexpr E && error() &&noexcept LIFETIMEBOUND
Definition: expected.h:88
constexpr E & error() &noexcept LIFETIMEBOUND
Definition: expected.h:87
T value_or(U &&default_value) &&
Definition: expected.h:81
std::variant< T, E > m_data
Definition: expected.h:46
constexpr Expected(T v)
Definition: expected.h:50
constexpr T & value() &LIFETIMEBOUND
Definition: expected.h:66
constexpr const T & operator*() const &noexcept LIFETIMEBOUND
Definition: expected.h:93
constexpr T * operator->() noexcept LIFETIMEBOUND
Definition: expected.h:96
constexpr bool has_value() const noexcept
Definition: expected.h:56
constexpr T && value() &&LIFETIMEBOUND
Definition: expected.h:73
constexpr const T & value() const &LIFETIMEBOUND
Definition: expected.h:59
constexpr Expected()
Definition: expected.h:49
constexpr Expected(Unexpected< Err > u)
Definition: expected.h:52
constexpr const E & error() const &noexcept LIFETIMEBOUND
Definition: expected.h:86
constexpr T && operator*() &&noexcept LIFETIMEBOUND
Definition: expected.h:94
constexpr void swap(Expected &other) noexcept
Definition: expected.h:90
The util::Unexpected class represents an unexpected value stored in util::Expected.
Definition: expected.h:21
constexpr E & error() &noexcept LIFETIMEBOUND
Definition: expected.h:26
constexpr const E & error() const &noexcept LIFETIMEBOUND
Definition: expected.h:25
constexpr E && error() &&noexcept LIFETIMEBOUND
Definition: expected.h:27
constexpr Unexpected(E e)
Definition: expected.h:23
#define T(expected, seed, data)
Definition: common.h:30
const char * what() const noexcept override
Definition: expected.h:34
#define E
Definition: util_tests.cpp:563