aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorkoe <ukoe@protonmail.com>2023-02-12 13:00:53 -0600
committerkoe <ukoe@protonmail.com>2023-02-12 13:00:53 -0600
commit2a7435e026b114d92809959ca51f96c05572cc07 (patch)
treea8c2bb2360e4288a4fcc6ee04036799d534e6dcb /src/common
parentadd variant class with cleaner interface than boost::variant<> (diff)
downloadmonero-2a7435e026b114d92809959ca51f96c05572cc07.tar.xz
variant: add mutable unwrap and visitation
Diffstat (limited to 'src/common')
-rw-r--r--src/common/variant.h25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/common/variant.h b/src/common/variant.h
index a2121c75e..ffb34e40a 100644
--- a/src/common/variant.h
+++ b/src/common/variant.h
@@ -62,7 +62,6 @@ namespace tools
////
// variant: convenience wrapper around boost::variant with a cleaner interface
-// - the value may be assigned to but is otherwise read-only
// - the variant is 'optional' - an empty variant will evaluate to 'false' and an initialized variant will be 'true'
///
template <typename ResultT>
@@ -70,6 +69,7 @@ struct variant_static_visitor : public boost::static_visitor<ResultT>
{
/// provide visitation for empty variants
/// - add this to your visitor with: using variant_static_visitor::operator();
+ [[noreturn]] ResultT operator()(const boost::blank) { variant_static_visitor_blank_err(); }
[[noreturn]] ResultT operator()(const boost::blank) const { variant_static_visitor_blank_err(); }
};
@@ -107,14 +107,20 @@ public:
template <typename T>
bool is_type() const noexcept { return this->index() == this->type_index_of<T>(); }
- /// try to get a read-only handle to the embedded value (return nullptr on failure)
+ /// try to get a handle to the embedded value (return nullptr on failure)
template <typename T>
- const T* try_unwrap() const
+ T* try_unwrap() noexcept { return boost::strict_get< T>(&m_value); }
+ template <typename T>
+ const T* try_unwrap() const noexcept { return boost::strict_get<const T>(&m_value); }
+
+ /// get a handle to the embedded value
+ template <typename T>
+ T& unwrap()
{
- return boost::strict_get<T>(&m_value);
+ T *value_ptr{this->try_unwrap<T>()};
+ if (!value_ptr) variant_unwrap_err();
+ return *value_ptr;
}
-
- /// get a read-only handle to the embedded value
template <typename T>
const T& unwrap() const
{
@@ -131,7 +137,7 @@ public:
static constexpr int type_index_of() noexcept
{
using types = boost::mpl::vector<boost::blank, Types...>;
- using elem = typename boost::mpl::find<types, T>::type;
+ using elem = typename boost::mpl::find<types, T>::type;
using begin = typename boost::mpl::begin<types>::type;
return boost::mpl::distance<begin, elem>::value;
}
@@ -142,6 +148,11 @@ public:
/// apply a visitor to the variant
template <typename VisitorT>
+ typename VisitorT::result_type visit(VisitorT &&visitor)
+ {
+ return boost::apply_visitor(std::forward<VisitorT>(visitor), m_value);
+ }
+ template <typename VisitorT>
typename VisitorT::result_type visit(VisitorT &&visitor) const
{
return boost::apply_visitor(std::forward<VisitorT>(visitor), m_value);