Skip to content

Commit

Permalink
MSVC variant support
Browse files Browse the repository at this point in the history
  • Loading branch information
AzothAmmo committed Oct 23, 2019
1 parent 32f71b1 commit df229ce
Showing 1 changed file with 41 additions and 18 deletions.
59 changes: 41 additions & 18 deletions include/cereal/types/boost_variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,6 @@ namespace cereal
Archive & ar;
};

//! @internal
template<class T, class Variant, class Archive>
typename std::enable_if<std::is_default_constructible<T>::value>::type
load_variant(Archive & ar, Variant & variant)
{
T value;
ar( CEREAL_NVP_("data", value) );
variant = std::move(value);
}

//! @internal
template <class Archive, class T>
struct LoadAndConstructLoadWrapper
Expand Down Expand Up @@ -98,15 +88,48 @@ namespace cereal
};

//! @internal
template<class T, class Variant, class Archive>
typename std::enable_if<!std::is_default_constructible<T>::value>::type
load_variant(Archive & ar, Variant & variant)
template <class T> struct load_variant_wrapper;

//! Avoid serializing variant void_ type
/*! @internal */
template <>
struct load_variant_wrapper<boost::detail::variant::void_>
{
LoadAndConstructLoadWrapper<Archive, T> loadWrapper;
template <class Variant, class Archive>
static void load_variant( Archive &, Variant & )
{ }
};

ar( CEREAL_NVP_("data", loadWrapper) );
variant = std::move(*loadWrapper.construct.ptr());
}
//! @internal
template <class T>
struct load_variant_wrapper
{
// default constructible
template <class Archive, class Variant>
static void load_variant_impl( Archive & ar, Variant & variant, std::true_type )
{
T value;
ar( CEREAL_NVP_("data", value) );
variant = std::move(value);
}

// not default constructible
template<class Variant, class Archive>
static void load_variant_impl(Archive & ar, Variant & variant, std::false_type )
{
LoadAndConstructLoadWrapper<Archive, T> loadWrapper;

ar( CEREAL_NVP_("data", loadWrapper) );
variant = std::move(*loadWrapper.construct.ptr());
}

//! @internal
template<class Variant, class Archive>
static void load_variant(Archive & ar, Variant & variant)
{
load_variant_impl( ar, variant, typename std::is_default_constructible<T>::type() );
}
};
} // namespace boost_variant_detail

//! Saving for boost::variant
Expand All @@ -127,7 +150,7 @@ namespace cereal
ar( CEREAL_NVP_("which", which) );

using LoadFuncType = void(*)(Archive &, boost::variant<VariantTypes...> &);
CEREAL_CONSTEXPR_LAMBDA LoadFuncType loadFuncArray[] = {&boost_variant_detail::load_variant<VariantTypes>...};
CEREAL_CONSTEXPR_LAMBDA LoadFuncType loadFuncArray[] = {&boost_variant_detail::load_variant_wrapper<VariantTypes>::load_variant...};

if(which >= int32_t(sizeof(loadFuncArray)/sizeof(loadFuncArray[0])))
throw Exception("Invalid 'which' selector when deserializing boost::variant");
Expand Down

0 comments on commit df229ce

Please sign in to comment.