adjacency_list_io.hpp 12 KB

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