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