... and fix another one.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
21 ///\brief Lemon Graph Format reader.
23 #ifndef LEMON_GRAPH_READER_H
24 #define LEMON_GRAPH_READER_H
28 #include <lemon/error.h>
29 #include <lemon/lemon_reader.h>
33 /// \addtogroup lemon_io
36 /// \brief The graph reader class.
38 /// The \c GraphReader class provides the graph input.
39 /// Before you read this documentation it might be useful to read the general
40 /// description of \ref graph-io-page "Graph Input-Output".
42 /// The file to be read may contain several maps and labeled nodes or
45 /// If you read a graph you need not read all the maps and items just those
46 /// that you need. The interface of the \c GraphReader is very similar to
47 /// the GraphWriter but the reading method does not depend on the order the
48 /// given commands (i.e. you don't have to insist on the order in which the
49 /// maps are given in the file).
51 /// The reader object assumes that not read values do not contain
52 /// whitespaces, therefore it has some extra possibilities to control how
53 /// it should skip the values when the string representation contains spaces.
56 /// GraphReader<ListGraph> reader(std::cin, graph);
59 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
60 /// If there is a map that you do not want to read from the file and there is
61 /// whitespace in the string represenation of the values then you should
62 /// call the \c skipNodeMap() template member function with proper
66 /// reader.readNodeMap("coords", coords);
68 /// reader.skipNodeMap("description", desc);
70 /// reader.readNodeMap("color", colorMap);
73 /// With the \c readEdgeMap() member function you can give an edge map
74 /// reading command similar to the NodeMaps.
77 /// reader.readEdgeMap("weight", weightMap);
78 /// reader.readEdgeMap("label", labelMap);
81 /// With \c readNode() and \c readEdge() functions you can read
82 /// labeled Nodes and Edges.
85 /// reader.readNode("source", sourceNode);
86 /// reader.readNode("target", targetNode);
88 /// reader.readEdge("observed", edge);
91 /// With the \c readAttribute() functions you can read an attribute
92 /// into a variable. You can specify the reader for the attribute as
95 /// After you give all read commands you must call the \c run() member
96 /// function, which executes all the commands.
102 /// \see DefaultReaderTraits
103 /// \see QuotedStringReader
104 /// \see \ref GraphWriter
105 /// \see \ref graph-io-page
106 /// \author Balazs Dezso
107 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
111 typedef _Graph Graph;
112 typedef typename Graph::Node Node;
113 typedef typename Graph::Edge Edge;
115 typedef _ReaderTraits ReaderTraits;
116 typedef typename ReaderTraits::Skipper DefaultSkipper;
118 /// \brief Construct a new GraphReader.
120 /// Construct a new GraphReader. It reads into the given graph
121 /// and it uses the given reader as the default skipper.
122 GraphReader(std::istream& _is, Graph& _graph,
123 const DefaultSkipper& _skipper = DefaultSkipper())
124 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
125 nodeset_reader(*reader, _graph, std::string(), skipper),
126 edgeset_reader(*reader, _graph, nodeset_reader,
127 std::string(), skipper),
128 node_reader(*reader, nodeset_reader, std::string()),
129 edge_reader(*reader, edgeset_reader, std::string()),
130 attribute_reader(*reader, std::string()) {}
132 /// \brief Construct a new GraphReader.
134 /// Construct a new GraphReader. It reads into the given graph
135 /// and it uses the given reader as the default skipper.
136 GraphReader(const std::string& _filename, Graph& _graph,
137 const DefaultSkipper& _skipper = DefaultSkipper())
138 : reader(new LemonReader(_filename)), own_reader(true),
140 nodeset_reader(*reader, _graph, std::string(), skipper),
141 edgeset_reader(*reader, _graph, nodeset_reader,
142 std::string(), skipper),
143 node_reader(*reader, nodeset_reader, std::string()),
144 edge_reader(*reader, edgeset_reader, std::string()),
145 attribute_reader(*reader, std::string()) {}
147 /// \brief Construct a new GraphReader.
149 /// Construct a new GraphReader. It reads into the given graph
150 /// and it uses the given reader as the default skipper.
151 GraphReader(LemonReader& _reader, Graph& _graph,
152 const DefaultSkipper& _skipper = DefaultSkipper())
153 : reader(_reader), own_reader(false), skipper(_skipper),
154 nodeset_reader(*reader, _graph, std::string(), skipper),
155 edgeset_reader(*reader, _graph, nodeset_reader,
156 std::string(), skipper),
157 node_reader(*reader, nodeset_reader, std::string()),
158 edge_reader(*reader, edgeset_reader, std::string()),
159 attribute_reader(*reader, std::string()) {}
161 /// \brief Destruct the graph reader.
163 /// Destruct the graph reader.
169 /// \brief Give a new node map reading command to the reader.
171 /// Give a new node map reading command to the reader.
172 template <typename Map>
173 GraphReader& readNodeMap(std::string name, Map& map) {
174 nodeset_reader.readNodeMap(name, map);
178 template <typename Map>
179 GraphReader& readNodeMap(std::string name, const Map& map) {
180 nodeset_reader.readNodeMap(name, map);
184 /// \brief Give a new node map reading command to the reader.
186 /// Give a new node map reading command to the reader.
187 template <typename Reader, typename Map>
188 GraphReader& readNodeMap(std::string name, Map& map,
189 const Reader& reader = Reader()) {
190 nodeset_reader.readNodeMap(name, map, reader);
194 template <typename Reader, typename Map>
195 GraphReader& readNodeMap(std::string name, const Map& map,
196 const Reader& reader = Reader()) {
197 nodeset_reader.readNodeMap(name, map, reader);
201 /// \brief Give a new node map skipping command to the reader.
203 /// Give a new node map skipping command to the reader.
204 template <typename Reader>
205 GraphReader& skipNodeMap(std::string name,
206 const Reader& reader = Reader()) {
207 nodeset_reader.skipNodeMap(name, reader);
211 /// \brief Give a new edge map reading command to the reader.
213 /// Give a new edge map reading command to the reader.
214 template <typename Map>
215 GraphReader& readEdgeMap(std::string name, Map& map) {
216 edgeset_reader.readEdgeMap(name, map);
220 template <typename Map>
221 GraphReader& readEdgeMap(std::string name, const Map& map) {
222 edgeset_reader.readEdgeMap(name, map);
227 /// \brief Give a new edge map reading command to the reader.
229 /// Give a new edge map reading command to the reader.
230 template <typename Reader, typename Map>
231 GraphReader& readEdgeMap(std::string name, Map& map,
232 const Reader& reader = Reader()) {
233 edgeset_reader.readEdgeMap(name, map, reader);
237 template <typename Reader, typename Map>
238 GraphReader& readEdgeMap(std::string name, const Map& map,
239 const Reader& reader = Reader()) {
240 edgeset_reader.readEdgeMap(name, map, reader);
244 /// \brief Give a new edge map skipping command to the reader.
246 /// Give a new edge map skipping command to the reader.
247 template <typename Reader>
248 GraphReader& skipEdgeMap(std::string name,
249 const Reader& reader = Reader()) {
250 edgeset_reader.skipEdgeMap(name, reader);
254 /// \brief Give a new labeled node reading command to the reader.
256 /// Give a new labeled node reading command to the reader.
257 GraphReader& readNode(std::string name, Node& node) {
258 node_reader.readNode(name, node);
262 /// \brief Give a new labeled edge reading command to the reader.
264 /// Give a new labeled edge reading command to the reader.
265 GraphReader& readEdge(std::string name, Edge& edge) {
266 edge_reader.readEdge(name, edge);
270 /// \brief Give a new attribute reading command.
272 /// Give a new attribute reading command.
273 template <typename Value>
274 GraphReader& readAttribute(std::string name, Value& value) {
275 attribute_reader.readAttribute(name, value);
279 /// \brief Give a new attribute reading command.
281 /// Give a new attribute reading command.
282 template <typename Reader, typename Value>
283 GraphReader& readAttribute(std::string name, Value& value,
284 const Reader& reader) {
285 attribute_reader.readAttribute<Reader>(name, value, reader);
289 /// \brief Conversion operator to LemonReader.
291 /// Conversion operator to LemonReader. It makes possible to access the
292 /// encapsulated \e LemonReader, this way you can attach to this reader
293 /// new instances of \e LemonReader::SectionReader. For more details see
294 /// the \ref rwbackground "Background of Reading and Writing".
295 operator LemonReader&() {
299 /// \brief Executes the reading commands.
301 /// Executes the reading commands.
307 /// \brief Returns true if the reader can give back the items by its label.
309 /// \brief Returns true if the reader can give back the items by its label.
310 bool isLabelReader() const {
311 return nodeset_reader.isLabelReader() && edgeset_reader.isLabelReader();
314 /// \brief Gives back the node by its label.
316 /// It reads an label from the stream and gives back which node belongs to
317 /// it. It is possible only if there was read a "label" named node map.
318 void readLabel(std::istream& is, Node& node) const {
319 nodeset_reader.readLabel(is, node);
322 /// \brief Gives back the edge by its label.
324 /// It reads an label from the stream and gives back which edge belongs to
325 /// it. It is possible only if there was read a "label" named edge map.
326 void readLabel(std::istream& is, Edge& edge) const {
327 return edgeset_reader.readLabel(is, edge);
335 DefaultSkipper skipper;
337 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
338 EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
340 NodeReader<Graph> node_reader;
341 EdgeReader<Graph> edge_reader;
343 AttributeReader<ReaderTraits> attribute_reader;
347 /// \brief Read a graph from the input.
349 /// It is a helper function to read a graph from the given input
350 /// stream. It gives back an GraphReader object and this object
351 /// can read more maps, labeled nodes, edges and attributes.
353 /// \warning Do not forget to call the \c run() function.
355 /// \param is The input stream.
356 /// \param g The graph.
357 template<typename Graph>
358 GraphReader<Graph> graphReader(std::istream& is, Graph &g) {
359 return GraphReader<Graph>(is, g);
362 /// \brief Read a graph from the input.
364 /// It is a helper function to read a graph from the given input
365 /// file. It gives back an GraphReader object and this object
366 /// can read more maps, labeled nodes, edges and attributes.
368 /// \warning Do not forget to call the \c run() function.
370 /// \param fn The input filename.
371 /// \param g The graph.
372 template<typename Graph>
373 GraphReader<Graph> graphReader(const std::string& fn, Graph &g) {
374 return GraphReader<Graph>(fn, g);
377 /// \brief The undirected graph reader class.
379 /// The \c UGraphReader class provides the graph input.
380 /// Before you read this documentation it might be useful to read the general
381 /// description of \ref graph-io-page "Graph Input-Output".
383 /// The given file format may contain several maps and labeled nodes or
386 /// If you read a graph you need not read all the maps and items just those
387 /// that you need. The interface of the \c UGraphReader is very similar
388 /// to the UGraphWriter but the reading method does not depend on the
389 /// order of the given commands.
391 /// The reader object suppose that each not read value does not contain
392 /// whitespaces, therefore it has some extra possibilities to control how
393 /// it should skip the values when the string representation contains spaces.
396 /// UGraphReader<ListUGraph> reader(std::cin, graph);
399 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
400 /// If there is a map that you do not want to read from the file and there is
401 /// whitespace in the string represenation of the values then you should
402 /// call the \c skipNodeMap() template member function with proper
406 /// reader.readNodeMap("coords", coords);
408 /// reader.skipNodeMap("description", desc);
410 /// reader.readNodeMap("color", colorMap);
413 /// With the \c readUEdgeMap() member function you can give an
414 /// uedge map reading command similar to the NodeMaps.
417 /// reader.readUEdgeMap("capacity", capacityMap);
420 /// The reading of the directed edge maps is just a syntactical sugar.
421 /// It reads two undirected edgemaps into a directed edge map. The
422 /// undirected edge maps' name should be start with the \c '+' and the
423 /// \c '-' character and the same.
426 /// reader.readEdgeMap("flow", flowMap);
429 /// With \c readNode() and \c readUEdge() functions you can read
430 /// labeled Nodes and UEdges.
433 /// reader.readNode("source", sourceNode);
434 /// reader.readNode("target", targetNode);
436 /// reader.readUEdge("observed", uEdge);
439 /// With the \c readAttribute() functions you can read an attribute
440 /// in a variable. You can specify the reader for the attribute as
443 /// After you give all read commands you must call the \c run() member
444 /// function, which execute all the commands.
451 /// \see DefaultReaderTraits
452 /// \see \ref UGraphWriter
453 /// \see \ref graph-io-page
455 /// \author Balazs Dezso
456 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
460 typedef _Graph Graph;
461 typedef typename Graph::Node Node;
462 typedef typename Graph::Edge Edge;
463 typedef typename Graph::UEdge UEdge;
465 typedef _ReaderTraits ReaderTraits;
466 typedef typename ReaderTraits::Skipper DefaultSkipper;
468 /// \brief Construct a new UGraphReader.
470 /// Construct a new UGraphReader. It reads into the given graph
471 /// and it use the given reader as the default skipper.
472 UGraphReader(std::istream& _is, Graph& _graph,
473 const DefaultSkipper& _skipper = DefaultSkipper())
474 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
475 nodeset_reader(*reader, _graph, std::string(), skipper),
476 u_edgeset_reader(*reader, _graph, nodeset_reader,
477 std::string(), skipper),
478 node_reader(*reader, nodeset_reader, std::string()),
479 u_edge_reader(*reader, u_edgeset_reader, std::string()),
480 attribute_reader(*reader, std::string()) {}
482 /// \brief Construct a new UGraphReader.
484 /// Construct a new UGraphReader. It reads into the given graph
485 /// and it use the given reader as the default skipper.
486 UGraphReader(const std::string& _filename, Graph& _graph,
487 const DefaultSkipper& _skipper = DefaultSkipper())
488 : reader(new LemonReader(_filename)), own_reader(true),
490 nodeset_reader(*reader, _graph, std::string(), skipper),
491 u_edgeset_reader(*reader, _graph, nodeset_reader,
492 std::string(), skipper),
493 node_reader(*reader, nodeset_reader, std::string()),
494 u_edge_reader(*reader, u_edgeset_reader, std::string()),
495 attribute_reader(*reader, std::string()) {}
497 /// \brief Construct a new UGraphReader.
499 /// Construct a new UGraphReader. It reads into the given graph
500 /// and it use the given reader as the default skipper.
501 UGraphReader(LemonReader& _reader, Graph& _graph,
502 const DefaultSkipper& _skipper = DefaultSkipper())
503 : reader(_reader), own_reader(false), skipper(_skipper),
504 nodeset_reader(*reader, _graph, std::string(), skipper),
505 u_edgeset_reader(*reader, _graph, nodeset_reader,
506 std::string(), skipper),
507 node_reader(*reader, nodeset_reader, std::string()),
508 u_edge_reader(*reader, u_edgeset_reader, std::string()),
509 attribute_reader(*reader, std::string()) {}
511 /// \brief Destruct the graph reader.
513 /// Destruct the graph reader.
519 /// \brief Give a new node map reading command to the reader.
521 /// Give a new node map reading command to the reader.
522 template <typename Map>
523 UGraphReader& readNodeMap(std::string name, Map& map) {
524 nodeset_reader.readNodeMap(name, map);
528 template <typename Map>
529 UGraphReader& readNodeMap(std::string name, const Map& map) {
530 nodeset_reader.readNodeMap(name, map);
534 /// \brief Give a new node map reading command to the reader.
536 /// Give a new node map reading command to the reader.
537 template <typename Reader, typename Map>
538 UGraphReader& readNodeMap(std::string name, Map& map,
539 const Reader& reader = Reader()) {
540 nodeset_reader.readNodeMap(name, map, reader);
544 template <typename Reader, typename Map>
545 UGraphReader& readNodeMap(std::string name, const Map& map,
546 const Reader& reader = Reader()) {
547 nodeset_reader.readNodeMap(name, map, reader);
551 /// \brief Give a new node map skipping command to the reader.
553 /// Give a new node map skipping command to the reader.
554 template <typename Reader>
555 UGraphReader& skipNodeMap(std::string name,
556 const Reader& reader = Reader()) {
557 nodeset_reader.skipNodeMap(name, reader);
561 /// \brief Give a new undirected edge map reading command to the reader.
563 /// Give a new undirected edge map reading command to the reader.
564 template <typename Map>
565 UGraphReader& readUEdgeMap(std::string name, Map& map) {
566 u_edgeset_reader.readUEdgeMap(name, map);
570 template <typename Map>
571 UGraphReader& readUEdgeMap(std::string name, const Map& map) {
572 u_edgeset_reader.readUEdgeMap(name, map);
577 /// \brief Give a new undirected edge map reading command to the reader.
579 /// Give a new undirected edge map reading command to the reader.
580 template <typename Reader, typename Map>
581 UGraphReader& readUEdgeMap(std::string name, Map& map,
582 const Reader& reader = Reader()) {
583 u_edgeset_reader.readUEdgeMap(name, map, reader);
587 template <typename Reader, typename Map>
588 UGraphReader& readUEdgeMap(std::string name, const Map& map,
589 const Reader& reader = Reader()) {
590 u_edgeset_reader.readUEdgeMap(name, map, reader);
594 /// \brief Give a new undirected edge map skipping command to the reader.
596 /// Give a new undirected edge map skipping command to the reader.
597 template <typename Reader>
598 UGraphReader& skipUEdgeMap(std::string name,
599 const Reader& reader = Reader()) {
600 u_edgeset_reader.skipUMap(name, reader);
605 /// \brief Give a new edge map reading command to the reader.
607 /// Give a new edge map reading command to the reader.
608 template <typename Map>
609 UGraphReader& readEdgeMap(std::string name, Map& map) {
610 u_edgeset_reader.readEdgeMap(name, map);
614 template <typename Map>
615 UGraphReader& readEdgeMap(std::string name, const Map& map) {
616 u_edgeset_reader.readEdgeMap(name, map);
621 /// \brief Give a new edge map reading command to the reader.
623 /// Give a new edge map reading command to the reader.
624 template <typename Reader, typename Map>
625 UGraphReader& readEdgeMap(std::string name, Map& map,
626 const Reader& reader = Reader()) {
627 u_edgeset_reader.readEdgeMap(name, map, reader);
631 template <typename Reader, typename Map>
632 UGraphReader& readEdgeMap(std::string name, const Map& map,
633 const Reader& reader = Reader()) {
634 u_edgeset_reader.readEdgeMap(name, map, reader);
638 /// \brief Give a new edge map skipping command to the reader.
640 /// Give a new edge map skipping command to the reader.
641 template <typename Reader>
642 UGraphReader& skipEdgeMap(std::string name,
643 const Reader& reader = Reader()) {
644 u_edgeset_reader.skipEdgeMap(name, reader);
648 /// \brief Give a new labeled node reading command to the reader.
650 /// Give a new labeled node reading command to the reader.
651 UGraphReader& readNode(std::string name, Node& node) {
652 node_reader.readNode(name, node);
656 /// \brief Give a new labeled edge reading command to the reader.
658 /// Give a new labeled edge reading command to the reader.
659 UGraphReader& readEdge(std::string name, Edge& edge) {
660 u_edge_reader.readEdge(name, edge);
663 /// \brief Give a new labeled undirected edge reading command to the
666 /// Give a new labeled undirected edge reading command to the reader.
667 UGraphReader& readUEdge(std::string name, UEdge& edge) {
668 u_edge_reader.readUEdge(name, edge);
671 /// \brief Give a new attribute reading command.
673 /// Give a new attribute reading command.
674 template <typename Value>
675 UGraphReader& readAttribute(std::string name, Value& value) {
676 attribute_reader.readAttribute(name, value);
680 /// \brief Give a new attribute reading command.
682 /// Give a new attribute reading command.
683 template <typename Reader, typename Value>
684 UGraphReader& readAttribute(std::string name, Value& value,
685 const Reader& reader) {
686 attribute_reader.readAttribute<Reader>(name, value, reader);
690 /// \brief Conversion operator to LemonReader.
692 /// Conversion operator to LemonReader. It make possible
693 /// to access the encapsulated \e LemonReader, this way
694 /// you can attach to this reader new instances of
695 /// \e LemonReader::SectionReader.
696 operator LemonReader&() {
700 /// \brief Executes the reading commands.
702 /// Executes the reading commands.
708 /// \brief Returns true if the reader can give back the items by its label.
710 /// \brief Returns true if the reader can give back the items by its label.
711 bool isLabelReader() const {
712 return nodeset_reader.isLabelReader() &&
713 u_edgeset_reader.isLabelReader();
716 /// \brief Gives back the node by its label.
718 /// It reads an label from the stream and gives back which node belongs to
719 /// it. It is possible only if there was read a "label" named node map.
720 void readLabel(std::istream& is, Node& node) const {
721 return nodeset_reader.readLabel(is, node);
724 /// \brief Gives back the edge by its label
726 /// It reads an label from the stream and gives back which edge belongs to
727 /// it. It is possible only if there was read a "label" named edge map.
728 void readLabel(std::istream& is, Edge& edge) const {
729 return u_edgeset_reader.readLabel(is, edge);
732 /// \brief Gives back the undirected edge by its label.
734 /// It reads an label from the stream and gives back which undirected edge
735 /// belongs to it. It is possible only if there was read a "label" named
737 void readLabel(std::istream& is, UEdge& uedge) const {
738 return u_edgeset_reader.readLabel(is, uedge);
747 DefaultSkipper skipper;
749 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
750 UEdgeSetReader<Graph, ReaderTraits> u_edgeset_reader;
752 NodeReader<Graph> node_reader;
753 UEdgeReader<Graph> u_edge_reader;
755 AttributeReader<ReaderTraits> attribute_reader;
758 /// \brief Read an undirected graph from the input.
760 /// It is a helper function to read an undirected graph from the given input
761 /// stream. It gives back an UGraphReader object and this object
762 /// can read more maps, labeled nodes, edges, undirected edges and
765 /// \warning Do not forget to call the \c run() function.
767 /// \param is The input stream.
768 /// \param g The graph.
769 template<typename Graph>
770 UGraphReader<Graph> uGraphReader(std::istream& is, Graph &g) {
771 return GraphReader<Graph>(is, g);
774 /// \brief Read an undirected graph from the input.
776 /// It is a helper function to read an undirected graph from the given input
777 /// file. It gives back an UGraphReader object and this object
778 /// can read more maps, labeled nodes, edges, undirected edges and
781 /// \warning Do not forget to call the \c run() function.
783 /// \param fn The input filename.
784 /// \param g The graph.
785 template<typename Graph>
786 UGraphReader<Graph> uGraphReader(const std::string& fn, Graph &g) {
787 return GraphReader<Graph>(fn, g);