williamr@2: //=======================================================================
williamr@2: // Copyright 2005 Jeremy G. Siek
williamr@2: // Authors: Jeremy G. Siek
williamr@2: //
williamr@2: // Distributed under the Boost Software License, Version 1.0. (See
williamr@2: // accompanying file LICENSE_1_0.txt or copy at
williamr@2: // http://www.boost.org/LICENSE_1_0.txt)
williamr@2: //=======================================================================
williamr@2: #ifndef ADJ_LIST_SERIALIZE_HPP
williamr@2: #define ADJ_LIST_SERIALIZE_HPP
williamr@2: 
williamr@2: #include <boost/graph/adjacency_list.hpp>
williamr@2: #include <boost/pending/property_serialize.hpp>
williamr@2: #include <boost/config.hpp>
williamr@2: #include <boost/detail/workaround.hpp>
williamr@2: 
williamr@2: #include <boost/serialization/collections_save_imp.hpp>
williamr@2: #include <boost/serialization/collections_load_imp.hpp>
williamr@2: #include <boost/serialization/split_free.hpp>
williamr@2: 
williamr@2: namespace boost { 
williamr@2: 
williamr@2: namespace serialization {
williamr@2: 
williamr@2: // Turn off tracking for adjacency_list. It's not polymorphic, and we
williamr@2: // need to do this to enable saving of non-const adjacency lists.
williamr@2: template<class OEL, class VL, class D, class VP, class EP, class GP, class EL>
williamr@2: struct tracking_level<boost::adjacency_list<OEL,VL,D,VP,EP,GP,EL> > {
williamr@2:   typedef mpl::integral_c_tag tag;
williamr@2:   typedef mpl::int_<track_never> type;
williamr@2:   BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value);
williamr@2: };
williamr@2: 
williamr@2: template<class Archive, class OEL, class VL, class D, 
williamr@2:      class VP, class EP, class GP, class EL>
williamr@2: inline void save(
williamr@2:     Archive & ar,
williamr@2:     const boost::adjacency_list<OEL,VL,D,VP,EP,GP,EL> &graph,
williamr@2:     const unsigned int /* file_version */
williamr@2: ){
williamr@2:   typedef adjacency_list<OEL,VL,D,VP,EP,GP,EL> Graph;
williamr@2:   typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
williamr@2: 
williamr@2:   int V = num_vertices(graph);
williamr@2:   int E = num_edges(graph);
williamr@2:   ar << BOOST_SERIALIZATION_NVP(V);
williamr@2:   ar << BOOST_SERIALIZATION_NVP(E);
williamr@2: 
williamr@2:   // assign indices to vertices
williamr@2:   std::map<Vertex,int> indices;
williamr@2:   int num = 0;
williamr@2:   typename graph_traits<Graph>::vertex_iterator vi;
williamr@2:   for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi) {
williamr@2:     indices[*vi] = num++;
williamr@2:     ar << serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, *vi) );
williamr@2:   }
williamr@2:   
williamr@2:   // write edges
williamr@2:   typename graph_traits<Graph>::edge_iterator ei;
williamr@2:   for (ei = edges(graph).first; ei != edges(graph).second; ++ei){
williamr@2:     ar << serialization::make_nvp("u" , indices[source(*ei,graph)]);
williamr@2:     ar << serialization::make_nvp("v" , indices[target(*ei,graph)]);
williamr@2:     ar << serialization::make_nvp("edge_property", get(edge_all_t(), graph, *ei) );
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@2: 
williamr@2: template<class Archive, class OEL, class VL, class D,
williamr@2:      class VP, class EP, class GP, class EL>
williamr@2: inline void load(
williamr@2:     Archive & ar,
williamr@2:     boost::adjacency_list<OEL,VL,D,VP,EP,GP,EL> &graph,
williamr@2:     const unsigned int /* file_version */
williamr@2: ){
williamr@2:   typedef adjacency_list<OEL,VL,D,VP,EP,GP,EL> Graph;
williamr@2:   typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
williamr@2:   typedef typename graph_traits<Graph>::edge_descriptor Edge;
williamr@2: 
williamr@2:   unsigned int V;
williamr@2:   ar >> BOOST_SERIALIZATION_NVP(V);
williamr@2:   unsigned int E;
williamr@2:   ar >> BOOST_SERIALIZATION_NVP(E);
williamr@2:   
williamr@2:   std::vector<Vertex> verts(V);
williamr@2:   int i = 0;
williamr@2:   while(V-- > 0){
williamr@2:     Vertex v = add_vertex(graph);
williamr@2:     verts[i++] = v;
williamr@2:     ar >> serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, v) );
williamr@2:   }
williamr@2:   while(E-- > 0){
williamr@2:     int u; int v;
williamr@2:     ar >> BOOST_SERIALIZATION_NVP(u);
williamr@2:     ar >> BOOST_SERIALIZATION_NVP(v);
williamr@2:     Edge e; bool inserted;
williamr@2:     tie(e,inserted) = add_edge(verts[u], verts[v], graph);
williamr@2:     ar >> serialization::make_nvp("edge_property", get(edge_all_t(), graph, e) );
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@2: template<class Archive, class OEL, class VL, class D, class VP, class EP, class GP, class EL>
williamr@2: inline void serialize(
williamr@2:     Archive & ar,
williamr@2:     boost::adjacency_list<OEL,VL,D,VP,EP,GP,EL> &graph,
williamr@2:     const unsigned int file_version
williamr@2: ){
williamr@2:     boost::serialization::split_free(ar, graph, file_version);
williamr@2: }
williamr@2: 
williamr@2: }//serialization
williamr@2: }//boost
williamr@2: 
williamr@2: 
williamr@2: #endif // ADJ_LIST_SERIALIZE_HPP