/Users/eugenesiegel/btc/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 | 299k | 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: _ZN4util6ResultINSt3__110shared_ptrIK12CTransactionEEEC2ES5_ Unexecuted instantiation: _ZN4util6ResultINSt3__110unique_ptrIN10interfaces6WalletENS1_14default_deleteIS4_EEEEEC2ES7_ Unexecuted instantiation: _ZN4util6ResultIN10interfaces21WalletMigrationResultEEC2ES2_ Unexecuted instantiation: _ZN4util6ResultINSt3__17variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEEC2ESC_ Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEC2ES2_ Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEEC2ES2_ Unexecuted instantiation: _ZN4util6ResultIN2fs4pathEEC2ES2_ Unexecuted instantiation: _ZN4util6ResultIPN6wallet15ScriptPubKeyManEEC2ES3_ Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEEC2ES2_ Unexecuted instantiation: _ZN4util6ResultINSt3__110unique_ptrI7AddrManNS1_14default_deleteIS3_EEEEEC2ES6_ Unexecuted instantiation: _ZN4util6ResultINSt3__13setIN5boost11multi_index6detail21hashed_index_iteratorINS5_17hashed_index_nodeINS7_INS5_18ordered_index_nodeINS5_19null_augment_policyENS8_IS9_NS8_IS9_NS5_15index_node_baseI15CTxMemPoolEntryNS1_9allocatorISB_EEEEEEEEEEEEEENS5_12bucket_arrayISD_EENS5_17hashed_unique_tagENS5_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashNSC_ISO_EEEEEC2ESR_ Unexecuted instantiation: _ZN4util6ResultINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_EEEC2ES8_ Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexEC2ES2_ |
58 | 0 | Result(Error error) : m_variant{std::in_place_index_t<0>{}, std::move(error.message)} {} Unexecuted instantiation: _ZN4util6ResultIiEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIvEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultINSt3__17variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultINSt3__110shared_ptrIK12CTransactionEEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultINSt3__110unique_ptrIN10interfaces6WalletENS1_14default_deleteIS4_EEEEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIN10interfaces21WalletMigrationResultEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIN2fs4pathEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIPN6wallet15ScriptPubKeyManEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultINSt3__110unique_ptrI7AddrManNS1_14default_deleteIS3_EEEEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultINSt3__13setIN5boost11multi_index6detail21hashed_index_iteratorINS5_17hashed_index_nodeINS7_INS5_18ordered_index_nodeINS5_19null_augment_policyENS8_IS9_NS8_IS9_NS5_15index_node_baseI15CTxMemPoolEntryNS1_9allocatorISB_EEEEEEEEEEEEEENS5_12bucket_arrayISD_EENS5_17hashed_unique_tagENS5_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashNSC_ISO_EEEEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_EEEC2ENS_5ErrorE Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexEC2ENS_5ErrorE |
59 | 0 | Result(Result&&) = default; Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEC2EOS3_ Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEC2EOS3_ Unexecuted instantiation: _ZN4util6ResultIPN6wallet15ScriptPubKeyManEEC2EOS4_ |
60 | 299k | ~Result() = default; Unexecuted instantiation: _ZN4util6ResultINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_EEED2Ev Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexED2Ev Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEED2Ev Unexecuted instantiation: _ZN4util6ResultIPN6wallet15ScriptPubKeyManEED2Ev Unexecuted instantiation: _ZN4util6ResultINSt3__17variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEED2Ev Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEED2Ev Unexecuted instantiation: _ZN4util6ResultIiED2Ev Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEED2Ev Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEED2Ev Line | Count | Source | 60 | 299k | ~Result() = default; |
Unexecuted instantiation: _ZN4util6ResultIN2fs4pathEED2Ev Unexecuted instantiation: _ZN4util6ResultINSt3__110unique_ptrI7AddrManNS1_14default_deleteIS3_EEEEED2Ev Unexecuted instantiation: _ZN4util6ResultINSt3__13setIN5boost11multi_index6detail21hashed_index_iteratorINS5_17hashed_index_nodeINS7_INS5_18ordered_index_nodeINS5_19null_augment_policyENS8_IS9_NS8_IS9_NS5_15index_node_baseI15CTxMemPoolEntryNS1_9allocatorISB_EEEEEEEEEEEEEENS5_12bucket_arrayISD_EENS5_17hashed_unique_tagENS5_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashNSC_ISO_EEEEED2Ev |
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 | 299k | bool has_value() const noexcept { return m_variant.index() == 1; } Unexecuted instantiation: _ZNK4util6ResultINSt3__13setIN5boost11multi_index6detail21hashed_index_iteratorINS5_17hashed_index_nodeINS7_INS5_18ordered_index_nodeINS5_19null_augment_policyENS8_IS9_NS8_IS9_NS5_15index_node_baseI15CTxMemPoolEntryNS1_9allocatorISB_EEEEEEEEEEEEEENS5_12bucket_arrayISD_EENS5_17hashed_unique_tagENS5_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashNSC_ISO_EEEEE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_EEE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultIP11CBlockIndexE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultIN6wallet15SelectionResultEE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultIPN6wallet15ScriptPubKeyManEE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultINSt3__17variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultIiE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultIN6wallet24CreatedTransactionResultEE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultIN6wallet17PreSelectedInputsEE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultIN6wallet15MigrationResultEE9has_valueEv _ZNK4util6ResultIvE9has_valueEv Line | Count | Source | 64 | 299k | bool has_value() const noexcept { return m_variant.index() == 1; } |
Unexecuted instantiation: _ZNK4util6ResultIN2fs4pathEE9has_valueEv Unexecuted instantiation: _ZNK4util6ResultINSt3__110unique_ptrI7AddrManNS1_14default_deleteIS3_EEEEE9has_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: _ZNK4util6ResultINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_EEE5valueEv |
70 | | T& value() LIFETIMEBOUND |
71 | 0 | { |
72 | 0 | assert(has_value()); |
73 | 0 | return std::get<1>(m_variant); |
74 | 0 | } Unexecuted instantiation: _ZN4util6ResultINSt3__13setIN5boost11multi_index6detail21hashed_index_iteratorINS5_17hashed_index_nodeINS7_INS5_18ordered_index_nodeINS5_19null_augment_policyENS8_IS9_NS8_IS9_NS5_15index_node_baseI15CTxMemPoolEntryNS1_9allocatorISB_EEEEEEEEEEEEEENS5_12bucket_arrayISD_EENS5_17hashed_unique_tagENS5_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashNSC_ISO_EEEEE5valueEv Unexecuted instantiation: _ZN4util6ResultINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_EEE5valueEv Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEE5valueEv Unexecuted instantiation: _ZN4util6ResultIPN6wallet15ScriptPubKeyManEE5valueEv Unexecuted instantiation: _ZN4util6ResultINSt3__17variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEE5valueEv Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEE5valueEv Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEE5valueEv Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEE5valueEv Unexecuted instantiation: _ZN4util6ResultINSt3__110unique_ptrI7AddrManNS1_14default_deleteIS3_EEEEE5valueEv Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexE5valueEv |
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 | } |
85 | 299k | explicit operator bool() const noexcept { return has_value(); } Unexecuted instantiation: _ZNK4util6ResultINSt3__13setIN5boost11multi_index6detail21hashed_index_iteratorINS5_17hashed_index_nodeINS7_INS5_18ordered_index_nodeINS5_19null_augment_policyENS8_IS9_NS8_IS9_NS5_15index_node_baseI15CTxMemPoolEntryNS1_9allocatorISB_EEEEEEEEEEEEEENS5_12bucket_arrayISD_EENS5_17hashed_unique_tagENS5_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashNSC_ISO_EEEEEcvbEv Unexecuted instantiation: _ZNK4util6ResultIP11CBlockIndexEcvbEv Unexecuted instantiation: _ZNK4util6ResultIN6wallet15SelectionResultEEcvbEv Unexecuted instantiation: _ZNK4util6ResultIPN6wallet15ScriptPubKeyManEEcvbEv Unexecuted instantiation: _ZNK4util6ResultINSt3__17variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEEcvbEv Unexecuted instantiation: _ZNK4util6ResultIiEcvbEv Unexecuted instantiation: _ZNK4util6ResultIN6wallet24CreatedTransactionResultEEcvbEv Unexecuted instantiation: _ZNK4util6ResultIN6wallet17PreSelectedInputsEEcvbEv Unexecuted instantiation: _ZNK4util6ResultIN6wallet15MigrationResultEEcvbEv Line | Count | Source | 85 | 299k | explicit operator bool() const noexcept { return has_value(); } |
Unexecuted instantiation: _ZNK4util6ResultIN2fs4pathEEcvbEv Unexecuted instantiation: _ZNK4util6ResultINSt3__110unique_ptrI7AddrManNS1_14default_deleteIS3_EEEEEcvbEv Unexecuted instantiation: _ZNK4util6ResultINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_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: _ZN4util6ResultINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_EEEptEv Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEptEv Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEEptEv Unexecuted instantiation: _ZN4util6ResultIN6wallet15MigrationResultEEptEv Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEptEv |
89 | 0 | T& operator*() LIFETIMEBOUND { return value(); } Unexecuted instantiation: _ZN4util6ResultINSt3__13setIN5boost11multi_index6detail21hashed_index_iteratorINS5_17hashed_index_nodeINS7_INS5_18ordered_index_nodeINS5_19null_augment_policyENS8_IS9_NS8_IS9_NS5_15index_node_baseI15CTxMemPoolEntryNS1_9allocatorISB_EEEEEEEEEEEEEENS5_12bucket_arrayISD_EENS5_17hashed_unique_tagENS5_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashNSC_ISO_EEEEEdeEv Unexecuted instantiation: _ZN4util6ResultIN6wallet15SelectionResultEEdeEv Unexecuted instantiation: _ZN4util6ResultIPN6wallet15ScriptPubKeyManEEdeEv Unexecuted instantiation: _ZN4util6ResultINSt3__17variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEEdeEv Unexecuted instantiation: _ZN4util6ResultIN6wallet24CreatedTransactionResultEEdeEv Unexecuted instantiation: _ZN4util6ResultIN6wallet17PreSelectedInputsEEdeEv Unexecuted instantiation: _ZN4util6ResultINSt3__110unique_ptrI7AddrManNS1_14default_deleteIS3_EEEEEdeEv Unexecuted instantiation: _ZN4util6ResultIP11CBlockIndexEdeEv |
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: _ZN4util11ErrorStringIN6wallet24CreatedTransactionResultEEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringIN6wallet15MigrationResultEEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringINSt3__17variantIJ14CNoDestination17PubKeyDestination6PKHash10ScriptHash19WitnessV0ScriptHash16WitnessV0KeyHash16WitnessV1Taproot11PayToAnchor14WitnessUnknownEEEEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringIvEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringIPN6wallet15ScriptPubKeyManEEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringIN6wallet17PreSelectedInputsEEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringIN2fs4pathEEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringINSt3__110unique_ptrI7AddrManNS1_14default_deleteIS3_EEEEEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringINSt3__14pairINS1_6vectorI7FeeFracNS1_9allocatorIS4_EEEES7_EEEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringIP11CBlockIndexEE13bilingual_strRKNS_6ResultIT_EE Unexecuted instantiation: _ZN4util11ErrorStringINSt3__13setIN5boost11multi_index6detail21hashed_index_iteratorINS5_17hashed_index_nodeINS7_INS5_18ordered_index_nodeINS5_19null_augment_policyENS8_IS9_NS8_IS9_NS5_15index_node_baseI15CTxMemPoolEntryNS1_9allocatorISB_EEEEEEEEEEEEEENS5_12bucket_arrayISD_EENS5_17hashed_unique_tagENS5_32hashed_index_global_iterator_tagEEE21CompareIteratorByHashNSC_ISO_EEEEEE13bilingual_strRKNS_6ResultIT_EE |
97 | | } // namespace util |
98 | | |
99 | | #endif // BITCOIN_UTIL_RESULT_H |