Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:22

0001 /* Copyright 2023 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See https://www.boost.org/libs/unordered for library home page.
0007  */
0008 
0009 #ifndef BOOST_UNORDERED_DETAIL_SERIALIZE_TRACKED_ADDRESS_HPP
0010 #define BOOST_UNORDERED_DETAIL_SERIALIZE_TRACKED_ADDRESS_HPP
0011 
0012 #include <boost/unordered/detail/bad_archive_exception.hpp>
0013 
0014 #include <boost/core/pointer_traits.hpp>
0015 #include <boost/core/serialization.hpp>
0016 #include <boost/throw_exception.hpp>
0017 
0018 #include <type_traits>
0019 
0020 namespace boost{
0021 namespace unordered{
0022 namespace detail{
0023 
0024 /* Tracked address serialization to support iterator serialization as described
0025  * in serialize_container.hpp. The underlying technique is to reinterpret_cast
0026  * T pointers to serialization_tracker<T> pointers, which, when dereferenced
0027  * and serialized, do not emit any serialization payload to the
0028  * archive, but activate object tracking on the relevant addresses for later
0029  * use with serialize_tracked_address().
0030  */
0031 
0032 template<typename T>
0033 struct serialization_tracker
0034 {
0035   /* An attempt to construct a serialization_tracker means a stray address
0036    * in the archive, that is, one without a previously tracked address.
0037    */
0038   serialization_tracker(){throw_exception(bad_archive_exception());}
0039 
0040   template<typename Archive>
0041   void serialize(Archive&,unsigned int){} /* no data emitted */
0042 };
0043 
0044 template<typename Archive,typename Ptr>
0045 void track_address(Archive& ar,Ptr p)
0046 {
0047   typedef typename boost::pointer_traits<Ptr> ptr_traits;
0048   typedef typename std::remove_const<
0049     typename ptr_traits::element_type>::type  element_type;
0050 
0051   if(p){
0052     ar&core::make_nvp(
0053       "address",
0054       *reinterpret_cast<serialization_tracker<element_type>*>(
0055         const_cast<element_type*>(
0056           boost::to_address(p))));
0057   }
0058 }
0059 
0060 template<typename Archive,typename Ptr>
0061 void serialize_tracked_address(Archive& ar,Ptr& p,std::true_type /* save */)
0062 {
0063   typedef typename boost::pointer_traits<Ptr> ptr_traits;
0064   typedef typename std::remove_const<
0065     typename ptr_traits::element_type>::type  element_type;
0066   typedef serialization_tracker<element_type> tracker;
0067 
0068   tracker* pt=
0069     const_cast<tracker*>(
0070       reinterpret_cast<const tracker*>(
0071         const_cast<const element_type*>(
0072           boost::to_address(p))));
0073   ar<<core::make_nvp("pointer",pt);
0074 }
0075 
0076 template<typename Archive,typename Ptr>
0077 void serialize_tracked_address(Archive& ar,Ptr& p,std::false_type /* load */)
0078 {
0079   typedef typename boost::pointer_traits<Ptr> ptr_traits;
0080   typedef typename std::remove_const<
0081     typename ptr_traits::element_type>::type  element_type;
0082   typedef serialization_tracker<element_type> tracker;
0083 
0084   tracker* pt;
0085   ar>>core::make_nvp("pointer",pt);
0086   element_type* pn=const_cast<element_type*>(
0087     reinterpret_cast<const element_type*>(
0088       const_cast<const tracker*>(pt)));
0089   p=pn?ptr_traits::pointer_to(*pn):0;
0090 }
0091 
0092 template<typename Archive,typename Ptr>
0093 void serialize_tracked_address(Archive& ar,Ptr& p)
0094 {
0095   serialize_tracked_address(
0096     ar,p,
0097     std::integral_constant<bool,Archive::is_saving::value>());
0098 }
0099 
0100 } /* namespace detail */
0101 } /* namespace unordered */
0102 } /* namespace boost */
0103 
0104 #endif