/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 |