1 //=======================================================================
2 // Copyright 2001 Universite Joseph Fourier, Grenoble.
3 // Author: Francois 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>
15 #include <boost/graph/iteration_macros.hpp>
18 // Method read to parse an adjacency list from an input stream. Examples:
20 // cin >> read( G, NodePropertySubset(), EdgepropertySubset() );
22 // Method write to print an adjacency list to an output stream. Examples:
23 // cout << write( G );
24 // cout << write( G, NodePropertySubset(), EdgepropertySubset() );
29 - basic property input
37 //===========================================================================
38 // basic property input
40 template<class Tag, class Value, class Next>
41 std::istream& operator >> ( std::istream& in, property<Tag,Value,Next>& p )
43 in >> p.m_value >> p.m_base; // houpla !!
47 template<class Tag, class Value>
48 std::istream& operator >> ( std::istream& in, property<Tag,Value,no_property>& p )
54 inline std::istream& operator >> ( std::istream& in, no_property& )
59 // basic property input
60 //===========================================================================
61 // get property subsets
63 // get a single property tagged Stag
64 template<class Tag, class Value, class Next, class V, class Stag>
66 ( property<Tag,Value,Next>& p, const V& v, Stag s )
71 template<class Value, class Next, class V, class Stag>
73 ( property<Stag,Value,Next>& p, const V& v, Stag )
78 // get a subset of properties tagged Stag
79 template<class Tag, class Value, class Next,
80 class Stag, class Svalue, class Snext>
82 ( property<Tag,Value,Next>& p, const property<Stag,Svalue,Snext>& s )
84 get( p, s.m_value, Stag() );
85 getSubset( p, s.m_base );
88 template<class Tag, class Value, class Next,
89 class Stag, class Svalue>
91 ( property<Tag,Value,Next>& p, const property<Stag,Svalue,no_property>& s)
93 get( p, s.m_value, Stag() );
97 ( no_property&, const no_property& )
101 #if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
102 template<typename T, typename U>
103 void getSubset(T& p, const U& s)
109 void getSubset(T&, const no_property&)
116 // get property subset
117 //===========================================================================
119 typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } GraphParserState;
121 template<class Graph_t, class VertexProperty, class EdgeProperty, class VertexPropertySubset,
122 class EdgePropertySubset>
126 typedef Graph_t Graph;
128 GraphParser( Graph* g ): graph(g)
131 GraphParser& operator () ( std::istream& in )
133 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
134 std::vector<Vertex> nodes;
136 GraphParserState state = PARSE_VERTEX;
138 unsigned int numLine = 1;
142 if( c== '#' ) skip(in);
143 else if( c== 'n' ) state = PARSE_NUM_NODES;
144 else if( c== 'v' ) state = PARSE_VERTEX;
145 else if( c== 'e' ) state = PARSE_EDGE;
146 else if( c== '\n' ) numLine++;
147 else if( !std::isspace(c) ){
149 if( state == PARSE_VERTEX ){
150 VertexPropertySubset readProp;
154 getSubset( vp, readProp );
155 nodes.push_back( add_vertex(vp, *graph) );
158 std::cerr<<"read vertex, parse error at line"<<numLine<<std::endl;
160 else if( state == PARSE_EDGE ) {
162 EdgePropertySubset readProp;
163 in >> source >> target;
167 getSubset( ep, readProp );
168 add_edge(nodes[source], nodes[target], ep, *graph);
171 std::cerr<<"read edge, parse error at line"<<numLine<<std::endl;
173 else { // state == PARSE_NUM_NODES
176 for( int i=0; i<n; ++i )
177 nodes.push_back( add_vertex( *graph ));
180 std::cerr<<"read num_nodes, parse error at line "<< numLine << std::endl;
192 void skip( std::istream& in )
195 while( c!='\n' && !in.eof() )
202 //=======================================================================
205 #if defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
206 template<class Graph, class Property>
207 struct PropertyPrinter
209 typedef typename Property::value_type Value;
210 typedef typename Property::tag_type Tag;
211 typedef typename Property::next_type Next;
213 PropertyPrinter( const Graph& g ):graph(&g){}
216 PropertyPrinter& operator () ( std::ostream& out, const Val& v )
218 typename property_map<Graph,Tag>::const_type ps = get(Tag(), *graph);
219 out << ps[ v ] <<" ";
220 PropertyPrinter<Graph,Next> print(*graph);
228 template<class Graph, typename Property>
229 struct PropertyPrinter
231 PropertyPrinter( const Graph& g ):graph(&g){}
234 PropertyPrinter& operator () ( std::ostream& out, const Val& v )
236 out << (*graph)[ v ] <<" ";
243 template<class Graph, typename Tag, typename Value, typename Next>
244 struct PropertyPrinter<Graph, property<Tag, Value, Next> >
246 PropertyPrinter( const Graph& g ):graph(&g){}
249 PropertyPrinter& operator () ( std::ostream& out, const Val& v )
251 typename property_map<Graph,Tag>::const_type ps = get(Tag(), *graph);
252 out << ps[ v ] <<" ";
253 PropertyPrinter<Graph,Next> print(*graph);
262 template<class Graph>
263 struct PropertyPrinter<Graph, no_property>
265 PropertyPrinter( const Graph& ){}
268 PropertyPrinter& operator () ( std::ostream&, const Val& ){ return *this; }
272 //=========================================================================
275 template<class Graph_t, class EdgeProperty>
279 typedef Graph_t Graph;
280 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
282 EdgePrinter( const Graph& g )
286 const EdgePrinter& operator () ( std::ostream& out ) const
288 // assign indices to vertices
289 std::map<Vertex,int> indices;
291 BGL_FORALL_VERTICES_T(v, graph, Graph) {
296 PropertyPrinter<Graph, EdgeProperty> print_Edge(graph);
297 out << "e" << std::endl;
298 BGL_FORALL_EDGES_T(e, graph, Graph) {
299 out << indices[source(e,graph)] << " " << indices[target(e,graph)] << " ";
313 template<class Graph, class V, class E>
314 struct GraphPrinter: public EdgePrinter<Graph,E>
316 GraphPrinter( const Graph& g )
317 : EdgePrinter<Graph,E>(g)
320 const GraphPrinter& operator () ( std::ostream& out ) const
322 PropertyPrinter<Graph, V> printNode(this->graph);
323 out << "v"<<std::endl;
324 BGL_FORALL_VERTICES_T(v, this->graph, Graph) {
329 EdgePrinter<Graph,E>::operator ()( out );
334 template<class Graph, class E>
335 struct GraphPrinter<Graph,no_property,E>
336 : public EdgePrinter<Graph,E>
338 GraphPrinter( const Graph& g )
339 : EdgePrinter<Graph,E>(g)
342 const GraphPrinter& operator () ( std::ostream& out ) const
344 out << "n "<< num_vertices(this->graph) << std::endl;
345 EdgePrinter<Graph,E>::operator ()( out );
351 //=========================================================================
354 /// input stream for reading a graph
355 template<class Graph, class VP, class EP, class VPS, class EPS>
356 std::istream& operator >> ( std::istream& in, GraphParser<Graph,VP,EP,VPS,EPS> gp )
362 /// graph parser for given subsets of internal vertex and edge properties
363 template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
364 GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>
365 read( adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS vps, EPS eps )
367 return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>(&g);
370 /// graph parser for all internal vertex and edge properties
371 template<class EL, class VL, class D, class VP, class EP, class GP>
372 GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>
373 read( adjacency_list<EL,VL,D,VP,EP,GP>& g )
375 return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>(&g);
379 /// output stream for writing a graph
380 template<class Graph, class VP, class EP>
381 std::ostream& operator << ( std::ostream& out, const GraphPrinter<Graph,VP,EP>& gp )
387 /// write the graph with given property subsets
388 template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
389 GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>
390 write( const adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS, EPS )
392 return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>(g);
395 /// write the graph with all internal vertex and edge properties
396 template<class EL, class VL, class D, class VP, class EP, class GP>
397 GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>
398 write( const adjacency_list<EL,VL,D,VP,EP,GP>& g )
400 return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>(g);
404 //=========================================================================