LCOV - code coverage report

Current view: | top level - cereal/archives - adapters.hpp (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 8 | 9 | 88.9 %
Date: | 2022-01-16 21:05:07 |  | Functions: | 8 | 12 | 66.7 %

              Line data    Source code

           1             : /*! \file adapters.hpp
           2             :     \brief Archive adapters that provide additional functionality
           3             :            on top of an existing archive */
           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_ARCHIVES_ADAPTERS_HPP_
          31             : #define CEREAL_ARCHIVES_ADAPTERS_HPP_
          32             :
          33             : #include "cereal/details/helpers.hpp"
          34             : #include <utility>
          35             :
          36             : namespace cereal
          37             : {
          38             :   #ifdef CEREAL_FUTURE_EXPERIMENTAL
          39             :
          40             :   // Forward declaration for friend access
          41             :   template <class U, class A> U & get_user_data( A & );
          42             :
          43             :   //! Wraps an archive and gives access to user data
          44             :   /*! This adapter is useful if you require access to
          45             :       either raw pointers or references within your
          46             :       serialization functions.
          47             :
          48             :       While cereal does not directly support serialization
          49             :       raw pointers or references, it is sometimes the case
          50             :       that you may want to supply something such as a raw
          51             :       pointer or global reference to some constructor.
          52             :       In this situation this adapter would likely be used
          53             :       with the construct class to allow for non-default
          54             :       constructors.
          55             :
          56             :       @note This feature is experimental and may be altered or removed in a future release. See issue #46.
          57             :
          58             :       @code{.cpp}
          59             :       struct MyUserData
          60             :       {
          61             :         int * myRawPointer;
          62             :         std::reference_wrapper<MyOtherType> myReference;
          63             :       };
          64             :
          65             :       struct MyClass
          66             :       {
          67             :         // Note the raw pointer parameter
          68             :         MyClass( int xx, int * rawP );
          69             :
          70             :         int x;
          71             :
          72             :         template <class Archive>
          73             :         void serialize( Archive & ar )
          74             :         { ar( x ); }
          75             :
          76             :         template <class Archive>
          77             :         static void load_and_construct( Archive & ar, cereal::construct<MyClass> & construct )
          78             :         {
          79             :           int xx;
          80             :           ar( xx );
          81             :           // note the need to use get_user_data to retrieve user data from the archive
          82             :           construct( xx, cereal::get_user_data<MyUserData>( ar ).myRawPointer );
          83             :         }
          84             :       };
          85             :
          86             :       int main()
          87             :       {
          88             :         {
          89             :           MyUserData md;
          90             :           md.myRawPointer = &something;
          91             :           md.myReference = someInstanceOfType;
          92             :
          93             :           std::ifstream is( "data.xml" );
          94             :           cereal::UserDataAdapter<MyUserData, cereal::XMLInputArchive> ar( md, is );
          95             :
          96             :           std::unique_ptr<MyClass> sc;
          97             :           ar( sc ); // use as normal
          98             :         }
          99             :
         100             :         return 0;
         101             :       }
         102             :       @endcode
         103             :
         104             :       @relates get_user_data
         105             :
         106             :       @tparam UserData The type to give the archive access to
         107             :       @tparam Archive The archive to wrap */
         108             :   template <class UserData, class Archive>
         109             :   class UserDataAdapter : public Archive
         110             :   {
         111             :     public:
         112             :       //! Construct the archive with some user data struct
         113             :       /*! This will forward all arguments (other than the user
         114             :           data) to the wrapped archive type.  The UserDataAdapter
         115             :           can then be used identically to the wrapped archive type
         116             :
         117             :           @tparam Args The arguments to pass to the constructor of
         118             :                        the archive. */
         119             :       template <class ... Args>
         120         400 :       UserDataAdapter( UserData & ud, Args && ... args ) :
         121         400 :         Archive( std::forward<Args>( args )... ),
         122         500 :         userdata( ud )
         123         400 :       { }
         124             :
         125             :     private:
         126             :       //! Overload the rtti function to enable dynamic_cast
         127           0 :       void rtti() {}
         128             :       friend UserData & get_user_data<UserData>( Archive & ar );
         129             :       UserData & userdata; //!< The actual user data
         130             :   };
         131             :
         132             :   //! Retrieves user data from an archive wrapped by UserDataAdapter
         133             :   /*! This will attempt to retrieve the user data associated with
         134             :       some archive wrapped by UserDataAdapter.  If this is used on
         135             :       an archive that is not wrapped, a run-time exception will occur.
         136             :
         137             :       @note This feature is experimental and may be altered or removed in a future release. See issue #46.
         138             :
         139             :       @note The correct use of this function cannot be enforced at compile
         140             :             time.
         141             :
         142             :       @relates UserDataAdapter
         143             :       @tparam UserData The data struct contained in the archive
         144             :       @tparam Archive The archive, which should be wrapped by UserDataAdapter
         145             :       @param ar The archive
         146             :       @throws Exception if the archive this is used upon is not wrapped with
         147             :                         UserDataAdapter. */
         148             :   template <class UserData, class Archive>
         149         800 :   UserData & get_user_data( Archive & ar )
         150             :   {
         151             :     try
         152             :     {
         153         800 :       return dynamic_cast<UserDataAdapter<UserData, Archive> &>( ar ).userdata;
         154             :     }
         155         800 :     catch( std::bad_cast const & )
         156             :     {
         157         400 :       throw ::cereal::Exception("Attempting to get user data from archive not wrapped in UserDataAdapter");
         158             :     }
         159             :   }
         160             :   #endif // CEREAL_FUTURE_EXPERIMENTAL
         161             : } // namespace cereal
         162             :
         163             : #endif // CEREAL_ARCHIVES_ADAPTERS_HPP_

Generated by: LCOV version 1.14