Search code examples
c++serializationtreeboost-serialization

Serialization tree structure using boost::serialization


I have to serialize libkdtree++ in my program, the tree structures are briefly described as following:

struct _Node_base {
  _Node_base * _M_parent, *_M_left, * _M_right;

  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar & _M_left & _M_right;
  }
}

template<typename V>
struct _Node : public _Node_base {
  typedef V value_type;
  value_type value;
  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar.register_type(static_cast<_Node*>(NULL));
    ar & boost::serialization::base_object<_Node_base>(*this);
    ar & value;
  }
}

struct Tree {
  _Node * root;
  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar & root;
  }
}

This program reports "stream error". But from the "serailzed file", it lacks the value fields for the children nodes of roots. Thus I think it is possible that BaseNode serialized _M_left and _M_right pointer. However since _Node_base have no idea about the value type of _Node, so it looks hard to add "ar.register_type" to _Node_base.serialize().


Solution

  • The following solution for libkdtree++ & boost::serialization seems work:

    // KDTree::_Node
    friend class boost::serialization::access;
    template<class Archive>
    //void serialize(Archive & ar, const unsigned int version)
    void save(Archive & ar, const unsigned int version) const
    {
      ar.register_type(static_cast< _Link_type>(NULL));
      ar & boost::serialization::base_object<_Node_base>(*this);
      _Link_type left = static_cast<_Link_type>(_M_left);
      _Link_type right = static_cast<_Link_type>(_M_right);
      ar & left & right;
      ar & _M_value;
    }
    
    
    template<class Archive>
    void load(Archive & ar, const unsigned int version)
    {
        ar.register_type(static_cast< _Link_type>(NULL));
        ar & boost::serialization::base_object<_Node_base>(*this);
        _Link_type left, right;
        ar & left & right;
        ar & _M_value;
        if (left) {
           left->_M_parent = this;
        } 
        if (right) {
           right->_M_parent = this;
        }
        _M_left = left;
        _M_right = right;
    }
    
    BOOST_SERIALIZATION_SPLIT_MEMBER()