Boost logo

Boost Users :

Subject: Re: [Boost-users] [Serialization][BGL] problem serializing an edge
From: Ireneusz Szcześniak (irek.szczesniak_at_[hidden])
Date: 2010-07-25 17:11:03


Hi Cedric and others,

I tried to solve the problem non-intrusively by implementing the
serialize function like this:

namespace boost {
namespace serialization {

template<class Archive>
void serialize(Archive &ar, Edge &g, const unsigned int version) {...}

}
}

I wanted to serialize the edge e by serializing the vertexes of the
edge, but to do this I need a reference to graph g. Having e and g, I
would call source(e, g) and target(e, g) to get the vertexes.

The problem is that in serializing an edge, I would have to pass to
the serialize function a reference to graph g. Below there is a
complete example that passes a pair of an edge and a graph for
serialization.

#include <cassert>
#include <iostream>
#include <sstream>
#include <utility>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/graph/adj_list_serialize.hpp>

using namespace std;
using namespace boost;

typedef adjacency_list<listS, vecS, undirectedS> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef pair<Edge &, const Graph &> SEdge;

namespace boost {
   namespace serialization {

     template<class A>
     void load(A &ar, SEdge &p, const unsigned int)
     {
       Vertex s, t;
       ar & s & t;
       p.first = edge(s, t, p.second).first;
     }

     template<class A>
     void save(A &ar, const SEdge &p, const unsigned int)
     {
       Vertex s = source(p.first, p.second);
       Vertex t = target(p.first, p.second);
       ar & s & t;
     }

  }
}

BOOST_SERIALIZATION_SPLIT_FREE(SEdge)

int
main()
{
   stringstream str;

   {
     Graph g(2);
     add_edge(0, 1, g);
     Edge e = edge(0, 1, g).first;
     boost::archive::text_oarchive oa(str);
     oa << g;
     SEdge se(e, g);
     oa << se;
   }

   {
     Graph g;
     Edge e;
     boost::archive::text_iarchive ia(str);
     ia >> g;
     SEdge se(e, g);
     ia >> se;
     assert(source(e, g) == 0);
     assert(target(e, g) == 1);
   }

   return 0;
}

In my code, what I really want to serialize is a std::list, where the
elements are of type Edge. I could make SEdge (defined in the example
above), and then serialize the list with boost/serialization/list.hpp,
but then I have to heavily modify my code, which I would like to avoid.

One solution that comes to mind is to make the graph a global object,
and so my code for serializing an edge would use that global object.
However, this is an uglu hack, and I would like to avoid this too.

Ideally, I would like to pass a function object to the serialization
library. The serialization library would ask the function object to
serialize an edge, and that function object would know how to do it,
because one of its fields would be a reference to the graph object.

Is there a way to pass such a function object to the serialization
library?

Thanks,
Irek

Cedric Laczny wrote:

> Hi Irek,
>
> you did not mention if you tried the operator& instead of operator<<.
> I could imagine that the fact, that you are using nested properties might
> impose problems to the operator<<. However, I am not sure if this can be fixed
> by using operator&, but it could be worth a try.
>
> Best,
>
> Cedric

-- 
Ireneusz (Irek) Szczesniak
http://www.irkos.org

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net