Boost ptr_vectorのシリアライズ

公開:2006-02-08 06:21
更新:2020-02-15 04:36
カテゴリ:boost,windows,c++

boost.ptr_vectorをシリアライズするため、boost/serialization/vector.hppをカスタマイズしてシリアライザを作成してみたが、下記の違いによってそのままでは動作しなかった。

・イテレータが指す値の違い

iteratorはvectorではコンテナに収納される型の値となる。
その意味で行くとptr_vectorでの
iteratorはポインタ値となるが、ポインタが指す値そのものを返す仕様になっている。
http://www.boost.org/libs/ptr_container/doc/tutorial.html#indirected-interface
これは(*this)->member_func()と書かなくて良いようにとか、ポインタ値をそのまま返すことの危険性を避けるという理由があると思うが、いずれにせよ意味が違うことには変わりない。

そういうことで、とりあえず動くように「ベタ」に改造した。


#ifndef  SF_SERIALIZATION_PTR_VECTOR_HPP
#define SF_SERIALIZATION_PTR_VECTOR_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// ptr_vector.hpp: serialization for pointer vector templates
#include <boost/ptr_container/ptr_container.hpp>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/serialization/split_free.hpp>
namespace boost {
namespace serialization {
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
template<class Archive, class U, class CloneAllocator,class Allocator>
inline void save(
Archive & ar,
const boost::ptr_vector<U,CloneAllocator, Allocator> &t,
const unsigned int /* file_version */
){
boost::serialization::save_ptr_collection<Archive, boost::ptr_vector<U,CloneAllocator, Allocator> >(
ar, t
);
}
template<class Archive, class Container>
inline void save_ptr_collection(Archive & ar, const Container &s)
{
// record number of elements
unsigned int count = s.size();
ar << BOOST_SERIALIZATION_NVP(count);
BOOST_DEDUCED_TYPENAME Container::const_iterator it = s.begin();
while(count-- > 0){
Container::value_type pt_ = static_cast<Container::value_type>(*it.base());
ar << boost::serialization::make_nvp("item", pt_);
++it;
}
}
template<class Archive, class U, class CloneAllocator,class Allocator>
inline void load(
Archive & ar,
boost::ptr_vector<U,CloneAllocator, Allocator> &t,
const unsigned int /* file_version */
){
typedef boost::ptr_vector<U,CloneAllocator, Allocator>::value_type value_type;
t.clear();
// retrieve number of elements
unsigned int count;
ar >> BOOST_SERIALIZATION_NVP(count);
while(count-- > 0){
value_type pt_;
ar & boost::serialization::make_nvp("item", pt_);
t.push_back(pt_);
}
}
// split non-intrusive serialization function member into separate
// non intrusive save/load member functions
template<class Archive, class U, class CloneAllocator,class Allocator>
inline void serialize(
Archive & ar,
boost::ptr_vector<U,CloneAllocator, Allocator> & t,
const unsigned int file_version
){
boost::serialization::split_free(ar, t, file_version);
}
} // serialization
} // namespace boost
#endif // SF_SERIALIZATION_PTR_VECTOR_HPP<br/>