mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 19:07:15 +02:00
added serialization support (pending docs and testing)
This commit is contained in:
@ -19,6 +19,7 @@
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/type_traits/type_identity.hpp>
|
||||
@ -101,6 +102,11 @@ namespace boost {
|
||||
friend typename concurrent_flat_map<K, V, H, KE, A>::size_type erase_if(
|
||||
concurrent_flat_map<K, V, H, KE, A>& set, Predicate pred);
|
||||
|
||||
template<class Archive, class K, class V, class H, class KE, class A>
|
||||
friend void serialize(
|
||||
Archive& ar, concurrent_flat_map<K, V, H, KE, A>& c,
|
||||
unsigned int version);
|
||||
|
||||
public:
|
||||
using key_type = Key;
|
||||
using mapped_type = T;
|
||||
@ -772,6 +778,14 @@ namespace boost {
|
||||
return c.table_.erase_if(pred);
|
||||
}
|
||||
|
||||
template<class Archive, class K, class V, class H, class KE, class A>
|
||||
void serialize(
|
||||
Archive& ar, concurrent_flat_map<K, V, H, KE, A>& c,
|
||||
unsigned int version)
|
||||
{
|
||||
ar & core::make_nvp("table",c.table_);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
template <class InputIterator,
|
||||
|
71
include/boost/unordered/detail/archive_constructed.hpp
Normal file
71
include/boost/unordered/detail/archive_constructed.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/* Copyright 2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See https://www.boost.org/libs/unordered for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
/* constructs a stack-based object from a serialization archive */
|
||||
|
||||
template<typename T>
|
||||
struct archive_constructed:private noncopyable
|
||||
{
|
||||
template<class Archive>
|
||||
archive_constructed(const char* name,Archive& ar,unsigned int version)
|
||||
{
|
||||
core::load_construct_data_adl(ar,&get(),version);
|
||||
BOOST_TRY{
|
||||
ar>>core::make_nvp(name,get());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
(&get())->~T();
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
~archive_constructed()
|
||||
{
|
||||
(&get())->~T();
|
||||
}
|
||||
|
||||
#if defined(BOOST_GCC)&&(BOOST_GCC>=4*10000+6*100)
|
||||
#define BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
|
||||
T& get(){return *reinterpret_cast<T*>(&space);}
|
||||
|
||||
#if defined(BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING)
|
||||
#pragma GCC diagnostic pop
|
||||
#undef BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING
|
||||
#endif
|
||||
|
||||
private:
|
||||
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
|
||||
};
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace unordered */
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
27
include/boost/unordered/detail/bad_archive_exception.hpp
Normal file
27
include/boost/unordered/detail/bad_archive_exception.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright 2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See https://www.boost.org/libs/unordered for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
struct bad_archive_exception:std::runtime_error
|
||||
{
|
||||
bad_archive_exception():std::runtime_error("Invalid or corrupted archive"){}
|
||||
};
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace unordered */
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2022 Joaquin M Lopez Munoz.
|
||||
// Copyright (C) 2022-2023 Joaquin M Lopez Munoz.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -114,12 +114,14 @@ to normal separate chaining implementations.
|
||||
*/
|
||||
|
||||
#include <boost/unordered/detail/prime_fmod.hpp>
|
||||
#include <boost/unordered/detail/serialize_node_pointer.hpp>
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/bit.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
@ -287,6 +289,25 @@ namespace boost {
|
||||
p = pbg->buckets + x;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
friend void serialization_track(
|
||||
Archive& ar, grouped_bucket_iterator const& x)
|
||||
{
|
||||
// requires: not at end() position
|
||||
track_node_pointer(ar, x.p);
|
||||
track_node_pointer(ar, x.pbg);
|
||||
}
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar,unsigned int)
|
||||
{
|
||||
// requires: not at end() position
|
||||
serialize_node_pointer(ar, p);
|
||||
serialize_node_pointer(ar, pbg);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Node> struct const_grouped_local_bucket_iterator;
|
||||
|
@ -16,13 +16,18 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/mp11/tuple.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/unordered/detail/archive_constructed.hpp>
|
||||
#include <boost/unordered/detail/bad_archive_exception.hpp>
|
||||
#include <boost/unordered/detail/foa/core.hpp>
|
||||
#include <boost/unordered/detail/foa/reentrancy_check.hpp>
|
||||
#include <boost/unordered/detail/foa/rw_spinlock.hpp>
|
||||
#include <boost/unordered/detail/foa/tuple_rotate_right.hpp>
|
||||
#include <boost/unordered/detail/serialization_version.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
@ -1442,6 +1447,139 @@ private:
|
||||
}
|
||||
#endif
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar,unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
void save(Archive& ar,unsigned int version)const
|
||||
{
|
||||
save(
|
||||
ar,version,
|
||||
std::integral_constant<bool,std::is_same<key_type,value_type>::value>{});
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
void save(Archive& ar,unsigned int version,std::true_type /* set */)const
|
||||
{
|
||||
auto lck=exclusive_access();
|
||||
const std::size_t s=super::size();
|
||||
const serialization_version<value_type> value_version;
|
||||
|
||||
ar<<core::make_nvp("count",s);
|
||||
ar<<core::make_nvp("value_version",value_version);
|
||||
|
||||
super::for_all_elements([&,this](element_type* p){
|
||||
auto& x=type_policy::value_from(*p);
|
||||
core::save_construct_data_adl(ar,std::addressof(x),value_version);
|
||||
ar<<serialization::make_nvp("item",x);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
void save(Archive& ar,unsigned int version,std::false_type /* map */)const
|
||||
{
|
||||
using key_type=typename std::remove_const<key_type>::type;
|
||||
using mapped_type=typename std::remove_const<
|
||||
typename TypePolicy::mapped_type>::type;
|
||||
|
||||
auto lck=exclusive_access();
|
||||
const std::size_t s=super::size();
|
||||
const serialization_version<key_type> key_version;
|
||||
const serialization_version<mapped_type> mapped_version;
|
||||
|
||||
ar<<core::make_nvp("count",s);
|
||||
ar<<core::make_nvp("key_version",key_version);
|
||||
ar<<core::make_nvp("mapped_version",mapped_version);
|
||||
|
||||
super::for_all_elements([&,this](element_type* p){
|
||||
/* To remain lib-independent from Boost.Serialization and not rely on
|
||||
* the user having included the serialization code for std::pair
|
||||
* (boost/serialization/utility.hpp), we serialize the key and the
|
||||
* mapped value separately.
|
||||
*/
|
||||
|
||||
auto& x=type_policy::value_from(*p);
|
||||
core::save_construct_data_adl(
|
||||
ar,std::addressof(x.first),key_version);
|
||||
ar<<serialization::make_nvp("key",x.first);
|
||||
core::save_construct_data_adl(
|
||||
ar,std::addressof(x.second),mapped_version);
|
||||
ar<<serialization::make_nvp("mapped",x.second);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
void load(Archive& ar,unsigned int version)
|
||||
{
|
||||
load(
|
||||
ar,version,
|
||||
std::integral_constant<bool,std::is_same<key_type,value_type>::value>{});
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
void load(Archive& ar,unsigned int version,std::true_type /* set */)
|
||||
{
|
||||
auto lck=exclusive_access();
|
||||
std::size_t s;
|
||||
serialization_version<value_type> value_version;
|
||||
|
||||
ar>>core::make_nvp("count",s);
|
||||
ar>>core::make_nvp("value_version",value_version);
|
||||
|
||||
super::clear();
|
||||
super::reserve(s);
|
||||
|
||||
for(std::size_t n=0;n<s;++n){
|
||||
archive_constructed<value_type> value("item",ar,value_version);
|
||||
auto& x=value.get();
|
||||
auto hash=this->hash_for(x);
|
||||
auto pos0=this->position_for(hash);
|
||||
|
||||
if(this->find(x,pos0,hash))throw_exception(bad_archive_exception());
|
||||
auto loc=this->unchecked_emplace_at(pos0,hash,std::move(x));
|
||||
ar.reset_object_address(std::addressof(*loc.p),std::addressof(x));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
void load(Archive& ar,unsigned int version,std::false_type /* map */)
|
||||
{
|
||||
using key_type=typename std::remove_const<key_type>::type;
|
||||
using mapped_type=typename std::remove_const<
|
||||
typename TypePolicy::mapped_type>::type;
|
||||
|
||||
auto lck=exclusive_access();
|
||||
std::size_t s;
|
||||
serialization_version<key_type> key_version;
|
||||
serialization_version<mapped_type> mapped_version;
|
||||
|
||||
ar>>core::make_nvp("count",s);
|
||||
ar>>core::make_nvp("key_version",key_version);
|
||||
ar>>core::make_nvp("mapped_version",mapped_version);
|
||||
|
||||
super::clear();
|
||||
super::reserve(s);
|
||||
|
||||
for(std::size_t n=0;n<s;++n){
|
||||
archive_constructed<key_type> key("key",ar,key_version);
|
||||
archive_constructed<mapped_type> mapped("mapped",ar,mapped_version);
|
||||
auto& k=key.get();
|
||||
auto& m=mapped.get();
|
||||
auto hash=this->hash_for(k);
|
||||
auto pos0=this->position_for(hash);
|
||||
|
||||
if(this->find(k,pos0,hash))throw_exception(bad_archive_exception());
|
||||
auto loc=this->unchecked_emplace_at(pos0,hash,std::move(k),std::move(m));
|
||||
ar.reset_object_address(std::addressof(loc.p->first),std::addressof(k));
|
||||
ar.reset_object_address(std::addressof(loc.p->second),std::addressof(m));
|
||||
}
|
||||
}
|
||||
|
||||
static std::atomic<std::size_t> thread_counter;
|
||||
mutable multimutex_type mutexes;
|
||||
};
|
||||
|
@ -1180,7 +1180,8 @@ alloc_make_insert_type(const Allocator& al,Args&&... args)
|
||||
* init_type and element_type:
|
||||
*
|
||||
* - TypePolicy::key_type and TypePolicy::value_type have the obvious
|
||||
* meaning.
|
||||
* meaning. TypePolicy::mapped_type is expected to be provided as well
|
||||
* when key_type and value_type are not the same.
|
||||
*
|
||||
* - TypePolicy::init_type is the type implicitly converted to when
|
||||
* writing x.insert({...}). For maps, this is std::pair<Key,T> rather
|
||||
|
@ -14,6 +14,7 @@ namespace boost {
|
||||
template <class Key, class T> struct flat_map_types
|
||||
{
|
||||
using key_type = Key;
|
||||
using mapped_type = T;
|
||||
using raw_key_type = typename std::remove_const<Key>::type;
|
||||
using raw_mapped_type = typename std::remove_const<T>::type;
|
||||
|
||||
|
@ -15,7 +15,9 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/unordered/detail/foa/core.hpp>
|
||||
#include <boost/unordered/detail/serialize_node_pointer.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
@ -195,6 +197,25 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
friend void serialization_track(Archive& ar,const table_iterator& x)
|
||||
{
|
||||
if(x.p){
|
||||
track_node_pointer(ar,x.pc);
|
||||
track_node_pointer(ar,x.p);
|
||||
}
|
||||
}
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar,unsigned int)
|
||||
{
|
||||
if(!p)pc=nullptr;
|
||||
serialize_node_pointer(ar,pc);
|
||||
serialize_node_pointer(ar,p);
|
||||
}
|
||||
|
||||
unsigned char *pc=nullptr;
|
||||
table_element_type *p=nullptr;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
||||
// Copyright (C) 2005-2016 Daniel James
|
||||
// Copyright (C) 2022 Joaquin M Lopez Munoz.
|
||||
// Copyright (C) 2022-2023 Joaquin M Lopez Munoz.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -19,6 +19,7 @@
|
||||
#include <boost/core/bit.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/pointer_traits.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
@ -47,6 +48,7 @@
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/unordered/detail/fca.hpp>
|
||||
#include <boost/unordered/detail/serialize_node_pointer.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
@ -1703,6 +1705,25 @@ namespace boost {
|
||||
p = (++itb)->next;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
friend void serialization_track(Archive& ar, const iterator& x)
|
||||
{
|
||||
if(x.p){
|
||||
track_node_pointer(ar, x.p);
|
||||
serialization_track(ar, x.itb);
|
||||
}
|
||||
}
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar,unsigned int)
|
||||
{
|
||||
if(!p) itb = bucket_iterator();
|
||||
serialize_node_pointer(ar, p);
|
||||
ar & core::make_nvp("bucket_iterator", itb);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Node, class Bucket> class c_iterator
|
||||
@ -1793,6 +1814,25 @@ namespace boost {
|
||||
p = (++itb)->next;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
friend void serialization_track(Archive& ar, const c_iterator& x)
|
||||
{
|
||||
if(x.p){
|
||||
track_node_pointer(ar, x.p);
|
||||
serialization_track(ar, x.itb);
|
||||
}
|
||||
}
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar,unsigned int)
|
||||
{
|
||||
if(!p) itb = bucket_iterator();
|
||||
serialize_node_pointer(ar, p);
|
||||
ar & core::make_nvp("bucket_iterator", itb);
|
||||
}
|
||||
};
|
||||
} // namespace iterator_detail
|
||||
|
||||
|
74
include/boost/unordered/detail/serialization_version.hpp
Normal file
74
include/boost/unordered/detail/serialization_version.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/* Copyright 2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See https://www.boost.org/libs/unordered for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_SERIALIZATION_VERSION_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_SERIALIZATION_VERSION_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
/* boost::serialization::load_construct_adl(ar,t,version) requires user code
|
||||
* to pass the serialization version for t, when this information is really
|
||||
* stored in the archive. serialization_version<T> circumvents this design
|
||||
* error by acting as a regular serializable type with the same serialization
|
||||
* version as T; loading/saving serialization_version<T> does nothing with
|
||||
* the archive data itself but captures the stored serialization version
|
||||
* at load() time.
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
struct serialization_version
|
||||
{
|
||||
serialization_version():
|
||||
value(boost::serialization::version<serialization_version>::value){}
|
||||
|
||||
serialization_version& operator=(unsigned int x){value=x;return *this;};
|
||||
|
||||
operator unsigned int()const{return value;}
|
||||
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive&,unsigned int)const{}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive&,unsigned int version)
|
||||
{
|
||||
this->value=version;
|
||||
}
|
||||
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace unordered */
|
||||
|
||||
namespace serialization{
|
||||
|
||||
template<typename T>
|
||||
struct version<boost::unordered::detail::serialization_version<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int,value=version<T>::value);
|
||||
};
|
||||
|
||||
} /* namespace serialization */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
208
include/boost/unordered/detail/serialize_container.hpp
Normal file
208
include/boost/unordered/detail/serialize_container.hpp
Normal file
@ -0,0 +1,208 @@
|
||||
/* Copyright 2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See https://www.boost.org/libs/unordered for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_SERIALIZE_CONTAINER_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_SERIALIZE_CONTAINER_HPP
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/unordered/detail/archive_constructed.hpp>
|
||||
#include <boost/unordered/detail/bad_archive_exception.hpp>
|
||||
#include <boost/unordered/detail/serialization_version.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
/* serialize_container(ar,x,v) serializes any of the unordered associative
|
||||
* containers in Boost.Unordered. Iterator serialization is also supported
|
||||
* through the following protocol:
|
||||
* - At saving time, for each iterator it in [x.begin(),x.end()),
|
||||
* serialization_track(ar,it) is ADL-called to instruct the archive to
|
||||
* track the addresses of the iterator's associated node(s) via
|
||||
* track_node_pointer().
|
||||
* - At loading time, these addresses are mapped to those of the equivalent
|
||||
* reconstructed nodes using again serialization_track(ar,it).
|
||||
* - Serializing an iterator reduces to serializing pointers to previously
|
||||
* tracked nodes via serialize_node_pointer().
|
||||
*/
|
||||
|
||||
template<typename Iterator>
|
||||
std::pair<Iterator,bool> adapt_insert_return_type(Iterator it)
|
||||
{
|
||||
return std::pair<Iterator,bool>(it,true);
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
std::pair<Iterator,bool> adapt_insert_return_type(std::pair<Iterator,bool> p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename Set,bool IsSaving> struct load_or_save_unordered_set;
|
||||
|
||||
template<typename Set> struct load_or_save_unordered_set<Set,true> /* save */
|
||||
{
|
||||
template<typename Archive>
|
||||
void operator()(Archive& ar,const Set& x,unsigned int version)const
|
||||
{
|
||||
typedef typename Set::value_type value_type;
|
||||
typedef typename Set::const_iterator const_iterator;
|
||||
|
||||
const std::size_t s=x.size();
|
||||
const serialization_version<value_type> value_version;
|
||||
|
||||
ar<<core::make_nvp("count",s);
|
||||
ar<<core::make_nvp("value_version",value_version);
|
||||
|
||||
for(const_iterator first=x.begin(),last=x.end();first!=last;++first){
|
||||
core::save_construct_data_adl(ar,boost::addressof(*first),value_version);
|
||||
ar<<core::make_nvp("item",*first);
|
||||
serialization_track(ar,first);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Set> struct load_or_save_unordered_set<Set,false> /* load */
|
||||
{
|
||||
template<typename Archive>
|
||||
void operator()(Archive& ar,Set& x,unsigned int version)const
|
||||
{
|
||||
typedef typename Set::value_type value_type;
|
||||
typedef typename Set::iterator iterator;
|
||||
|
||||
std::size_t s;
|
||||
serialization_version<value_type> value_version;
|
||||
|
||||
ar>>core::make_nvp("count",s);
|
||||
ar>>core::make_nvp("value_version",value_version);
|
||||
|
||||
x.clear();
|
||||
x.reserve(s); /* critical so that iterator tracking is stable */
|
||||
|
||||
for(std::size_t n=0;n<s;++n){
|
||||
archive_constructed<value_type> value("item",ar,value_version);
|
||||
|
||||
std::pair<iterator,bool> p=adapt_insert_return_type(
|
||||
x.insert(boost::move(value.get())));
|
||||
if(!p.second)throw_exception(bad_archive_exception());
|
||||
ar.reset_object_address(
|
||||
boost::addressof(*p.first),boost::addressof(value.get()));
|
||||
serialization_track(ar,p.first);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Map,bool IsSaving> struct load_or_save_unordered_map;
|
||||
|
||||
template<typename Map> struct load_or_save_unordered_map<Map,true> /* save */
|
||||
{
|
||||
template<typename Archive>
|
||||
void operator()(Archive& ar,const Map& x,unsigned int version)const
|
||||
{
|
||||
typedef typename boost::remove_const<
|
||||
typename Map::key_type>::type key_type;
|
||||
typedef typename boost::remove_const<
|
||||
typename Map::mapped_type>::type mapped_type;
|
||||
typedef typename Map::const_iterator const_iterator;
|
||||
|
||||
const std::size_t s=x.size();
|
||||
const serialization_version<key_type> key_version;
|
||||
const serialization_version<mapped_type> mapped_version;
|
||||
|
||||
ar<<core::make_nvp("count",s);
|
||||
ar<<core::make_nvp("key_version",key_version);
|
||||
ar<<core::make_nvp("mapped_version",mapped_version);
|
||||
|
||||
for(const_iterator first=x.begin(),last=x.end();first!=last;++first){
|
||||
/* To remain lib-independent from Boost.Serialization and not rely on
|
||||
* the user having included the serialization code for std::pair
|
||||
* (boost/serialization/utility.hpp), we serialize the key and the
|
||||
* mapped value separately.
|
||||
*/
|
||||
|
||||
core::save_construct_data_adl(
|
||||
ar,boost::addressof(first->first),key_version);
|
||||
ar<<core::make_nvp("key",first->first);
|
||||
core::save_construct_data_adl(
|
||||
ar,boost::addressof(first->second),mapped_version);
|
||||
ar<<core::make_nvp("mapped",first->second);
|
||||
serialization_track(ar,first);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Map> struct load_or_save_unordered_map<Map,false> /* load */
|
||||
{
|
||||
template<typename Archive>
|
||||
void operator()(Archive& ar,Map& x,unsigned int version)const
|
||||
{
|
||||
typedef typename boost::remove_const<
|
||||
typename Map::key_type>::type key_type;
|
||||
typedef typename boost::remove_const<
|
||||
typename Map::mapped_type>::type mapped_type;
|
||||
typedef typename Map::iterator iterator;
|
||||
|
||||
std::size_t s;
|
||||
serialization_version<key_type> key_version;
|
||||
serialization_version<mapped_type> mapped_version;
|
||||
|
||||
ar>>core::make_nvp("count",s);
|
||||
ar>>core::make_nvp("key_version",key_version);
|
||||
ar>>core::make_nvp("mapped_version",mapped_version);
|
||||
|
||||
x.clear();
|
||||
x.reserve(s);
|
||||
|
||||
for(std::size_t n=0;n<s;++n){
|
||||
archive_constructed<key_type> key("key",ar,key_version);
|
||||
archive_constructed<mapped_type> mapped("mapped",ar,mapped_version);
|
||||
|
||||
std::pair<iterator,bool> p=adapt_insert_return_type(
|
||||
x.emplace(boost::move(key.get()),boost::move(mapped.get())));
|
||||
if(!p.second)throw_exception(bad_archive_exception());
|
||||
ar.reset_object_address(
|
||||
boost::addressof(p.first->first),boost::addressof(key.get()));
|
||||
ar.reset_object_address(
|
||||
boost::addressof(p.first->second),boost::addressof(mapped.get()));
|
||||
serialization_track(ar,p.first);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Container,bool IsSet,bool IsSaving>
|
||||
struct load_or_save_container;
|
||||
|
||||
template<typename Set,bool IsSaving>
|
||||
struct load_or_save_container<Set,true,IsSaving>:
|
||||
load_or_save_unordered_set<Set,IsSaving>{};
|
||||
|
||||
template<typename Map,bool IsSaving>
|
||||
struct load_or_save_container<Map,false,IsSaving>:
|
||||
load_or_save_unordered_map<Map,IsSaving>{};
|
||||
|
||||
template<typename Archive,typename Container>
|
||||
void serialize_container(Archive& ar,Container& x,unsigned int version)
|
||||
{
|
||||
load_or_save_container<
|
||||
Container,
|
||||
boost::is_same<
|
||||
typename Container::key_type,typename Container::value_type>::value,
|
||||
Archive::is_saving::value>()(ar,x,version);
|
||||
}
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace unordered */
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
156
include/boost/unordered/detail/serialize_fca_container.hpp
Normal file
156
include/boost/unordered/detail/serialize_fca_container.hpp
Normal file
@ -0,0 +1,156 @@
|
||||
/* Copyright 2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See https://www.boost.org/libs/unordered for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_SERIALIZE_FCA_CONTAINER_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_SERIALIZE_FCA_CONTAINER_HPP
|
||||
|
||||
#include <boost/unordered/detail/serialize_container.hpp>
|
||||
|
||||
#if defined(BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0)
|
||||
|
||||
#define BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/serialization/archive_input_unordered_map.hpp>
|
||||
#include BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER
|
||||
#define BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/serialization/archive_input_unordered_set.hpp>
|
||||
#include BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER
|
||||
#define BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/serialization/unordered_collections_load_imp.hpp>
|
||||
#include BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER
|
||||
#define BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER \
|
||||
<boost/serialization/utility.hpp>
|
||||
#include BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER
|
||||
#undef BOOST_UNORDERED_BLOCK_BOOSTDEP_HEADER
|
||||
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
/* Support for boost::unordered_[multi](map|set) loading from legacy archives.
|
||||
* Until Boost 1.84, serialization of these containers was provided from
|
||||
* Boost.Serialization via boost/serialization/boost_unordered_(map|set).hpp,
|
||||
* from that release on support is native in Boost.Unordered. To enable legacy
|
||||
* archive loading, BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0
|
||||
* must be defined (it implies header dependency from Boost.Serialization).
|
||||
*/
|
||||
|
||||
#if defined(BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0)
|
||||
|
||||
template<typename Archive,typename Container>
|
||||
struct archive_input;
|
||||
|
||||
template<
|
||||
typename Archive,typename K,typename T,typename H,typename P,typename A
|
||||
>
|
||||
struct archive_input<Archive,boost::unordered_map<K,T,H,P,A> >:
|
||||
boost::serialization::stl::archive_input_unordered_map<
|
||||
Archive,
|
||||
boost::unordered_map<K,T,H,P,A>
|
||||
>
|
||||
{};
|
||||
|
||||
template<
|
||||
typename Archive,typename K,typename T,typename H,typename P,typename A
|
||||
>
|
||||
struct archive_input<Archive,boost::unordered_multimap<K,T,H,P,A> >:
|
||||
boost::serialization::stl::archive_input_unordered_multimap<
|
||||
Archive,
|
||||
boost::unordered_multimap<K,T,H,P,A>
|
||||
>
|
||||
{};
|
||||
|
||||
template<
|
||||
typename Archive,typename K,typename H,typename P,typename A
|
||||
>
|
||||
struct archive_input<Archive,boost::unordered_set<K,H,P,A> >:
|
||||
boost::serialization::stl::archive_input_unordered_set<
|
||||
Archive,
|
||||
boost::unordered_set<K,H,P,A>
|
||||
>
|
||||
{};
|
||||
|
||||
template<
|
||||
typename Archive,typename K,typename H,typename P,typename A
|
||||
>
|
||||
struct archive_input<Archive,boost::unordered_multiset<K,H,P,A> >:
|
||||
boost::serialization::stl::archive_input_unordered_multiset<
|
||||
Archive,
|
||||
boost::unordered_multiset<K,H,P,A>
|
||||
>
|
||||
{};
|
||||
|
||||
#else
|
||||
|
||||
struct legacy_archive_exception:std::runtime_error
|
||||
{
|
||||
legacy_archive_exception():std::runtime_error(
|
||||
"Legacy archive detected, define "
|
||||
"BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0 to load"){}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<typename Container,bool IsSaving>
|
||||
struct load_or_save_fca_container;
|
||||
|
||||
template<typename Container>
|
||||
struct load_or_save_fca_container<Container,true> /* save */
|
||||
{
|
||||
template<typename Archive>
|
||||
void operator()(Archive& ar,Container& x,unsigned int version)const
|
||||
{
|
||||
serialize_container(ar,x,version);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
struct load_or_save_fca_container<Container,false> /* load */
|
||||
{
|
||||
template<typename Archive>
|
||||
void operator()(Archive& ar,Container& x,unsigned int version)const
|
||||
{
|
||||
if(version==0){
|
||||
#if defined(BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0)
|
||||
boost::serialization::stl::load_unordered_collection<
|
||||
Archive,Container,archive_input<Archive,Container>
|
||||
>(ar,x);
|
||||
#else
|
||||
throw_exception(legacy_archive_exception());
|
||||
#endif
|
||||
}
|
||||
else{
|
||||
serialize_container(ar,x,version);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Archive,typename Container>
|
||||
void serialize_fca_container(Archive& ar,Container& x,unsigned int version)
|
||||
{
|
||||
load_or_save_fca_container<Container,Archive::is_saving::value>()(
|
||||
ar,x,version);
|
||||
}
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace unordered */
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
90
include/boost/unordered/detail/serialize_node_pointer.hpp
Normal file
90
include/boost/unordered/detail/serialize_node_pointer.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
/* Copyright 2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See https://www.boost.org/libs/unordered for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_SERIALIZE_NODE_POINTER_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_SERIALIZE_NODE_POINTER_HPP
|
||||
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/unordered/detail/bad_archive_exception.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
/* Node pointer serialization to support iterator serialization as described
|
||||
* in serialize_container.hpp. The underlying technique is to reinterpret_cast
|
||||
* Node pointers to serialization_tracker<Node> pointers, which, when
|
||||
* dereferenced and serialized, do not emit any serialization payload to the
|
||||
* archive, but activate object tracking on the relevant addresses for later
|
||||
* use with serialize_node_pointer().
|
||||
*/
|
||||
|
||||
template<typename Node>
|
||||
struct serialization_tracker
|
||||
{
|
||||
/* An attempt to construct a serialization_tracker means a stray address
|
||||
* in the archive, that is, one without a previously tracked node.
|
||||
*/
|
||||
serialization_tracker(){throw_exception(bad_archive_exception());}
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive&,unsigned int){} /* no data emitted */
|
||||
};
|
||||
|
||||
template<typename Archive,typename Node>
|
||||
void track_node_pointer(Archive& ar,const Node* p)
|
||||
{
|
||||
if(p){
|
||||
ar&core::make_nvp(
|
||||
"node",
|
||||
*reinterpret_cast<serialization_tracker<Node>*>(const_cast<Node*>(p)));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Archive,typename Node>
|
||||
void serialize_node_pointer(Archive& ar,Node*& p,boost::true_type /* save */)
|
||||
{
|
||||
typedef typename boost::remove_const<Node>::type node_type;
|
||||
typedef serialization_tracker<node_type> tracker;
|
||||
|
||||
tracker* pn=
|
||||
const_cast<tracker*>(
|
||||
reinterpret_cast<const tracker*>(
|
||||
const_cast<const Node*>(p)));
|
||||
ar<<core::make_nvp("pointer",pn);
|
||||
}
|
||||
|
||||
template<typename Archive,typename Node>
|
||||
void serialize_node_pointer(Archive& ar,Node*& p,boost::false_type /* load */)
|
||||
{
|
||||
typedef typename boost::remove_const<Node>::type node_type;
|
||||
typedef serialization_tracker<node_type> tracker;
|
||||
|
||||
tracker* pn;
|
||||
ar>>core::make_nvp("pointer",pn);
|
||||
p=const_cast<Node*>(
|
||||
reinterpret_cast<const Node*>(
|
||||
const_cast<const tracker*>(pn)));
|
||||
}
|
||||
|
||||
template<typename Archive,typename Node>
|
||||
void serialize_node_pointer(Archive& ar,Node*& p)
|
||||
{
|
||||
serialize_node_pointer(
|
||||
ar,p,
|
||||
boost::integral_constant<bool,Archive::is_saving::value>());
|
||||
}
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace unordered */
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2022-2023 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <boost/unordered/concurrent_flat_map_fwd.hpp>
|
||||
#include <boost/unordered/detail/foa/flat_map_types.hpp>
|
||||
#include <boost/unordered/detail/foa/table.hpp>
|
||||
#include <boost/unordered/detail/serialize_container.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/unordered_flat_map_fwd.hpp>
|
||||
|
||||
@ -696,6 +697,16 @@ namespace boost {
|
||||
return erase_if(map.table_, pred);
|
||||
}
|
||||
|
||||
template <class Archive,
|
||||
class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& map,
|
||||
unsigned int version)
|
||||
{
|
||||
detail::serialize_container(ar, map, version);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4714 */
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2022-2023 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include <boost/unordered/detail/foa/flat_set_types.hpp>
|
||||
#include <boost/unordered/detail/foa/table.hpp>
|
||||
#include <boost/unordered/detail/serialize_container.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/unordered_flat_set_fwd.hpp>
|
||||
|
||||
@ -505,6 +506,16 @@ namespace boost {
|
||||
return erase_if(set.table_, pred);
|
||||
}
|
||||
|
||||
template <class Archive,
|
||||
class Key, class Hash, class KeyEqual, class Allocator>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator>& set,
|
||||
unsigned int version)
|
||||
{
|
||||
detail::serialize_container(ar, set, version);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4714 */
|
||||
#endif
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
||||
// Copyright (C) 2005-2011 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2022-2023 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -16,11 +15,13 @@
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/requires_cxx11.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/explicit_operator_bool.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/type_traits/is_constructible.hpp>
|
||||
#include <boost/unordered/detail/map.hpp>
|
||||
#include <boost/unordered/detail/serialize_fca_container.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
@ -1059,6 +1060,13 @@ namespace boost {
|
||||
#endif
|
||||
}; // class template unordered_map
|
||||
|
||||
template <class Archive, class K, class T, class H, class P, class A>
|
||||
void serialize(
|
||||
Archive & ar,unordered_map<K, T, H, P, A>& m,unsigned int version)
|
||||
{
|
||||
detail::serialize_fca_container(ar, m, version);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
template <class InputIterator,
|
||||
@ -1762,6 +1770,13 @@ namespace boost {
|
||||
#endif
|
||||
}; // class template unordered_multimap
|
||||
|
||||
template <class Archive, class K, class T, class H, class P, class A>
|
||||
void serialize(
|
||||
Archive & ar,unordered_multimap<K, T, H, P, A>& m,unsigned int version)
|
||||
{
|
||||
detail::serialize_fca_container(ar, m, version);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
template <class InputIterator,
|
||||
@ -3019,6 +3034,21 @@ namespace boost {
|
||||
boost::swap(x.position, y.position);
|
||||
}
|
||||
} // namespace unordered
|
||||
|
||||
namespace serialization {
|
||||
template <class K, class T, class H, class P, class A>
|
||||
struct version<boost::unordered_map<K, T, H, P, A> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = 1);
|
||||
};
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
struct version<boost::unordered_multimap<K, T, H, P, A> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = 1);
|
||||
};
|
||||
} // namespace serialization
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <boost/unordered/detail/foa/node_handle.hpp>
|
||||
#include <boost/unordered/detail/foa/node_map_types.hpp>
|
||||
#include <boost/unordered/detail/foa/table.hpp>
|
||||
#include <boost/unordered/detail/serialize_container.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/unordered_node_map_fwd.hpp>
|
||||
|
||||
@ -788,6 +789,16 @@ namespace boost {
|
||||
return erase_if(map.table_, pred);
|
||||
}
|
||||
|
||||
template <class Archive,
|
||||
class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
unordered_node_map<Key, T, Hash, KeyEqual, Allocator>& map,
|
||||
unsigned int version)
|
||||
{
|
||||
detail::serialize_container(ar, map, version);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4714 */
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2022-2023 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include <boost/unordered/detail/foa/node_handle.hpp>
|
||||
#include <boost/unordered/detail/foa/node_set_types.hpp>
|
||||
#include <boost/unordered/detail/foa/table.hpp>
|
||||
#include <boost/unordered/detail/serialize_container.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/unordered_node_set_fwd.hpp>
|
||||
|
||||
@ -601,6 +602,16 @@ namespace boost {
|
||||
return erase_if(set.table_, pred);
|
||||
}
|
||||
|
||||
template <class Archive,
|
||||
class Key, class Hash, class KeyEqual, class Allocator>
|
||||
void serialize(
|
||||
Archive & ar,
|
||||
unordered_node_set<Key, Hash, KeyEqual, Allocator>& set,
|
||||
unsigned int version)
|
||||
{
|
||||
detail::serialize_container(ar, set, version);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4714 */
|
||||
#endif
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
||||
// Copyright (C) 2005-2011 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2022-2023 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -20,6 +19,7 @@
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/unordered/detail/set.hpp>
|
||||
#include <boost/unordered/detail/serialize_fca_container.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
@ -641,6 +641,13 @@ namespace boost {
|
||||
#endif
|
||||
}; // class template unordered_set
|
||||
|
||||
template <class Archive, class K, class H, class P, class A>
|
||||
void serialize(
|
||||
Archive & ar,unordered_set<K, H, P, A>& c,unsigned int version)
|
||||
{
|
||||
detail::serialize_fca_container(ar, c, version);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
template <class InputIterator,
|
||||
@ -1290,6 +1297,13 @@ namespace boost {
|
||||
#endif
|
||||
}; // class template unordered_multiset
|
||||
|
||||
template <class Archive, class K, class H, class P, class A>
|
||||
void serialize(
|
||||
Archive & ar,unordered_multiset<K, H, P, A>& c,unsigned int version)
|
||||
{
|
||||
detail::serialize_fca_container(ar, c, version);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
template <class InputIterator,
|
||||
@ -2367,6 +2381,21 @@ namespace boost {
|
||||
boost::swap(x.position, y.position);
|
||||
}
|
||||
} // namespace unordered
|
||||
|
||||
namespace serialization {
|
||||
template <class K, class H, class P, class A>
|
||||
struct version<boost::unordered_set<K, H, P, A> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = 1);
|
||||
};
|
||||
|
||||
template <class K, class H, class P, class A>
|
||||
struct version<boost::unordered_multiset<K, H, P, A> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = 1);
|
||||
};
|
||||
} // namespace serialization
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
|
Reference in New Issue
Block a user