Combination of Boost ICL and Boost Serialization

雨燕双飞 提交于 2020-01-16 04:13:29

问题


I'm trying to use the Boost Serialization library to archive Boost ICL interval sets (because I couldn't find any other more or less standard ways to serialize them). I want to split the serialize function into two functions save and load. Sorry to say, I'm stuck in the load function for now - I can't save even the size of the interval set. My testing program is below. The compiler complains about the line A << IS.iterative_size(), which is strange cause the return type of the iterative_size() function is the size_t.

#include <fstream>
#include <string>

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/split_free.hpp>

#include <boost/icl/discrete_interval.hpp>
#include <boost/icl/interval_set.hpp>

const std::string Filename = "tmp.archive";

typedef boost::icl::discrete_interval<int> Interval;
typedef boost::icl::interval_set<int> IntervalSet;

namespace boost
{
  namespace serialization
  {

    template<class Archive>
    void save(Archive& A, const IntervalSet& IS, const unsigned int)
    {
      A << IS.iterative_size();
      // ...
    }

    template<class Archive>
    void load(Archive& A, IntervalSet& IS, const unsigned int)
    {
      // ...
    }

    template<class Archive>
    inline void serialize(Archive& A, IntervalSet& IS, const unsigned int V)
    {
      split_free(A, IS, V); 
    }

  }
}

int main()
{
  std::ofstream f(Filename);
  if (f.good())
  {
    boost::archive::binary_oarchive oa(f);
    IntervalSet s;
    s += Interval::closed(100, 200); 
    oa << s;
    f.close();
  }
  else
  {
    std::cout << "Error" << std::endl;
  }
}

Any thoughts?

(Compiler - GCC 4.8.1, Boost - 1.55.0, OS - Xubuntu 3.11)


回答1:


iterative_size() doesn't return a lvalue, which is required. You can't usefully deserialize derived properties anyways (in much the same way as a vector doesn't (de)serialize the size() member result. Instead, it serializes all data, and the size() happens to end up being the same in the end.

Also look at

If there is no such default constructor, the function templates load_construct_data and perhaps save_construct_data will have to be overridden. Here is a simple example

From the docs

which can probably be used beneficially in cases where object instances get initialized from (non-default) constructor parameters only.

Update Here's a demo implementation: Live On Coliru

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/split_free.hpp>

#include <boost/icl/discrete_interval.hpp>
#include <boost/icl/interval_set.hpp>

namespace boost { namespace serialization {

    template <typename Archive, typename V>
        void save(Archive& ar, boost::icl::discrete_interval<V> const& di, unsigned) {
            auto const& bb = di.bounds().bits();
            auto const& l  = di.lower();
            auto const& u  = di.upper();

            ar << bb << l << u;
        }

    template <typename Archive, typename V>
        void load(Archive& ar, boost::icl::discrete_interval<V>& di, unsigned) {
            auto bb = di.bounds().bits();
            V    l, u;

            ar >> bb >> l >> u;

            di = boost::icl::discrete_interval<V>(l, u, boost::icl::interval_bounds(bb));
        }

    template <typename Archive, typename V>
        void serialize(Archive& ar, boost::icl::discrete_interval<V>& di, unsigned v) {
            split_free(ar, di, v);
        }

    template <typename Archive, typename V>
        void save(Archive& ar, boost::icl::interval_set<V> const& is, unsigned) {
            auto sz = is.iterative_size();

            ar & sz;
            for (auto& di : is) ar & di;
        }

    template <typename Archive, typename V>
        void load(Archive& ar, boost::icl::interval_set<V>& is, unsigned) {
            is.clear();

            size_t sz;
            ar & sz;

            size_t counter = sz;

            while (counter--) {
                typename boost::icl::interval_set<V>::value_type di;
                ar & di;
                is.insert(is.end(), di);
            }

            assert(is.iterative_size() == sz);
        }

    template <typename Archive, typename V>
        void serialize(Archive& ar, boost::icl::interval_set<V>& is, unsigned v)
        {
            split_free(ar, is, v);
        }
} }

const std::string Filename = "tmp.archive";

typedef boost::icl::discrete_interval<int> Interval;
typedef boost::icl::interval_set<int> IntervalSet;

#include <fstream>
#include <string>

int main()
{
    {
        std::ofstream f(Filename);
        boost::archive::binary_oarchive oa(f);
        IntervalSet s;
        s += Interval::closed(100, 200); 
        s += Interval::left_open(30,45);
        s += Interval::right_open(77, 78);

        oa << s;
    }
    {
        std::ifstream f(Filename);
        boost::archive::binary_iarchive ia(f);

        IntervalSet s;
        ia >> s;

        std::cout << "Deserialized: ";
        std::copy(s.begin(), s.end(), std::ostream_iterator<Interval>(std::cout, " "));
    }
}

Prints:

Deserialized: (30,45] [77,78) [100,200] 


来源:https://stackoverflow.com/questions/24004243/combination-of-boost-icl-and-boost-serialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!