From 5bfab6e795b95014b69c0d71d5f844a47d789c0d Mon Sep 17 00:00:00 2001 From: koe Date: Mon, 20 May 2024 16:40:13 -0500 Subject: [PATCH] split variant into plain and optional, add variant serialization --- src/common/variant.h | 49 ++++++++++++++++++++++++++++--------- src/serialization/variant.h | 11 +++++++++ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/common/variant.h b/src/common/variant.h index ffb34e40a78..8c68e37150f 100644 --- a/src/common/variant.h +++ b/src/common/variant.h @@ -74,15 +74,14 @@ struct variant_static_visitor : public boost::static_visitor }; template -class variant final +class variant { - using VType = boost::variant; + using VType = boost::variant; public: //constructors /// default constructor variant() = default; - variant(boost::none_t) : variant{} {} //act like boost::optional /// construct from variant type (use enable_if to avoid issues with copy/move constructor) template ::type = true> variant(T &&value) : m_value{std::forward(value)} {} -//overloaded operators - /// boolean operator: true if the variant isn't empty/uninitialized - explicit operator bool() const noexcept { return !this->is_empty(); } - //member functions - /// check if empty/uninitialized - bool is_empty() const noexcept { return m_value.which() == 0; } - /// check the variant type template bool is_type() const noexcept { return this->index() == this->type_index_of(); } @@ -136,7 +128,7 @@ class variant final template static constexpr int type_index_of() noexcept { - using types = boost::mpl::vector; + using types = typename VType::types; using elem = typename boost::mpl::find::type; using begin = typename boost::mpl::begin::type; return boost::mpl::distance::value; @@ -162,6 +154,41 @@ class variant final //member variables /// variant of all value types VType m_value; + +//friend functions +template +friend bool do_serialize(Archive &ar, variant &v); +}; + +template +class optional_variant: public variant +{ +public: +//constructors + /// default constructor + optional_variant() = default; + + /// construct from variant type (use enable_if to avoid issues with copy/move constructor) + template >, + optional_variant + >::value, + bool + >::type = true> + optional_variant(T &&value) : variant(std::forward(value)) {} + + // construct like boost::optional + optional_variant(boost::none_t) {} + +//overloaded operators + /// boolean operator: true if the variant isn't empty/uninitialized + explicit operator bool() const noexcept { return !this->is_empty(); } + +//member functions + /// check if empty/uninitialized + bool is_empty() const noexcept { return this->index() == 0; } }; } //namespace tools diff --git a/src/serialization/variant.h b/src/serialization/variant.h index 1cf93c8cffe..a2d90a6800b 100644 --- a/src/serialization/variant.h +++ b/src/serialization/variant.h @@ -43,6 +43,7 @@ #include #include #include +#include "common/variant.h" #include "serialization.h" /*! \struct variant_serialization_triats @@ -144,3 +145,13 @@ static bool do_serialize(Archive &ar, boost::variant &v) { return boost::apply_visitor(variant_write_visitor(ar), v); } + +// implementation for tools::variant delegates to internal boost::variant member field +namespace tools +{ +template +bool do_serialize(Archive &ar, variant &v) +{ + return do_serialize(ar, v.m_value); +} +}