1 //=======================================================================
2 // Copyright 2001 Universite Joseph Fourier, Grenoble.
3 // Author: François Faure
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //=======================================================================
9 #ifndef BOOST_GRAPH_ADJACENCY_LIST_IO_HPP
10 #define BOOST_GRAPH_ADJACENCY_LIST_IO_HPP
14 #include <boost/graph/adjacency_list.hpp>
17 // Method read to parse an adjacency list from an input stream. Examples:
19 // cin >> read( G, NodePropertySubset(), EdgepropertySubset() );
21 // Method write to print an adjacency list to an output stream. Examples:
22 // cout << write( G );
23 // cout << write( G, NodePropertySubset(), EdgepropertySubset() );
28 - basic property input
36 //===========================================================================
37 // basic property input
39 template<class Tag, class Value, class Next>
40 std::istream& operator >> ( std::istream& in, property<Tag,Value,Next>& p )
42 in >> p.m_value >> *(static_cast<Next*>(&p)); // houpla !!
46 template<class Tag, class Value>
47 std::istream& operator >> ( std::istream& in, property<Tag,Value,no_property>& p )
53 inline std::istream& operator >> ( std::istream& in, no_property& )
58 // basic property input
59 //===========================================================================
60 // get property subsets
62 // get a single property tagged Stag
63 template<class Tag, class Value, class Next, class V, class Stag>
65 ( property<Tag,Value,Next>& p, const V& v, Stag s )
67 get( *(static_cast<Next*>(&p)),v,s );
70 template<class Value, class Next, class V, class Stag>
72 ( property<Stag,Value,Next>& p, const V& v, Stag )
77 // get a subset of properties tagged Stag
78 template<class Tag, class Value, class Next,
79 class Stag, class Svalue, class Snext>
81 ( property<Tag,Value,Next>& p, const property<Stag,Svalue,Snext>& s )
83 get( p, s.m_value, Stag() );
84 getSubset( p, Snext(s) );
87 template<class Tag, class Value, class Next,
88 class Stag, class Svalue>
90 ( property<Tag,Value,Next>& p, const property<Stag,Svalue,no_property>& s)
92 get( p, s.m_value, Stag() );
96 ( no_property& p, const no_property& s )
100 #if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
101 template<typename T, typename U>
102 void getSubset(T& p, const U& s)
108 void getSubset(T&, const no_property&)
115 // get property subset
116 //===========================================================================
118 typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } GraphParserState;
120 template<class Graph_t, class VertexProperty, class EdgeProperty, class VertexPropertySubset,
121 class EdgePropertySubset>
125 typedef Graph_t Graph;
127 GraphParser( Graph* g ): graph(g)
130 GraphParser& operator () ( std::istream& in )
132 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
133 std::vector<Vertex> nodes;
135 GraphParserState state = PARSE_VERTEX;
137 unsigned int numLine = 1;
141 if( c== '#' ) skip(in);
142 else if( c== 'n' ) state = PARSE_NUM_NODES;
143 else if( c== 'v' ) state = PARSE_VERTEX;
144 else if( c== 'e' ) state = PARSE_EDGE;
145 else if( c== '\n' ) numLine++;
146 else if( !std::isspace(c) ){
148 if( state == PARSE_VERTEX ){
149 VertexPropertySubset readProp;
153 getSubset( vp, readProp );
154 nodes.push_back( add_vertex(vp, *graph) );
157 std::cerr<<"read vertex, parse error at line"<<numLine<<std::endl;
159 else if( state == PARSE_EDGE ) {
161 EdgePropertySubset readProp;
162 in >> source >> target;
166 getSubset( ep, readProp );
167 add_edge(nodes[source], nodes[target], ep, *graph);
170 std::cerr<<"read edge, parse error at line"<<numLine<<std::endl;
172 else { // state == PARSE_NUM_NODES
175 for( int i=0; i<n; ++i )
176 nodes.push_back( add_vertex( *graph ));
179 std::cerr<<"read num_nodes, parse error at line "<< numLine << std::endl;
191 void skip( std::istream& in )
194 while( c!='\n' && !in.eof() )
201 //=======================================================================
204 #if defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
205 template<class Graph, class Property>
206 struct PropertyPrinter
208 typedef typename Property::value_type Value;
209 typedef typename Property::tag_type Tag;
210 typedef typename Property::next_type Next;
212 PropertyPrinter( const Graph& g ):graph(&g){}
214 template<class Iterator>
215 PropertyPrinter& operator () ( std::ostream& out, Iterator it )
217 typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);
218 out << ps[ *it ] <<" ";
219 PropertyPrinter<Graph,Next> print(*graph);
227 template<class Graph, typename Property>
228 struct PropertyPrinter
230 PropertyPrinter( const Graph& g ):graph(&g){}
232 template<class Iterator>
233 PropertyPrinter& operator () ( std::ostream& out, Iterator it )
235 out << (*graph)[ *it ] <<" ";
242 template<class Graph, typename Tag, typename Value, typename Next>
243 struct PropertyPrinter<Graph, property<Tag, Value, Next> >
245 PropertyPrinter( const Graph& g ):graph(&g){}
247 template<class Iterator>
248 PropertyPrinter& operator () ( std::ostream& out, Iterator it )
250 typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);
251 out << ps[ *it ] <<" ";
252 PropertyPrinter<Graph,Next> print(*graph);
261 template<class Graph>
262 struct PropertyPrinter<Graph, no_property>
264 PropertyPrinter( const Graph& ){}
266 template<class Iterator>
267 PropertyPrinter& operator () ( std::ostream&, Iterator it ){ return *this; }
271 //=========================================================================
274 template<class Graph_t, class EdgeProperty>
278 typedef Graph_t Graph;
279 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
281 EdgePrinter( const Graph& g )
285 const EdgePrinter& operator () ( std::ostream& out ) const
287 // assign indices to vertices
288 std::map<Vertex,int> indices;
290 typename graph_traits<Graph>::vertex_iterator vi;
291 for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi){
292 indices[*vi] = num++;
296 PropertyPrinter<Graph, EdgeProperty> print_Edge(graph);
297 out << "e" << std::endl;
298 typename graph_traits<Graph>::edge_iterator ei;
299 for (ei = edges(graph).first; ei != edges(graph).second; ++ei){
300 out << indices[source(*ei,graph)] << " " << indices[target(*ei,graph)] << " ";
314 template<class Graph, class V, class E>
315 struct GraphPrinter: public EdgePrinter<Graph,E>
317 GraphPrinter( const Graph& g )
318 : EdgePrinter<Graph,E>(g)
321 const GraphPrinter& operator () ( std::ostream& out ) const
323 PropertyPrinter<Graph, V> printNode(this->graph);
324 out << "v"<<std::endl;
325 typename graph_traits<Graph>::vertex_iterator vi;
326 for (vi = vertices(this->graph).first; vi != vertices(this->graph).second; ++vi){
331 EdgePrinter<Graph,E>::operator ()( out );
336 template<class Graph, class E>
337 struct GraphPrinter<Graph,no_property,E>
338 : public EdgePrinter<Graph,E>
340 GraphPrinter( const Graph& g )
341 : EdgePrinter<Graph,E>(g)
344 const GraphPrinter& operator () ( std::ostream& out ) const
346 out << "n "<< num_vertices(this->graph) << std::endl;
347 EdgePrinter<Graph,E>::operator ()( out );
353 //=========================================================================
356 /// input stream for reading a graph
357 template<class Graph, class VP, class EP, class VPS, class EPS>
358 std::istream& operator >> ( std::istream& in, GraphParser<Graph,VP,EP,VPS,EPS> gp )
364 /// graph parser for given subsets of internal vertex and edge properties
365 template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
366 GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>
367 read( adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS vps, EPS eps )
369 return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>(&g);
372 /// graph parser for all internal vertex and edge properties
373 template<class EL, class VL, class D, class VP, class EP, class GP>
374 GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>
375 read( adjacency_list<EL,VL,D,VP,EP,GP>& g )
377 return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>(&g);
381 /// output stream for writing a graph
382 template<class Graph, class VP, class EP>
383 std::ostream& operator << ( std::ostream& out, const GraphPrinter<Graph,VP,EP>& gp )
389 /// write the graph with given property subsets
390 template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
391 GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>
392 write( const adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS, EPS )
394 return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>(g);
397 /// write the graph with all internal vertex and edge properties
398 template<class EL, class VL, class D, class VP, class EP, class GP>
399 GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>
400 write( const adjacency_list<EL,VL,D,VP,EP,GP>& g )
402 return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>(g);
406 //=========================================================================