Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/unordered/detail/serialize_container.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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_CONTAINER_HPP
0010 #define BOOST_UNORDERED_DETAIL_SERIALIZE_CONTAINER_HPP
0011 
0012 #include <boost/core/serialization.hpp>
0013 #include <boost/throw_exception.hpp>
0014 #include <boost/unordered/detail/archive_constructed.hpp>
0015 #include <boost/unordered/detail/bad_archive_exception.hpp>
0016 #include <boost/unordered/detail/serialization_version.hpp>
0017 #include <cstddef>
0018 
0019 namespace boost{
0020 namespace unordered{
0021 namespace detail{
0022 
0023 /* serialize_container(ar,x,v) serializes any of the unordered associative
0024  * containers in Boost.Unordered. Iterator serialization is also supported
0025  * through the following protocol: 
0026  *  - At saving time, for each iterator it in [x.begin(),x.end()),
0027  *    serialization_track(ar,it) is ADL-called to instruct the archive to
0028  *    track the positions internally pointed to by the iterator via
0029  *    track_address().
0030  *  - At loading time, these addresses are mapped to those of the equivalent
0031  *    reconstructed positions using again serialization_track(ar,it).
0032  *  - Serializing an iterator reduces to serializing pointers to previously
0033  *    tracked addresses via serialize_address().
0034  */
0035 
0036 template<typename Iterator>
0037 std::pair<Iterator,bool> adapt_insert_return_type(Iterator it)
0038 {
0039   return std::pair<Iterator,bool>(it,true);
0040 }
0041 
0042 template<typename Iterator>
0043 std::pair<Iterator,bool> adapt_insert_return_type(std::pair<Iterator,bool> p)
0044 {
0045   return p;
0046 }
0047 
0048 template<typename Set,bool IsSaving> struct load_or_save_unordered_set;
0049 
0050 template<typename Set> struct load_or_save_unordered_set<Set,true> /* save */
0051 {
0052   template<typename Archive>
0053   void operator()(Archive& ar,const Set& x,unsigned int)const
0054   {
0055     typedef typename Set::value_type     value_type;
0056     typedef typename Set::const_iterator const_iterator;
0057 
0058     const std::size_t                       s=x.size();
0059     const serialization_version<value_type> value_version;
0060 
0061     ar<<core::make_nvp("count",s);
0062     ar<<core::make_nvp("value_version",value_version);
0063 
0064     for(const_iterator first=x.begin(),last=x.end();first!=last;++first){
0065       core::save_construct_data_adl(ar,std::addressof(*first),value_version);
0066       ar<<core::make_nvp("item",*first);
0067       serialization_track(ar,first);
0068     }
0069   }
0070 };
0071 
0072 template<typename Set> struct load_or_save_unordered_set<Set,false> /* load */
0073 {
0074   template<typename Archive>
0075   void operator()(Archive& ar,Set& x,unsigned int)const
0076   {
0077     typedef typename Set::value_type value_type;
0078     typedef typename Set::iterator   iterator;
0079 
0080     std::size_t                       s;
0081     serialization_version<value_type> value_version;
0082 
0083     ar>>core::make_nvp("count",s);
0084     ar>>core::make_nvp("value_version",value_version);
0085 
0086     x.clear();
0087     x.reserve(s); /* critical so that iterator tracking is stable */
0088 
0089     for(std::size_t n=0;n<s;++n){
0090       archive_constructed<value_type> value("item",ar,value_version);
0091 
0092       std::pair<iterator,bool> p=adapt_insert_return_type(
0093         x.insert(std::move(value.get())));
0094       if(!p.second)throw_exception(bad_archive_exception());
0095       ar.reset_object_address(
0096         std::addressof(*p.first),std::addressof(value.get()));
0097       serialization_track(ar,p.first);
0098     }
0099   }
0100 };
0101 
0102 template<typename Map,bool IsSaving> struct load_or_save_unordered_map;
0103 
0104 template<typename Map> struct load_or_save_unordered_map<Map,true> /* save */
0105 {
0106   template<typename Archive>
0107   void operator()(Archive& ar,const Map& x,unsigned int)const
0108   {
0109     typedef typename std::remove_const<
0110       typename Map::key_type>::type       key_type;
0111     typedef typename std::remove_const<
0112       typename Map::mapped_type>::type    mapped_type;
0113     typedef typename Map::const_iterator  const_iterator;
0114 
0115     const std::size_t                        s=x.size();
0116     const serialization_version<key_type>    key_version;
0117     const serialization_version<mapped_type> mapped_version;
0118 
0119     ar<<core::make_nvp("count",s);
0120     ar<<core::make_nvp("key_version",key_version);
0121     ar<<core::make_nvp("mapped_version",mapped_version);
0122 
0123     for(const_iterator first=x.begin(),last=x.end();first!=last;++first){
0124       /* To remain lib-independent from Boost.Serialization and not rely on
0125        * the user having included the serialization code for std::pair
0126        * (boost/serialization/utility.hpp), we serialize the key and the
0127        * mapped value separately.
0128        */
0129 
0130       core::save_construct_data_adl(
0131         ar,std::addressof(first->first),key_version);
0132       ar<<core::make_nvp("key",first->first);
0133       core::save_construct_data_adl(
0134         ar,std::addressof(first->second),mapped_version);
0135       ar<<core::make_nvp("mapped",first->second);
0136       serialization_track(ar,first);
0137     }
0138   }
0139 };
0140 
0141 template<typename Map> struct load_or_save_unordered_map<Map,false> /* load */
0142 {
0143   template<typename Archive>
0144   void operator()(Archive& ar,Map& x,unsigned int)const
0145   {
0146     typedef typename std::remove_const<
0147       typename Map::key_type>::type       key_type;
0148     typedef typename std::remove_const<
0149       typename Map::mapped_type>::type    mapped_type;
0150     typedef typename Map::iterator        iterator;
0151 
0152     std::size_t                        s;
0153     serialization_version<key_type>    key_version;
0154     serialization_version<mapped_type> mapped_version;
0155 
0156     ar>>core::make_nvp("count",s);
0157     ar>>core::make_nvp("key_version",key_version);
0158     ar>>core::make_nvp("mapped_version",mapped_version);
0159 
0160     x.clear();
0161     x.reserve(s); /* critical so that iterator tracking is stable */
0162 
0163     for(std::size_t n=0;n<s;++n){
0164       archive_constructed<key_type>    key("key",ar,key_version);
0165       archive_constructed<mapped_type> mapped("mapped",ar,mapped_version);
0166 
0167       std::pair<iterator,bool> p=adapt_insert_return_type(
0168         x.emplace(std::move(key.get()),std::move(mapped.get())));
0169       if(!p.second)throw_exception(bad_archive_exception());
0170       ar.reset_object_address(
0171         std::addressof(p.first->first),std::addressof(key.get()));
0172       ar.reset_object_address(
0173         std::addressof(p.first->second),std::addressof(mapped.get()));
0174       serialization_track(ar,p.first);
0175     }
0176   }
0177 };
0178 
0179 template<typename Container,bool IsSet,bool IsSaving>
0180 struct load_or_save_container;
0181   
0182 template<typename Set,bool IsSaving>
0183 struct load_or_save_container<Set,true,IsSaving>:
0184   load_or_save_unordered_set<Set,IsSaving>{};
0185 
0186 template<typename Map,bool IsSaving>
0187 struct load_or_save_container<Map,false,IsSaving>:
0188   load_or_save_unordered_map<Map,IsSaving>{};
0189 
0190 template<typename Archive,typename Container>
0191 void serialize_container(Archive& ar,Container& x,unsigned int version)
0192 {
0193   load_or_save_container<
0194     Container,
0195     std::is_same<
0196       typename Container::key_type,typename Container::value_type>::value,
0197     Archive::is_saving::value>()(ar,x,version);
0198 }
0199 
0200 } /* namespace detail */
0201 } /* namespace unordered */
0202 } /* namespace boost */
0203 
0204 #endif