Some bugfixes.
2 * lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
19 ///\brief Lemon Graph Format reader.
21 #ifndef LEMON_GRAPH_READER_H
22 #define LEMON_GRAPH_READER_H
26 #include <lemon/error.h>
27 #include <lemon/lemon_reader.h>
31 /// \addtogroup io_group
34 /// \brief The graph reader class.
36 /// The \c GraphReader class provides the graph input.
37 /// Before you read this documentation it might be useful to read the general
38 /// description of \ref graph-io-page "Graph Input-Output".
40 /// If you don't need very sophisticated
41 /// behaviour then you can use the versions of the public function
42 /// \ref readGraph() to read a graph (or a max flow instance etc).
44 /// The file to be read may contain several maps and labeled nodes or
47 /// If you read a graph you need not read all the maps and items just those
48 /// that you need. The interface of the \c GraphReader is very similar to
49 /// the GraphWriter but the reading method does not depend on the order the
50 /// given commands (i.e. you don't have to insist on the order in which the
51 /// maps are given in the file).
53 /// The reader object assumes that not readed values do not contain
54 /// whitespaces, therefore it has some extra possibilities to control how
55 /// it should skip the values when the string representation contains spaces.
58 /// GraphReader<ListGraph> reader(std::cin, graph);
61 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
62 /// If there is a map that you do not want to read from the file and there is
63 /// whitespace in the string represenation of the values then you should
64 /// call the \c skipNodeMap() template member function with proper
68 /// reader.readNodeMap("coords", coords);
70 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
71 /// reader.skipNodeMap<QuotedStringReader>("description");
73 /// reader.readNodeMap("color", colorMap);
76 /// With the \c readEdgeMap() member function you can give an edge map
77 /// reading command similar to the NodeMaps.
80 /// reader.readEdgeMap("weight", weightMap);
81 /// reader.readEdgeMap("label", labelMap);
84 /// With \c readNode() and \c readEdge() functions you can read
85 /// labeled Nodes and Edges.
88 /// reader.readNode("source", sourceNode);
89 /// reader.readNode("target", targetNode);
91 /// reader.readEdge("observed", edge);
94 /// With the \c readAttribute() functions you can read an attribute
95 /// into a variable. You can specify the reader for the attribute as
98 /// After you give all read commands you must call the \c run() member
99 /// function, which executes all the commands.
105 /// \see DefaultReaderTraits
106 /// \see QuotedStringReader
107 /// \see \ref GraphWriter
108 /// \see \ref graph-io-page
109 /// \author Balazs Dezso
110 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
114 typedef _Graph Graph;
115 typedef typename Graph::Node Node;
116 typedef typename Graph::Edge Edge;
118 typedef _ReaderTraits ReaderTraits;
119 typedef typename ReaderTraits::Skipper DefaultSkipper;
121 /// \brief Construct a new GraphReader.
123 /// Construct a new GraphReader. It reads into the given graph
124 /// and it uses the given reader as the default skipper.
125 GraphReader(std::istream& _is,
126 typename SmartParameter<Graph>::Type _graph,
127 const DefaultSkipper& _skipper = DefaultSkipper())
128 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
129 nodeset_reader(*reader, _graph, std::string(), skipper),
130 edgeset_reader(*reader, _graph, nodeset_reader,
131 std::string(), skipper),
132 node_reader(*reader, nodeset_reader, std::string()),
133 edge_reader(*reader, edgeset_reader, std::string()),
134 attribute_reader(*reader, std::string()) {}
136 /// \brief Construct a new GraphReader.
138 /// Construct a new GraphReader. It reads into the given graph
139 /// and it uses the given reader as the default skipper.
140 GraphReader(const std::string& _filename,
141 typename SmartParameter<Graph>::Type _graph,
142 const DefaultSkipper& _skipper = DefaultSkipper())
143 : reader(new LemonReader(_filename)), own_reader(true),
145 nodeset_reader(*reader, _graph, std::string(), skipper),
146 edgeset_reader(*reader, _graph, nodeset_reader,
147 std::string(), skipper),
148 node_reader(*reader, nodeset_reader, std::string()),
149 edge_reader(*reader, edgeset_reader, std::string()),
150 attribute_reader(*reader, std::string()) {}
152 /// \brief Construct a new GraphReader.
154 /// Construct a new GraphReader. It reads into the given graph
155 /// and it uses the given reader as the default skipper.
156 GraphReader(LemonReader& _reader,
157 typename SmartParameter<Graph>::Type _graph,
158 const DefaultSkipper& _skipper = DefaultSkipper())
159 : reader(_reader), own_reader(false), skipper(_skipper),
160 nodeset_reader(*reader, _graph, std::string(), skipper),
161 edgeset_reader(*reader, _graph, nodeset_reader,
162 std::string(), skipper),
163 node_reader(*reader, nodeset_reader, std::string()),
164 edge_reader(*reader, edgeset_reader, std::string()),
165 attribute_reader(*reader, std::string()) {}
167 /// \brief Destruct the graph reader.
169 /// Destruct the graph reader.
175 /// \brief Give a new node map reading command to the reader.
177 /// Give a new node map reading command to the reader.
178 template <typename Map>
179 GraphReader& readNodeMap(std::string name, Map& map) {
180 nodeset_reader.readNodeMap(name, map);
184 template <typename Map>
185 GraphReader& readNodeMap(std::string name, const Map& map) {
186 nodeset_reader.readNodeMap(name, map);
190 /// \brief Give a new node map reading command to the reader.
192 /// Give a new node map reading command to the reader.
193 template <typename Reader, typename Map>
194 GraphReader& readNodeMap(std::string name, Map& map,
195 const Reader& reader = Reader()) {
196 nodeset_reader.readNodeMap(name, map, reader);
200 template <typename Reader, typename Map>
201 GraphReader& readNodeMap(std::string name, const Map& map,
202 const Reader& reader = Reader()) {
203 nodeset_reader.readNodeMap(name, map, reader);
207 /// \brief Give a new node map skipping command to the reader.
209 /// Give a new node map skipping command to the reader.
210 template <typename Reader>
211 GraphReader& skipNodeMap(std::string name,
212 const Reader& reader = Reader()) {
213 nodeset_reader.skipNodeMap(name, reader);
217 /// \brief Give a new edge map reading command to the reader.
219 /// Give a new edge map reading command to the reader.
220 template <typename Map>
221 GraphReader& readEdgeMap(std::string name, Map& map) {
222 edgeset_reader.readEdgeMap(name, map);
226 template <typename Map>
227 GraphReader& readEdgeMap(std::string name, const Map& map) {
228 edgeset_reader.readEdgeMap(name, map);
233 /// \brief Give a new edge map reading command to the reader.
235 /// Give a new edge map reading command to the reader.
236 template <typename Reader, typename Map>
237 GraphReader& readEdgeMap(std::string name, Map& map,
238 const Reader& reader = Reader()) {
239 edgeset_reader.readEdgeMap(name, map, reader);
243 template <typename Reader, typename Map>
244 GraphReader& readEdgeMap(std::string name, const Map& map,
245 const Reader& reader = Reader()) {
246 edgeset_reader.readEdgeMap(name, map, reader);
250 /// \brief Give a new edge map skipping command to the reader.
252 /// Give a new edge map skipping command to the reader.
253 template <typename Reader>
254 GraphReader& skipEdgeMap(std::string name,
255 const Reader& reader = Reader()) {
256 edgeset_reader.skipEdgeMap(name, reader);
260 /// \brief Give a new labeled node reading command to the reader.
262 /// Give a new labeled node reading command to the reader.
263 GraphReader& readNode(std::string name, Node& node) {
264 node_reader.readNode(name, node);
268 /// \brief Give a new labeled edge reading command to the reader.
270 /// Give a new labeled edge reading command to the reader.
271 GraphReader& readEdge(std::string name, Edge& edge) {
272 edge_reader.readEdge(name, edge);
276 /// \brief Give a new attribute reading command.
278 /// Give a new attribute reading command.
279 template <typename Value>
280 GraphReader& readAttribute(std::string name, Value& value) {
281 attribute_reader.readAttribute(name, value);
285 /// \brief Give a new attribute reading command.
287 /// Give a new attribute reading command.
288 template <typename Reader, typename Value>
289 GraphReader& readAttribute(std::string name, Value& value,
290 const Reader& reader) {
291 attribute_reader.readAttribute<Reader>(name, value, reader);
295 /// \brief Conversion operator to LemonReader.
297 /// Conversion operator to LemonReader. It makes possible to access the
298 /// encapsulated \e LemonReader, this way you can attach to this reader
299 /// new instances of \e LemonReader::SectionReader. For more details see
300 /// the \ref rwbackground "Background of Reading and Writing".
301 operator LemonReader&() {
305 /// \brief Executes the reading commands.
307 /// Executes the reading commands.
312 /// \brief Gives back the node by its id.
314 /// It reads an id from the stream and gives back which node belongs to
315 /// it. It is possible only if there was read an "id" named node map.
316 Node readId(std::istream& is, Node) const {
317 return nodeset_reader.readId(is, Node());
320 /// \brief Gives back the edge by its id.
322 /// It reads an id from the stream and gives back which edge belongs to
323 /// it. It is possible only if there was read an "id" named edge map.
324 Edge readId(std::istream& is, Edge) const {
325 return edgeset_reader.readId(is, Edge());
333 DefaultSkipper skipper;
335 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
336 EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
338 NodeReader<Graph> node_reader;
339 EdgeReader<Graph> edge_reader;
341 AttributeReader<ReaderTraits> attribute_reader;
345 ///\anchor readGraph()
347 /// \brief Read a graph from an input stream.
349 /// Read a graph from an input stream.
350 /// \param is The input stream.
351 /// \param g The graph.
352 template<typename Graph>
353 void readGraph(std::istream& is, Graph &g) {
354 GraphReader<Graph> reader(is, g);
358 /// \brief Read a capacitated graph instance from an input stream.
360 /// Read a capacitated graph (graph+capacity on the
361 /// edges) from an input stream.
362 /// \param is The input stream.
363 /// \param g The graph.
364 /// \param capacity The capacity map.
365 template<typename Graph, typename CapacityMap>
366 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
367 GraphReader<Graph> reader(is, g);
368 reader.readEdgeMap("capacity", capacity);
372 /// \brief Read a shortest path instance from an input stream.
374 /// Read a shortest path instance (graph+capacity on the
375 /// edges+designated source) from an input stream.
376 /// \param is The input stream.
377 /// \param g The graph.
378 /// \param capacity The capacity map.
379 /// \param s The source node.
380 template<typename Graph, typename CapacityMap>
381 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
382 typename Graph::Node &s) {
383 GraphReader<Graph> reader(is, g);
384 reader.readEdgeMap("capacity", capacity);
385 reader.readNode("source", s);
391 /// \brief Read a max flow instance from an input stream.
393 /// Read a max flow instance (graph+capacity on the
394 /// edges+designated source and target) from an input stream.
396 /// \param is The input stream.
397 /// \param g The graph.
398 /// \param capacity The capacity map.
399 /// \param s The source node.
400 /// \param t The target node.
401 template<typename Graph, typename CapacityMap>
402 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
403 typename Graph::Node &s, typename Graph::Node &t) {
404 GraphReader<Graph> reader(is, g);
405 reader.readEdgeMap("capacity", capacity);
406 reader.readNode("source", s);
407 reader.readNode("target", t);
411 /// \brief Read a min cost flow instance from an input stream.
413 /// Read a min cost flow instance (graph+capacity on the edges+cost
414 /// function on the edges+designated source and target) from an input stream.
416 /// \param is The input stream.
417 /// \param g The graph.
418 /// \param capacity The capacity map.
419 /// \param s The source node.
420 /// \param t The target node.
421 /// \param cost The cost map.
422 template<typename Graph, typename CapacityMap, typename CostMap>
423 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
424 typename Graph::Node &s, typename Graph::Node &t,
426 GraphReader<Graph> reader(is, g);
427 reader.readEdgeMap("capacity", capacity);
428 reader.readEdgeMap("cost", cost);
429 reader.readNode("source", s);
430 reader.readNode("target", t);
435 /// \brief The undir graph reader class.
437 /// The \c UndirGraphReader class provides the graph input.
438 /// Before you read this documentation it might be useful to read the general
439 /// description of \ref graph-io-page "Graph Input-Output".
441 /// If you don't need very sophisticated
442 /// behaviour then you can use the versions of the public function
443 /// \ref readGraph() to read a graph (or a max flow instance etc).
445 /// The given file format may contain several maps and labeled nodes or
448 /// If you read a graph you need not read all the maps and items just those
449 /// that you need. The interface of the \c UndirGraphReader is very similar
450 /// to the UndirGraphWriter but the reading method does not depend on the
451 /// order of the given commands.
453 /// The reader object suppose that each not readed value does not contain
454 /// whitespaces, therefore it has some extra possibilities to control how
455 /// it should skip the values when the string representation contains spaces.
458 /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
461 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
462 /// If there is a map that you do not want to read from the file and there is
463 /// whitespace in the string represenation of the values then you should
464 /// call the \c skipNodeMap() template member function with proper
468 /// reader.readNodeMap("coords", coords);
470 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
471 /// reader.skipNodeMap<QuotedStringReader>("description");
473 /// reader.readNodeMap("color", colorMap);
476 /// With the \c readUndirEdgeMap() member function you can give an
477 /// undir edge map reading command similar to the NodeMaps.
480 /// reader.readUndirEdgeMap("capacity", capacityMap);
483 /// The reading of the directed edge maps is just a syntactical sugar.
484 /// It reads two undirected edgemaps into a directed edge map. The
485 /// undirected edge maps' name should be start with the \c '+' and the
486 /// \c '-' character and the same.
489 /// reader.readEdgeMap("flow", flowMap);
492 /// With \c readNode() and \c readUndirEdge() functions you can read
493 /// labeled Nodes and UndirEdges.
496 /// reader.readNode("source", sourceNode);
497 /// reader.readNode("target", targetNode);
499 /// reader.readUndirEdge("observed", undirEdge);
502 /// With the \c readAttribute() functions you can read an attribute
503 /// in a variable. You can specify the reader for the attribute as
506 /// After you give all read commands you must call the \c run() member
507 /// function, which execute all the commands.
514 /// \see DefaultReaderTraits
515 /// \see \ref UndirGraphWriter
516 /// \see \ref graph-io-page
518 /// \author Balazs Dezso
519 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
520 class UndirGraphReader {
523 typedef _Graph Graph;
524 typedef typename Graph::Node Node;
525 typedef typename Graph::Edge Edge;
526 typedef typename Graph::UndirEdge UndirEdge;
528 typedef _ReaderTraits ReaderTraits;
529 typedef typename ReaderTraits::Skipper DefaultSkipper;
531 /// \brief Construct a new UndirGraphReader.
533 /// Construct a new UndirGraphReader. It reads into the given graph
534 /// and it use the given reader as the default skipper.
535 UndirGraphReader(std::istream& _is, Graph& _graph,
536 const DefaultSkipper& _skipper = DefaultSkipper())
537 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
538 nodeset_reader(*reader, _graph, std::string(), skipper),
539 undir_edgeset_reader(*reader, _graph, nodeset_reader,
540 std::string(), skipper),
541 node_reader(*reader, nodeset_reader, std::string()),
542 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
543 attribute_reader(*reader, std::string()) {}
545 /// \brief Construct a new UndirGraphReader.
547 /// Construct a new UndirGraphReader. It reads into the given graph
548 /// and it use the given reader as the default skipper.
549 UndirGraphReader(const std::string& _filename, Graph& _graph,
550 const DefaultSkipper& _skipper = DefaultSkipper())
551 : reader(new LemonReader(_filename)), own_reader(true),
553 nodeset_reader(*reader, _graph, std::string(), skipper),
554 undir_edgeset_reader(*reader, _graph, nodeset_reader,
555 std::string(), skipper),
556 node_reader(*reader, nodeset_reader, std::string()),
557 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
558 attribute_reader(*reader, std::string()) {}
560 /// \brief Construct a new UndirGraphReader.
562 /// Construct a new UndirGraphReader. It reads into the given graph
563 /// and it use the given reader as the default skipper.
564 UndirGraphReader(LemonReader& _reader, Graph& _graph,
565 const DefaultSkipper& _skipper = DefaultSkipper())
566 : reader(_reader), own_reader(false), skipper(_skipper),
567 nodeset_reader(*reader, _graph, std::string(), skipper),
568 undir_edgeset_reader(*reader, _graph, nodeset_reader,
569 std::string(), skipper),
570 node_reader(*reader, nodeset_reader, std::string()),
571 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
572 attribute_reader(*reader, std::string()) {}
574 /// \brief Destruct the graph reader.
576 /// Destruct the graph reader.
577 ~UndirGraphReader() {
582 /// \brief Give a new node map reading command to the reader.
584 /// Give a new node map reading command to the reader.
585 template <typename Map>
586 UndirGraphReader& readNodeMap(std::string name, Map& map) {
587 nodeset_reader.readNodeMap(name, map);
591 template <typename Map>
592 UndirGraphReader& readNodeMap(std::string name, const Map& map) {
593 nodeset_reader.readNodeMap(name, map);
597 /// \brief Give a new node map reading command to the reader.
599 /// Give a new node map reading command to the reader.
600 template <typename Reader, typename Map>
601 UndirGraphReader& readNodeMap(std::string name, Map& map,
602 const Reader& reader = Reader()) {
603 nodeset_reader.readNodeMap(name, map, reader);
607 template <typename Reader, typename Map>
608 UndirGraphReader& readNodeMap(std::string name, const Map& map,
609 const Reader& reader = Reader()) {
610 nodeset_reader.readNodeMap(name, map, reader);
614 /// \brief Give a new node map skipping command to the reader.
616 /// Give a new node map skipping command to the reader.
617 template <typename Reader>
618 UndirGraphReader& skipNodeMap(std::string name,
619 const Reader& reader = Reader()) {
620 nodeset_reader.skipNodeMap(name, reader);
624 /// \brief Give a new undirected edge map reading command to the reader.
626 /// Give a new undirected edge map reading command to the reader.
627 template <typename Map>
628 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
629 undir_edgeset_reader.readUndirEdgeMap(name, map);
633 template <typename Map>
634 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
635 undir_edgeset_reader.readUndirEdgeMap(name, map);
640 /// \brief Give a new undirected edge map reading command to the reader.
642 /// Give a new undirected edge map reading command to the reader.
643 template <typename Reader, typename Map>
644 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
645 const Reader& reader = Reader()) {
646 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
650 template <typename Reader, typename Map>
651 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
652 const Reader& reader = Reader()) {
653 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
657 /// \brief Give a new undirected edge map skipping command to the reader.
659 /// Give a new undirected edge map skipping command to the reader.
660 template <typename Reader>
661 UndirGraphReader& skipUndirEdgeMap(std::string name,
662 const Reader& reader = Reader()) {
663 undir_edgeset_reader.skipUndirMap(name, reader);
668 /// \brief Give a new edge map reading command to the reader.
670 /// Give a new edge map reading command to the reader.
671 template <typename Map>
672 UndirGraphReader& readEdgeMap(std::string name, Map& map) {
673 undir_edgeset_reader.readEdgeMap(name, map);
677 template <typename Map>
678 UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
679 undir_edgeset_reader.readEdgeMap(name, map);
684 /// \brief Give a new edge map reading command to the reader.
686 /// Give a new edge map reading command to the reader.
687 template <typename Reader, typename Map>
688 UndirGraphReader& readEdgeMap(std::string name, Map& map,
689 const Reader& reader = Reader()) {
690 undir_edgeset_reader.readEdgeMap(name, map, reader);
694 template <typename Reader, typename Map>
695 UndirGraphReader& readEdgeMap(std::string name, const Map& map,
696 const Reader& reader = Reader()) {
697 undir_edgeset_reader.readEdgeMap(name, map, reader);
701 /// \brief Give a new edge map skipping command to the reader.
703 /// Give a new edge map skipping command to the reader.
704 template <typename Reader>
705 UndirGraphReader& skipEdgeMap(std::string name,
706 const Reader& reader = Reader()) {
707 undir_edgeset_reader.skipEdgeMap(name, reader);
711 /// \brief Give a new labeled node reading command to the reader.
713 /// Give a new labeled node reading command to the reader.
714 UndirGraphReader& readNode(std::string name, Node& node) {
715 node_reader.readNode(name, node);
719 /// \brief Give a new labeled edge reading command to the reader.
721 /// Give a new labeled edge reading command to the reader.
722 UndirGraphReader& readEdge(std::string name, Edge& edge) {
723 undir_edge_reader.readEdge(name, edge);
726 /// \brief Give a new labeled undirected edge reading command to the
729 /// Give a new labeled undirected edge reading command to the reader.
730 UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
731 undir_edge_reader.readUndirEdge(name, edge);
734 /// \brief Give a new attribute reading command.
736 /// Give a new attribute reading command.
737 template <typename Value>
738 UndirGraphReader& readAttribute(std::string name, Value& value) {
739 attribute_reader.readAttribute(name, value);
743 /// \brief Give a new attribute reading command.
745 /// Give a new attribute reading command.
746 template <typename Reader, typename Value>
747 UndirGraphReader& readAttribute(std::string name, Value& value,
748 const Reader& reader) {
749 attribute_reader.readAttribute<Reader>(name, value, reader);
753 /// \brief Conversion operator to LemonReader.
755 /// Conversion operator to LemonReader. It make possible
756 /// to access the encapsulated \e LemonReader, this way
757 /// you can attach to this reader new instances of
758 /// \e LemonReader::SectionReader.
759 operator LemonReader&() {
763 /// \brief Executes the reading commands.
765 /// Executes the reading commands.
770 /// \brief Gives back the node by its id.
772 /// It reads an id from the stream and gives back which node belongs to
773 /// it. It is possible only if there was read an "id" named node map.
774 Node readId(std::istream& is, Node) const {
775 return nodeset_reader.readId(is, Node());
778 /// \brief Gives back the edge by its id.
780 /// It reads an id from the stream and gives back which edge belongs to
781 /// it. It is possible only if there was read an "id" named edge map.
782 Edge readId(std::istream& is, Edge) const {
783 return undir_edgeset_reader.readId(is, Edge());
786 /// \brief Gives back the undirected edge by its id.
788 /// It reads an id from the stream and gives back which undirected edge
789 /// belongs to it. It is possible only if there was read an "id" named
791 UndirEdge readId(std::istream& is, UndirEdge) const {
792 return undir_edgeset_reader.readId(is, UndirEdge());
801 DefaultSkipper skipper;
803 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
804 UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
806 NodeReader<Graph> node_reader;
807 UndirEdgeReader<Graph> undir_edge_reader;
809 AttributeReader<ReaderTraits> attribute_reader;
812 /// \brief Read an undirected graph from an input stream.
814 /// Read an undirected graph from an input stream.
815 /// \param is The input stream.
816 /// \param g The graph.
817 template<typename Graph>
818 void readUndirGraph(std::istream& is, Graph &g) {
819 UndirGraphReader<Graph> reader(is, g);
823 /// \brief Read an undirected multigraph (undirected graph + capacity
824 /// map on the edges) from an input stream.
826 /// Read an undirected multigraph (undirected graph + capacity
827 /// map on the edges) from an input stream.
828 /// \param is The input stream.
829 /// \param g The graph.
830 /// \param capacity The capacity map.
831 template<typename Graph, typename CapacityMap>
832 void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
833 UndirGraphReader<Graph> reader(is, g);
834 reader.readUndirEdgeMap("capacity", capacity);