From 2a7435e026b114d92809959ca51f96c05572cc07 Mon Sep 17 00:00:00 2001 From: koe Date: Sun, 12 Feb 2023 13:00:53 -0600 Subject: variant: add mutable unwrap and visitation --- src/common/variant.h | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src') 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 @@ -70,6 +69,7 @@ struct variant_static_visitor : public boost::static_visitor { /// 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 bool is_type() const noexcept { return this->index() == this->type_index_of(); } - /// 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 - const T* try_unwrap() const + T* try_unwrap() noexcept { return boost::strict_get< T>(&m_value); } + template + const T* try_unwrap() const noexcept { return boost::strict_get(&m_value); } + + /// get a handle to the embedded value + template + T& unwrap() { - return boost::strict_get(&m_value); + T *value_ptr{this->try_unwrap()}; + if (!value_ptr) variant_unwrap_err(); + return *value_ptr; } - - /// get a read-only handle to the embedded value template const T& unwrap() const { @@ -131,7 +137,7 @@ public: static constexpr int type_index_of() noexcept { using types = boost::mpl::vector; - using elem = typename boost::mpl::find::type; + using elem = typename boost::mpl::find::type; using begin = typename boost::mpl::begin::type; return boost::mpl::distance::value; } @@ -142,6 +148,11 @@ public: /// apply a visitor to the variant template + typename VisitorT::result_type visit(VisitorT &&visitor) + { + return boost::apply_visitor(std::forward(visitor), m_value); + } + template typename VisitorT::result_type visit(VisitorT &&visitor) const { return boost::apply_visitor(std::forward(visitor), m_value); -- cgit v1.2.3