Search code examples
serializationboostvectorcontainersinterprocess

How to serialize boost::interprocess::containers::vector


I'd like to use boost serilaization with an boost::interprocess::containers::vector

The serialization of a std::vector works fine by including

#include <boost/interprocess/containers/vector.hpp>

But I have a class containing a shared vector

class MyClass {
  public:
    typedef boost::interprocess::allocator<double, SegmentManager> Allocator;
    typedef boost::interprocess::vector<double, Allocator > VectorDouble;
    VectorDouble *pVar;

    template<class archive>  
    void serialize ( archive &ar, const unsigned int version ) {
        using boost::serialization::make_nvp;
        ar & make_nvp ( "data", *pVar; );  # This does not work
        # what works it creating a std::vector and copy the data
    }
...
    MyClass(){
      # creating the shared memory and the pointer ot pVarß
    }

    ~MyClass(){
      # release data
    }
}

I am getting the error:

error: ‘class boost::container::vector<double, boost::interprocess::allocator<double, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> > >’ has no member named ‘serialize’

Solution

  • based on the header I wrote the following header which allows the serialization of an interprocess vector. More details can be found in my github repo.

    Greetings Markus

    #ifndef SHMFW_SERIALIZATION_INTERPROCESS_VECTOR_HPP
    #define SHMFW_SERIALIZATION_INTERPROCESS_VECTOR_HPP
    
    
    #include <boost/serialization/vector.hpp>
    #include <boost/interprocess/containers/vector.hpp>
    
    namespace boost { 
    namespace serialization {
    
    template<class Archive, class U, class Allocator>
    
    inline void save(
        Archive & ar,
        const boost::interprocess::vector<U, Allocator> &t,
        const unsigned int file_version
    ){
        boost::serialization::stl::save_collection<Archive, boost::interprocess::vector<U, Allocator> >(
            ar, t
        );
    }
    
    template<class Archive, class U, class Allocator>
    inline void load(
        Archive & ar,
        boost::interprocess::vector<U, Allocator> &t,
        const unsigned int file_version
    ){
    #ifdef BOOST_SERIALIZATION_VECTOR_135_HPP
        if (ar.get_library_version()==boost::archive::library_version_type(5))
        {
          load(ar,t,file_version, boost::is_arithmetic<U>());
          return;
        }
    #endif
        boost::serialization::stl::load_collection<
            Archive,
            boost::interprocess::vector<U, Allocator>,
            boost::serialization::stl::archive_input_seq<
                Archive, boost::interprocess::vector<U, Allocator> 
            >,
            boost::serialization::stl::reserve_imp<boost::interprocess::vector<U, Allocator> >
        >(ar, t);
    }
    
    // split non-intrusive serialization function member into separate
    // non intrusive save/load member functions
    template<class Archive, class U, class Allocator>
    inline void serialize(
        Archive & ar,
        boost::interprocess::vector<U, Allocator> & t,
        const unsigned int file_version
    ){
        boost::serialization::split_free(ar, t, file_version);
    }
    
    #if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    
    /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
    // vector<bool>
    template<class Archive, class Allocator>
    inline void save(
        Archive & ar,
        const boost::interprocess::vector<bool, Allocator> &t,
        const unsigned int /* file_version */
    ){
        // record number of elements
        collection_size_type count (t.size());
        ar << BOOST_SERIALIZATION_NVP(count);
        boost::interprocess::vector<bool>::const_iterator it = t.begin();
        while(count-- > 0){
            bool tb = *it++;
            ar << boost::serialization::make_nvp("item", tb);
        }
    }
    
    template<class Archive, class Allocator>
    inline void load(
        Archive & ar,
        boost::interprocess::vector<bool, Allocator> &t,
        const unsigned int /* file_version */
    ){
        // retrieve number of elements
        collection_size_type count;
        ar >> BOOST_SERIALIZATION_NVP(count);
        t.clear();
        while(count-- > 0){
            bool i;
            ar >> boost::serialization::make_nvp("item", i);
            t.push_back(i);
        }
    }
    
    // split non-intrusive serialization function member into separate
    // non intrusive save/load member functions
    template<class Archive, class Allocator>
    inline void serialize(
        Archive & ar,
        boost::interprocess::vector<bool, Allocator> & t,
        const unsigned int file_version
    ){
        boost::serialization::split_free(ar, t, file_version);
    }
    
    #endif // BOOST_WORKAROUND
    
    };
    };
    
    #endif // SHMFW_SERIALIZATION_INTERPROCESS_VECTOR_HPP