LCOV - code coverage report

Current view: | top level - cereal/types - boost_variant.hpp (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 39 | 40 | 97.5 %
Date: | 2022-01-16 21:05:07 |  | Functions: | 72 | 72 | 100.0 %

              Line data    Source code

           1             : /*! \file boost_variant.hpp
           2             :     \brief Support for boost::variant
           3             :     \ingroup OtherTypes */
           4             : /*
           5             :   Copyright (c) 2014, Randolph Voorhies, Shane Grant
           6             :   All rights reserved.
           7             :
           8             :   Redistribution and use in source and binary forms, with or without
           9             :   modification, are permitted provided that the following conditions are met:
          10             :       * Redistributions of source code must retain the above copyright
          11             :         notice, this list of conditions and the following disclaimer.
          12             :       * Redistributions in binary form must reproduce the above copyright
          13             :         notice, this list of conditions and the following disclaimer in the
          14             :         documentation and/or other materials provided with the distribution.
          15             :       * Neither the name of the copyright holder nor the
          16             :         names of its contributors may be used to endorse or promote products
          17             :         derived from this software without specific prior written permission.
          18             :
          19             :   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
          20             :   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
          21             :   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
          22             :   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
          23             :   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
          24             :   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
          25             :   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
          26             :   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
          27             :   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
          28             :   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
          29             : */
          30             : #ifndef CEREAL_TYPES_BOOST_VARIANT_HPP_
          31             : #define CEREAL_TYPES_BOOST_VARIANT_HPP_
          32             :
          33             : //! @internal
          34             : #if defined(_MSC_VER) && _MSC_VER < 1911
          35             : #define CEREAL_CONSTEXPR_LAMBDA
          36             : #else // MSVC 2017 or newer, all other compilers
          37             : #define CEREAL_CONSTEXPR_LAMBDA constexpr
          38             : #endif
          39             :
          40             : #include "cereal/cereal.hpp"
          41             : #include <boost/variant/variant_fwd.hpp>
          42             : #include <boost/variant/static_visitor.hpp>
          43             :
          44             : namespace cereal
          45             : {
          46             :   namespace boost_variant_detail
          47             :   {
          48             :     //! @internal
          49             :     template <class Archive>
          50             :     struct variant_save_visitor : boost::static_visitor<>
          51             :     {
          52          16 :       variant_save_visitor(Archive & ar_) : ar(ar_) {}
          53             :
          54             :       template<class T>
          55          16 :       void operator()(T const & value) const
          56             :       {
          57          16 :         ar( CEREAL_NVP_("data", value) );
          58          16 :       }
          59             :
          60             :       Archive & ar;
          61             :     };
          62             :
          63             :     //! @internal
          64             :     template <class Archive, class T>
          65             :     struct LoadAndConstructLoadWrapper
          66             :     {
          67             :       using ST = typename std::aligned_storage<sizeof(T), CEREAL_ALIGNOF(T)>::type;
          68             :
          69           4 :       LoadAndConstructLoadWrapper() :
          70           4 :         construct( reinterpret_cast<T *>( &st ) )
          71           4 :       { }
          72             :
          73           4 :       ~LoadAndConstructLoadWrapper()
          74             :       {
          75           4 :         if (construct.itsValid)
          76             :         {
          77           4 :           construct->~T();
          78             :         }
          79           4 :       }
          80             :
          81           4 :       void CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar )
          82             :       {
          83           4 :         ::cereal::detail::Construct<T, Archive>::load_andor_construct( ar, construct );
          84           4 :       }
          85             :
          86             :       ST st;
          87             :       ::cereal::construct<T> construct;
          88             :     };
          89             :
          90             :     //! @internal
          91             :     template <class T> struct load_variant_wrapper;
          92             :
          93             :     //! Avoid serializing variant void_ type
          94             :     /*! @internal */
          95             :     template <>
          96             :     struct load_variant_wrapper<boost::detail::variant::void_>
          97             :     {
          98             :       template <class Variant, class Archive>
          99             :       static void load_variant( Archive &, Variant & )
         100             :       { }
         101             :     };
         102             :
         103             :     //! @internal
         104             :     template <class T>
         105             :     struct load_variant_wrapper
         106             :     {
         107             :       // default constructible
         108             :       template <class Archive, class Variant>
         109          12 :       static void load_variant_impl( Archive & ar, Variant & variant, std::true_type )
         110             :       {
         111           8 :         T value;
         112          12 :         ar( CEREAL_NVP_("data", value) );
         113          12 :         variant = std::move(value);
         114          12 :       }
         115             :
         116             :       // not default constructible
         117             :       template<class Variant, class Archive>
         118           4 :       static void load_variant_impl(Archive & ar, Variant & variant, std::false_type )
         119             :       {
         120           8 :         LoadAndConstructLoadWrapper<Archive, T> loadWrapper;
         121             :
         122           4 :         ar( CEREAL_NVP_("data", loadWrapper) );
         123           4 :         variant = std::move(*loadWrapper.construct.ptr());
         124           4 :       }
         125             :
         126             :       //! @internal
         127             :       template<class Variant, class Archive>
         128          16 :       static void load_variant(Archive & ar, Variant & variant)
         129             :       {
         130          16 :         load_variant_impl( ar, variant, typename std::is_default_constructible<T>::type() );
         131          16 :       }
         132             :     };
         133             :   } // namespace boost_variant_detail
         134             :
         135             :   //! Saving for boost::variant
         136             :   template <class Archive, typename ... VariantTypes> inline
         137          16 :   void CEREAL_SAVE_FUNCTION_NAME( Archive & ar, boost::variant<VariantTypes...> const & variant )
         138             :   {
         139          16 :     int32_t which = variant.which();
         140          16 :     ar( CEREAL_NVP_("which", which) );
         141          16 :     boost_variant_detail::variant_save_visitor<Archive> visitor(ar);
         142          16 :     variant.apply_visitor(visitor);
         143          16 :   }
         144             :
         145             :   //! Loading for boost::variant
         146             :   template <class Archive, typename ... VariantTypes> inline
         147          16 :   void CEREAL_LOAD_FUNCTION_NAME( Archive & ar, boost::variant<VariantTypes...> & variant )
         148             :   {
         149             :     int32_t which;
         150          16 :     ar( CEREAL_NVP_("which", which) );
         151             :
         152             :     using LoadFuncType = void(*)(Archive &, boost::variant<VariantTypes...> &);
         153          16 :     CEREAL_CONSTEXPR_LAMBDA LoadFuncType loadFuncArray[] = {&boost_variant_detail::load_variant_wrapper<VariantTypes>::load_variant...};
         154             :
         155          16 :     if(which >= int32_t(sizeof(loadFuncArray)/sizeof(loadFuncArray[0])))
         156           0 :       throw Exception("Invalid 'which' selector when deserializing boost::variant");
         157             :
         158          16 :     loadFuncArray[which](ar, variant);
         159          16 :   }
         160             : } // namespace cereal
         161             :
         162             : #undef CEREAL_CONSTEXPR_LAMBDA
         163             :
         164             : #endif // CEREAL_TYPES_BOOST_VARIANT_HPP_

Generated by: LCOV version 1.14