Coverage Report

Created: 2024-10-21 15:10

/root/bitcoin/src/util/result.h
Line
Count
Source (jump to first uncovered line)
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 {
16
    bilingual_str message;
17
};
18
19
//! The util::Result class provides a standard way for functions to return
20
//! either error messages or result values.
21
//!
22
//! It is intended for high-level functions that need to report error strings to
23
//! end users. Lower-level functions that don't need this error-reporting and
24
//! only need error-handling should avoid util::Result and instead use standard
25
//! classes like std::optional, std::variant, and std::tuple, or custom structs
26
//! and enum types to return function results.
27
//!
28
//! Usage examples can be found in \example ../test/result_tests.cpp, but in
29
//! general code returning `util::Result<T>` values is very similar to code
30
//! returning `std::optional<T>` values. Existing functions returning
31
//! `std::optional<T>` can be updated to return `util::Result<T>` and return
32
//! error strings usually just replacing `return std::nullopt;` with `return
33
//! util::Error{error_string};`.
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
42
    //! Disallow copy constructor, require Result to be moved for efficiency.
43
    Result(const Result&) = delete;
44
45
    //! Disallow operator= to avoid confusion in the future when the Result
46
    //! class gains support for richer error reporting, and callers should have
47
    //! ability to set a new result value without clearing existing error
48
    //! messages.
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
0
    Result() : m_variant{std::in_place_index_t<1>{}, std::monostate{}} {}  // constructor for void
57
0
    Result(T obj) : m_variant{std::in_place_index_t<1>{}, std::move(obj)} {}
Unexecuted instantiation: _ZN4util6ResultIiEC2Ei
Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEC2ES2_
Unexecuted instantiation: _ZN4util6ResultISt7variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEC2ESB_
Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEC2ES2_
Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEEC2ES2_
Unexecuted instantiation: _ZN4util6ResultIN2fs4pathEEC2ES2_
Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEEC2ES2_
Unexecuted instantiation: _ZN4util6ResultISt10shared_ptrIK12CTransactionEEC2ES4_
Unexecuted instantiation: _ZN4util6ResultISt10unique_ptrIN10interfaces6WalletESt14default_deleteIS3_EEEC2ES6_
Unexecuted instantiation: _ZN4util6ResultIN10interfaces21WalletMigrationResultEEC2ES2_
Unexecuted instantiation: _ZN4util6ResultISt10unique_ptrI7AddrManSt14default_deleteIS2_EEEC2ES5_
Unexecuted instantiation: _ZN4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEEC2ESP_
Unexecuted instantiation: _ZN4util6ResultISt4pairISt6vectorI7FeeFracSaIS3_EES5_EEC2ES6_
Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexEC2ES2_
58
0
    Result(Error error) : m_variant{std::in_place_index_t<0>{}, std::move(error.message)} {}
Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultIiEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultISt7variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultIN2fs4pathEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultIvEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultISt10shared_ptrIK12CTransactionEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultISt10unique_ptrIN10interfaces6WalletESt14default_deleteIS3_EEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultIN10interfaces21WalletMigrationResultEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultISt10unique_ptrI7AddrManSt14default_deleteIS2_EEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultISt4pairISt6vectorI7FeeFracSaIS3_EES5_EEC2ENS_5ErrorE
Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexEC2ENS_5ErrorE
59
0
    Result(Result&&) = default;
Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEC2EOS3_
Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEC2EOS3_
60
0
    ~Result() = default;
Unexecuted instantiation: _ZN4util6ResultISt4pairISt6vectorI7FeeFracSaIS3_EES5_EED2Ev
Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexED2Ev
Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEED2Ev
Unexecuted instantiation: _ZN4util6ResultISt7variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEED2Ev
Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEED2Ev
Unexecuted instantiation: _ZN4util6ResultIiED2Ev
Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEED2Ev
Unexecuted instantiation: _ZN4util6ResultIvED2Ev
Unexecuted instantiation: _ZN4util6ResultIN2fs4pathEED2Ev
Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEED2Ev
Unexecuted instantiation: _ZN4util6ResultISt10unique_ptrI7AddrManSt14default_deleteIS2_EEED2Ev
Unexecuted instantiation: _ZN4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEED2Ev
61
62
    //! std::optional methods, so functions returning optional<T> can change to
63
    //! return Result<T> with minimal changes to existing code, and vice versa.
64
0
    bool has_value() const noexcept { return m_variant.index() == 1; }
Unexecuted instantiation: _ZNK4util6ResultISt4pairISt6vectorI7FeeFracSaIS3_EES5_EE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultIP11CBlockIndexE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultIN6wallet15SelectionResultEE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultISt7variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultIiE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultIN6wallet17PreSelectedInputsEE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultIvE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultIN6wallet24CreatedTransactionResultEE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultIN2fs4pathEE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultIN6wallet15MigrationResultEE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultISt10unique_ptrI7AddrManSt14default_deleteIS2_EEE9has_valueEv
Unexecuted instantiation: _ZNK4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEE9has_valueEv
65
    const T& value() const LIFETIMEBOUND
66
0
    {
67
0
        assert(has_value());
68
0
        return std::get<1>(m_variant);
69
0
    }
Unexecuted instantiation: _ZNK4util6ResultIiE5valueEv
Unexecuted instantiation: _ZNK4util6ResultIN2fs4pathEE5valueEv
Unexecuted instantiation: _ZNK4util6ResultISt4pairISt6vectorI7FeeFracSaIS3_EES5_EE5valueEv
70
    T& value() LIFETIMEBOUND
71
0
    {
72
0
        assert(has_value());
73
0
        return std::get<1>(m_variant);
74
0
    }
Unexecuted instantiation: _ZN4util6ResultISt4pairISt6vectorI7FeeFracSaIS3_EES5_EE5valueEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEE5valueEv
Unexecuted instantiation: _ZN4util6ResultISt7variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEE5valueEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEE5valueEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEE5valueEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEE5valueEv
Unexecuted instantiation: _ZN4util6ResultISt10unique_ptrI7AddrManSt14default_deleteIS2_EEE5valueEv
Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexE5valueEv
Unexecuted instantiation: _ZN4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEE5valueEv
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
0
    {
83
0
        return has_value() ? std::move(value()) : std::forward<U>(default_value);
84
0
    }
Unexecuted instantiation: _ZNO4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEE8value_orISP_EESP_OT_
Unexecuted instantiation: _ZNO4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEE8value_orIRSP_EESP_OT_
85
0
    explicit operator bool() const noexcept { return has_value(); }
Unexecuted instantiation: _ZNK4util6ResultIP11CBlockIndexEcvbEv
Unexecuted instantiation: _ZNK4util6ResultIN6wallet15SelectionResultEEcvbEv
Unexecuted instantiation: _ZNK4util6ResultISt7variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEcvbEv
Unexecuted instantiation: _ZNK4util6ResultIiEcvbEv
Unexecuted instantiation: _ZNK4util6ResultIN6wallet17PreSelectedInputsEEcvbEv
Unexecuted instantiation: _ZNK4util6ResultIvEcvbEv
Unexecuted instantiation: _ZNK4util6ResultIN6wallet24CreatedTransactionResultEEcvbEv
Unexecuted instantiation: _ZNK4util6ResultIN2fs4pathEEcvbEv
Unexecuted instantiation: _ZNK4util6ResultIN6wallet15MigrationResultEEcvbEv
Unexecuted instantiation: _ZNK4util6ResultISt10unique_ptrI7AddrManSt14default_deleteIS2_EEEcvbEv
Unexecuted instantiation: _ZNK4util6ResultISt4pairISt6vectorI7FeeFracSaIS3_EES5_EEcvbEv
Unexecuted instantiation: _ZNK4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEEcvbEv
86
    const T* operator->() const LIFETIMEBOUND { return &value(); }
87
0
    const T& operator*() const LIFETIMEBOUND { return value(); }
88
0
    T* operator->() LIFETIMEBOUND { return &value(); }
Unexecuted instantiation: _ZN4util6ResultISt4pairISt6vectorI7FeeFracSaIS3_EES5_EEptEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEptEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEptEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEEptEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEEptEv
89
0
    T& operator*() LIFETIMEBOUND { return value(); }
Unexecuted instantiation: _ZN4util6ResultISt7variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEdeEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEEdeEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEdeEv
Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEdeEv
Unexecuted instantiation: _ZN4util6ResultISt10unique_ptrI7AddrManSt14default_deleteIS2_EEEdeEv
Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexEdeEv
Unexecuted instantiation: _ZN4util6ResultISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEEdeEv
90
};
91
92
template <typename T>
93
bilingual_str ErrorString(const Result<T>& result)
94
0
{
95
0
    return result ? bilingual_str{} : std::get<0>(result.m_variant);
96
0
}
Unexecuted instantiation: _ZN4util11ErrorStringIN6wallet15SelectionResultEEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringIiEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringISt7variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringIN6wallet17PreSelectedInputsEEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringIvEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringIN2fs4pathEEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringIN6wallet24CreatedTransactionResultEEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringIN6wallet15MigrationResultEEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringISt10unique_ptrI7AddrManSt14default_deleteIS2_EEEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringISt4pairISt6vectorI7FeeFracSaIS3_EES5_EEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringIP11CBlockIndexEE13bilingual_strRKNS_6ResultIT_EE
Unexecuted instantiation: _ZN4util11ErrorStringISt3setIN5boost11multi_index6detail21hashed_index_iteratorINS4_17hashed_index_nodeINS6_INS4_18ordered_index_nodeINS4_19null_augment_policyENS7_IS8_NS7_IS8_NS4_15index_node_baseI15CTxMemPoolEntrySaISA_EEEEEEEEEEEEENS4_12bucket_arrayISB_EENS4_17hashed_unique_tagENS4_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashSaISM_EEEE13bilingual_strRKNS_6ResultIT_EE
97
} // namespace util
98
99
#endif // BITCOIN_UTIL_RESULT_H