mirror of
https://github.com/RPCS3/cereal.git
synced 2026-01-31 01:25:20 +01:00
MSVC support for doctest, boost variant serialization
This commit is contained in:
@@ -30,6 +30,13 @@
|
||||
#ifndef CEREAL_TYPES_BOOST_VARIANT_HPP_
|
||||
#define CEREAL_TYPES_BOOST_VARIANT_HPP_
|
||||
|
||||
//! @internal
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1911
|
||||
#define CEREAL_CONSTEXPR_LAMBDA
|
||||
#else // MSVC 2017 or newer, all other compilers
|
||||
#define CEREAL_CONSTEXPR_LAMBDA constexpr
|
||||
#endif
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
@@ -45,65 +52,65 @@ namespace cereal
|
||||
variant_save_visitor(Archive & ar_) : ar(ar_) {}
|
||||
|
||||
template<class T>
|
||||
void operator()(T const & value) const
|
||||
{
|
||||
ar( CEREAL_NVP_("data", value) );
|
||||
}
|
||||
void operator()(T const & value) const
|
||||
{
|
||||
ar( CEREAL_NVP_("data", value) );
|
||||
}
|
||||
|
||||
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);
|
||||
T value;
|
||||
ar( CEREAL_NVP_("data", value) );
|
||||
variant = std::move(value);
|
||||
}
|
||||
|
||||
//! @internal
|
||||
template <class Archive, class T>
|
||||
struct LoadAndConstructLoadWrapper
|
||||
{
|
||||
using ST = typename std::aligned_storage<sizeof(T), CEREAL_ALIGNOF(T)>::type;
|
||||
using ST = typename std::aligned_storage<sizeof(T), CEREAL_ALIGNOF(T)>::type;
|
||||
|
||||
LoadAndConstructLoadWrapper() :
|
||||
construct( reinterpret_cast<T *>( &st ) )
|
||||
{ }
|
||||
LoadAndConstructLoadWrapper() :
|
||||
construct( reinterpret_cast<T *>( &st ) )
|
||||
{ }
|
||||
|
||||
~LoadAndConstructLoadWrapper()
|
||||
~LoadAndConstructLoadWrapper()
|
||||
{
|
||||
if (construct.itsValid)
|
||||
{
|
||||
if (construct.itsValid)
|
||||
{
|
||||
construct->~T();
|
||||
}
|
||||
construct->~T();
|
||||
}
|
||||
}
|
||||
|
||||
void CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar )
|
||||
{
|
||||
::cereal::detail::Construct<T, Archive>::load_andor_construct( ar, construct );
|
||||
}
|
||||
void CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar )
|
||||
{
|
||||
::cereal::detail::Construct<T, Archive>::load_andor_construct( ar, construct );
|
||||
}
|
||||
|
||||
ST st;
|
||||
::cereal::construct<T> construct;
|
||||
ST st;
|
||||
::cereal::construct<T> construct;
|
||||
};
|
||||
|
||||
//! @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)
|
||||
{
|
||||
LoadAndConstructLoadWrapper<Archive, T> loadWrapper;
|
||||
LoadAndConstructLoadWrapper<Archive, T> loadWrapper;
|
||||
|
||||
ar( CEREAL_NVP_("data", loadWrapper) );
|
||||
variant = std::move(*loadWrapper.construct.ptr());
|
||||
ar( CEREAL_NVP_("data", loadWrapper) );
|
||||
variant = std::move(*loadWrapper.construct.ptr());
|
||||
}
|
||||
|
||||
} // namespace boost_variant_detail
|
||||
|
||||
//! Saving for boost::variant
|
||||
template <class Archive, typename... VariantTypes> inline
|
||||
template <class Archive, typename ... VariantTypes> inline
|
||||
void CEREAL_SAVE_FUNCTION_NAME( Archive & ar, boost::variant<VariantTypes...> const & variant )
|
||||
{
|
||||
int32_t which = variant.which();
|
||||
@@ -113,14 +120,14 @@ namespace cereal
|
||||
}
|
||||
|
||||
//! Loading for boost::variant
|
||||
template <class Archive, typename... VariantTypes> inline
|
||||
template <class Archive, typename ... VariantTypes> inline
|
||||
void CEREAL_LOAD_FUNCTION_NAME( Archive & ar, boost::variant<VariantTypes...> & variant )
|
||||
{
|
||||
int32_t which;
|
||||
ar( CEREAL_NVP_("which", which) );
|
||||
|
||||
using LoadFuncType = void(*)(Archive &, boost::variant<VariantTypes...> &);
|
||||
constexpr LoadFuncType loadFuncArray[] = {&boost_variant_detail::load_variant<VariantTypes>...};
|
||||
CEREAL_CONSTEXPR_LAMBDA LoadFuncType loadFuncArray[] = {&boost_variant_detail::load_variant<VariantTypes>...};
|
||||
|
||||
if(which >= int32_t(sizeof(loadFuncArray)/sizeof(loadFuncArray[0])))
|
||||
throw Exception("Invalid 'which' selector when deserializing boost::variant");
|
||||
@@ -129,4 +136,6 @@ namespace cereal
|
||||
}
|
||||
} // namespace cereal
|
||||
|
||||
#undef CEREAL_CONSTEXPR_LAMBDA
|
||||
|
||||
#endif // CEREAL_TYPES_BOOST_VARIANT_HPP_
|
||||
|
||||
@@ -302,7 +302,11 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom constr
|
||||
#define DOCTEST_ALIGNMENT(x)
|
||||
#define DOCTEST_NORETURN __declspec(noreturn)
|
||||
#ifndef DOCTEST_THREAD_LOCAL
|
||||
#if DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)
|
||||
#define DOCTEST_THREAD_LOCAL /* not supported */
|
||||
#else
|
||||
#define DOCTEST_THREAD_LOCAL __declspec(thread)
|
||||
#endif // MSVC version
|
||||
#endif // THREAD_LOCAL
|
||||
#else // MSVC
|
||||
#define DOCTEST_NOINLINE __attribute__((noinline))
|
||||
|
||||
Reference in New Issue
Block a user