adjacency_list_io.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. //=======================================================================
  2. // Copyright 2001 Universite Joseph Fourier, Grenoble.
  3. // Author: Francois Faure
  4. //
  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
  11. #include <iostream>
  12. #include <vector>
  13. #include <boost/graph/adjacency_list.hpp>
  14. #include <boost/graph/iteration_macros.hpp>
  15. #include <cctype>
  16. // Method read to parse an adjacency list from an input stream. Examples:
  17. // cin >> read( G );
  18. // cin >> read( G, NodePropertySubset(), EdgepropertySubset() );
  19. //
  20. // Method write to print an adjacency list to an output stream. Examples:
  21. // cout << write( G );
  22. // cout << write( G, NodePropertySubset(), EdgepropertySubset() );
  23. namespace boost {
  24. /* outline
  25. - basic property input
  26. - get property subset
  27. - graph parser
  28. - property printer
  29. - graph printer
  30. - user methods
  31. */
  32. //===========================================================================
  33. // basic property input
  34. template<class Tag, class Value, class Next>
  35. std::istream& operator >> ( std::istream& in, property<Tag,Value,Next>& p )
  36. {
  37. in >> p.m_value >> p.m_base; // houpla !!
  38. return in;
  39. }
  40. template<class Tag, class Value>
  41. std::istream& operator >> ( std::istream& in, property<Tag,Value,no_property>& p )
  42. {
  43. in >> p.m_value;
  44. return in;
  45. }
  46. inline std::istream& operator >> ( std::istream& in, no_property& )
  47. {
  48. return in;
  49. }
  50. // basic property input
  51. //===========================================================================
  52. // get property subsets
  53. // get a single property tagged Stag
  54. template<class Tag, class Value, class Next, class V, class Stag>
  55. void get
  56. ( property<Tag,Value,Next>& p, const V& v, Stag s )
  57. {
  58. get( p.m_base,v,s );
  59. }
  60. template<class Value, class Next, class V, class Stag>
  61. void get
  62. ( property<Stag,Value,Next>& p, const V& v, Stag )
  63. {
  64. p.m_value = v;
  65. }
  66. // get a subset of properties tagged Stag
  67. template<class Tag, class Value, class Next,
  68. class Stag, class Svalue, class Snext>
  69. void getSubset
  70. ( property<Tag,Value,Next>& p, const property<Stag,Svalue,Snext>& s )
  71. {
  72. get( p, s.m_value, Stag() );
  73. getSubset( p, s.m_base );
  74. }
  75. template<class Tag, class Value, class Next,
  76. class Stag, class Svalue>
  77. void getSubset
  78. ( property<Tag,Value,Next>& p, const property<Stag,Svalue,no_property>& s)
  79. {
  80. get( p, s.m_value, Stag() );
  81. }
  82. inline void getSubset
  83. ( no_property&, const no_property& )
  84. {
  85. }
  86. #if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
  87. template<typename T, typename U>
  88. void getSubset(T& p, const U& s)
  89. {
  90. p = s;
  91. }
  92. template<typename T>
  93. void getSubset(T&, const no_property&)
  94. {
  95. }
  96. #endif
  97. // get property subset
  98. //===========================================================================
  99. // graph parser
  100. typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } GraphParserState;
  101. template<class Graph_t, class VertexProperty, class EdgeProperty, class VertexPropertySubset,
  102. class EdgePropertySubset>
  103. struct GraphParser
  104. {
  105. typedef Graph_t Graph;
  106. GraphParser( Graph* g ): graph(g)
  107. {}
  108. GraphParser& operator () ( std::istream& in )
  109. {
  110. typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  111. std::vector<Vertex> nodes;
  112. GraphParserState state = PARSE_VERTEX;
  113. unsigned int numLine = 1;
  114. char c;
  115. while ( in.get(c) )
  116. {
  117. if( c== '#' ) skip(in);
  118. else if( c== 'n' ) state = PARSE_NUM_NODES;
  119. else if( c== 'v' ) state = PARSE_VERTEX;
  120. else if( c== 'e' ) state = PARSE_EDGE;
  121. else if( c== '\n' ) numLine++;
  122. else if( !std::isspace(c) ){
  123. in.putback(c);
  124. if( state == PARSE_VERTEX ){
  125. VertexPropertySubset readProp;
  126. if( in >> readProp )
  127. {
  128. VertexProperty vp;
  129. getSubset( vp, readProp );
  130. nodes.push_back( add_vertex(vp, *graph) );
  131. }
  132. else
  133. std::cerr<<"read vertex, parse error at line"<<numLine<<std::endl;
  134. }
  135. else if( state == PARSE_EDGE ) {
  136. int source, target;
  137. EdgePropertySubset readProp;
  138. in >> source >> target;
  139. if( in >> readProp )
  140. {
  141. EdgeProperty ep;
  142. getSubset( ep, readProp );
  143. add_edge(nodes[source], nodes[target], ep, *graph);
  144. }
  145. else
  146. std::cerr<<"read edge, parse error at line"<<numLine<<std::endl;
  147. }
  148. else { // state == PARSE_NUM_NODES
  149. int n;
  150. if( in >> n ){
  151. for( int i=0; i<n; ++i )
  152. nodes.push_back( add_vertex( *graph ));
  153. }
  154. else
  155. std::cerr<<"read num_nodes, parse error at line "<< numLine << std::endl;
  156. }
  157. }
  158. }
  159. return (*this);
  160. }
  161. protected:
  162. Graph* graph;
  163. void skip( std::istream& in )
  164. {
  165. char c = 0;
  166. while( c!='\n' && !in.eof() )
  167. in.get(c);
  168. in.putback(c);
  169. }
  170. };
  171. // parser
  172. //=======================================================================
  173. // property printer
  174. #if defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
  175. template<class Graph, class Property>
  176. struct PropertyPrinter
  177. {
  178. typedef typename Property::value_type Value;
  179. typedef typename Property::tag_type Tag;
  180. typedef typename Property::next_type Next;
  181. PropertyPrinter( const Graph& g ):graph(&g){}
  182. template<class Val>
  183. PropertyPrinter& operator () ( std::ostream& out, const Val& v )
  184. {
  185. typename property_map<Graph,Tag>::const_type ps = get(Tag(), *graph);
  186. out << ps[ v ] <<" ";
  187. PropertyPrinter<Graph,Next> print(*graph);
  188. print(out, v);
  189. return (*this);
  190. }
  191. private:
  192. const Graph* graph;
  193. };
  194. #else
  195. template<class Graph, typename Property>
  196. struct PropertyPrinter
  197. {
  198. PropertyPrinter( const Graph& g ):graph(&g){}
  199. template<class Val>
  200. PropertyPrinter& operator () ( std::ostream& out, const Val& v )
  201. {
  202. out << (*graph)[ v ] <<" ";
  203. return (*this);
  204. }
  205. private:
  206. const Graph* graph;
  207. };
  208. template<class Graph, typename Tag, typename Value, typename Next>
  209. struct PropertyPrinter<Graph, property<Tag, Value, Next> >
  210. {
  211. PropertyPrinter( const Graph& g ):graph(&g){}
  212. template<class Val>
  213. PropertyPrinter& operator () ( std::ostream& out, const Val& v )
  214. {
  215. typename property_map<Graph,Tag>::const_type ps = get(Tag(), *graph);
  216. out << ps[ v ] <<" ";
  217. PropertyPrinter<Graph,Next> print(*graph);
  218. print(out, v);
  219. return (*this);
  220. }
  221. private:
  222. const Graph* graph;
  223. };
  224. #endif
  225. template<class Graph>
  226. struct PropertyPrinter<Graph, no_property>
  227. {
  228. PropertyPrinter( const Graph& ){}
  229. template<class Val>
  230. PropertyPrinter& operator () ( std::ostream&, const Val& ){ return *this; }
  231. };
  232. // property printer
  233. //=========================================================================
  234. // graph printer
  235. template<class Graph_t, class EdgeProperty>
  236. struct EdgePrinter
  237. {
  238. typedef Graph_t Graph;
  239. typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  240. EdgePrinter( const Graph& g )
  241. : graph(g)
  242. {}
  243. const EdgePrinter& operator () ( std::ostream& out ) const
  244. {
  245. // assign indices to vertices
  246. std::map<Vertex,int> indices;
  247. int num = 0;
  248. BGL_FORALL_VERTICES_T(v, graph, Graph) {
  249. indices[v] = num++;
  250. }
  251. // write edges
  252. PropertyPrinter<Graph, EdgeProperty> print_Edge(graph);
  253. out << "e" << std::endl;
  254. BGL_FORALL_EDGES_T(e, graph, Graph) {
  255. out << indices[source(e,graph)] << " " << indices[target(e,graph)] << " ";
  256. print_Edge(out,e);
  257. out << std::endl;
  258. }
  259. out << std::endl;
  260. return (*this);
  261. }
  262. protected:
  263. const Graph& graph;
  264. };
  265. template<class Graph, class V, class E>
  266. struct GraphPrinter: public EdgePrinter<Graph,E>
  267. {
  268. GraphPrinter( const Graph& g )
  269. : EdgePrinter<Graph,E>(g)
  270. {}
  271. const GraphPrinter& operator () ( std::ostream& out ) const
  272. {
  273. PropertyPrinter<Graph, V> printNode(this->graph);
  274. out << "v"<<std::endl;
  275. BGL_FORALL_VERTICES_T(v, this->graph, Graph) {
  276. printNode(out,v);
  277. out << std::endl;
  278. }
  279. EdgePrinter<Graph,E>::operator ()( out );
  280. return (*this);
  281. }
  282. };
  283. template<class Graph, class E>
  284. struct GraphPrinter<Graph,no_property,E>
  285. : public EdgePrinter<Graph,E>
  286. {
  287. GraphPrinter( const Graph& g )
  288. : EdgePrinter<Graph,E>(g)
  289. {}
  290. const GraphPrinter& operator () ( std::ostream& out ) const
  291. {
  292. out << "n "<< num_vertices(this->graph) << std::endl;
  293. EdgePrinter<Graph,E>::operator ()( out );
  294. return (*this);
  295. }
  296. };
  297. // graph printer
  298. //=========================================================================
  299. // user methods
  300. /// input stream for reading a graph
  301. template<class Graph, class VP, class EP, class VPS, class EPS>
  302. std::istream& operator >> ( std::istream& in, GraphParser<Graph,VP,EP,VPS,EPS> gp )
  303. {
  304. gp(in);
  305. return in;
  306. }
  307. /// graph parser for given subsets of internal vertex and edge properties
  308. template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
  309. GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>
  310. read( adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS vps, EPS eps )
  311. {
  312. return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>(&g);
  313. }
  314. /// graph parser for all internal vertex and edge properties
  315. template<class EL, class VL, class D, class VP, class EP, class GP>
  316. GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>
  317. read( adjacency_list<EL,VL,D,VP,EP,GP>& g )
  318. {
  319. return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>(&g);
  320. }
  321. /// output stream for writing a graph
  322. template<class Graph, class VP, class EP>
  323. std::ostream& operator << ( std::ostream& out, const GraphPrinter<Graph,VP,EP>& gp )
  324. {
  325. gp(out);
  326. return out;
  327. }
  328. /// write the graph with given property subsets
  329. template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
  330. GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>
  331. write( const adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS, EPS )
  332. {
  333. return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>(g);
  334. }
  335. /// write the graph with all internal vertex and edge properties
  336. template<class EL, class VL, class D, class VP, class EP, class GP>
  337. GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>
  338. write( const adjacency_list<EL,VL,D,VP,EP,GP>& g )
  339. {
  340. return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>(g);
  341. }
  342. // user methods
  343. //=========================================================================
  344. }// boost
  345. #endif