Skip to content

Commit 2bd3d06

Browse files
PastaPastaPastaknst
andcommitted
refactor: convert maybe_error into generic Result template class
This is a simple implementation of the Result type in C++. The Result type is a type that can either be an Ok value, which represents a successful operation and contains a value, or an Err value, which represents a failed operation and contains an error value. The Result class is a template class that takes two types: T, which is the type of the value that an Ok result will contain, and E, which is the type of the value that an Err result will contain. The Ok and Err structs are also templates, and are used to construct Ok and Err values. The Ok struct has an optional single member val_ of type T, and the Err struct has a single member val_ of type E. The Result class has a constructor that takes either an Ok value or an Err value, and stores the value internally. It also has several member functions that can be used to access the value of the Result and check whether it is an Ok or Err value. The is_ok() and is_err() member functions can be used to check whether the Result is an Ok or Err value, respectively. The operator bool() function allows the Result to be used in a boolean context, such as an if statement. The unwrap() and err() member functions can be used to get the value contained in the Result, but will assert if the Result is not of the expected type. For parametrizing maybe_error with Ok without value, should be used template Ok<void>, you can return just {} in this case as success. Co-Authored-By: Konstantin Akimov <[email protected]>
1 parent 3c65626 commit 2bd3d06

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ BITCOIN_CORE_H = \
317317
util/message.h \
318318
util/moneystr.h \
319319
util/ranges.h \
320+
util/result.h \
320321
util/underlying.h \
321322
util/serfloat.h \
322323
util/settings.h \

src/util/result.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (c) 2023 The Dash Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_UTIL_RESULT_H
6+
#define BITCOIN_UTIL_RESULT_H
7+
8+
#include <cassert>
9+
#include <utility> // for std::move()
10+
#include <variant>
11+
12+
template<typename T>
13+
struct Ok {
14+
constexpr explicit Ok(T val) : val_(std::move(val)) {}
15+
const T val_;
16+
};
17+
18+
// Specialization of the Ok struct for void type
19+
template<>
20+
struct Ok<void> {
21+
constexpr Ok() = default;
22+
};
23+
24+
template<typename E>
25+
struct Err {
26+
constexpr explicit Err(E val) : val_(std::move(val)) {}
27+
28+
template<typename... Ts>
29+
constexpr explicit Err(Ts...t) : val_{t...} {}
30+
31+
const E val_;
32+
};
33+
34+
template<typename T, typename E>
35+
class Result {
36+
public:
37+
constexpr Result(Ok<T> val) : result{val} {}
38+
template<typename... Ts>
39+
constexpr Result(Ts... t) : result{Ok<T>{t...}} {}
40+
constexpr Result(Err<E> err) : result{err.val_} {}
41+
42+
[[nodiscard]] constexpr bool is_ok() const { return std::holds_alternative<Ok<T>>(result); }
43+
[[nodiscard]] constexpr bool is_err() const { return !is_ok(); }
44+
45+
[[nodiscard]] constexpr explicit operator bool() const {
46+
return is_ok();
47+
}
48+
49+
template<typename U = T>
50+
[[nodiscard]] constexpr const U& operator*() const {
51+
return unwrap();
52+
}
53+
54+
template<typename U = T>
55+
[[nodiscard]] constexpr const U& unwrap() const {
56+
assert(is_ok());
57+
return std::get<Ok<U>>(result).val_;
58+
}
59+
60+
[[nodiscard]] constexpr const E& err() const {
61+
assert(is_err());
62+
return std::get<E>(result);
63+
}
64+
65+
private:
66+
std::variant<Ok<T>, E> result;
67+
};
68+
69+
#endif

0 commit comments

Comments
 (0)