Do not append -Wall -W to CXXFLAGS when it is set on the commandline.
2 * lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2006 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.skipNodeMap("description", desc);
72 /// reader.readNodeMap("color", colorMap);
75 /// With the \c readEdgeMap() member function you can give an edge map
76 /// reading command similar to the NodeMaps.
79 /// reader.readEdgeMap("weight", weightMap);
80 /// reader.readEdgeMap("label", labelMap);
83 /// With \c readNode() and \c readEdge() functions you can read
84 /// labeled Nodes and Edges.
87 /// reader.readNode("source", sourceNode);
88 /// reader.readNode("target", targetNode);
90 /// reader.readEdge("observed", edge);
93 /// With the \c readAttribute() functions you can read an attribute
94 /// into a variable. You can specify the reader for the attribute as
97 /// After you give all read commands you must call the \c run() member
98 /// function, which executes all the commands.
104 /// \see DefaultReaderTraits
105 /// \see QuotedStringReader
106 /// \see \ref GraphWriter
107 /// \see \ref graph-io-page
108 /// \author Balazs Dezso
109 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
113 typedef _Graph Graph;
114 typedef typename Graph::Node Node;
115 typedef typename Graph::Edge Edge;
117 typedef _ReaderTraits ReaderTraits;
118 typedef typename ReaderTraits::Skipper DefaultSkipper;
120 /// \brief Construct a new GraphReader.
122 /// Construct a new GraphReader. It reads into the given graph
123 /// and it uses the given reader as the default skipper.
124 GraphReader(std::istream& _is, Graph& _graph,
125 const DefaultSkipper& _skipper = DefaultSkipper())
126 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
127 nodeset_reader(*reader, _graph, std::string(), skipper),
128 edgeset_reader(*reader, _graph, nodeset_reader,
129 std::string(), skipper),
130 node_reader(*reader, nodeset_reader, std::string()),
131 edge_reader(*reader, edgeset_reader, std::string()),
132 attribute_reader(*reader, std::string()) {}
134 /// \brief Construct a new GraphReader.
136 /// Construct a new GraphReader. It reads into the given graph
137 /// and it uses the given reader as the default skipper.
138 GraphReader(const std::string& _filename, Graph& _graph,
139 const DefaultSkipper& _skipper = DefaultSkipper())
140 : reader(new LemonReader(_filename)), own_reader(true),
142 nodeset_reader(*reader, _graph, std::string(), skipper),
143 edgeset_reader(*reader, _graph, nodeset_reader,
144 std::string(), skipper),
145 node_reader(*reader, nodeset_reader, std::string()),
146 edge_reader(*reader, edgeset_reader, std::string()),
147 attribute_reader(*reader, std::string()) {}
149 /// \brief Construct a new GraphReader.
151 /// Construct a new GraphReader. It reads into the given graph
152 /// and it uses the given reader as the default skipper.
153 GraphReader(LemonReader& _reader, Graph& _graph,
154 const DefaultSkipper& _skipper = DefaultSkipper())
155 : reader(_reader), own_reader(false), skipper(_skipper),
156 nodeset_reader(*reader, _graph, std::string(), skipper),
157 edgeset_reader(*reader, _graph, nodeset_reader,
158 std::string(), skipper),
159 node_reader(*reader, nodeset_reader, std::string()),
160 edge_reader(*reader, edgeset_reader, std::string()),
161 attribute_reader(*reader, std::string()) {}
163 /// \brief Destruct the graph reader.
165 /// Destruct the graph reader.
171 /// \brief Give a new node map reading command to the reader.
173 /// Give a new node map reading command to the reader.
174 template <typename Map>
175 GraphReader& readNodeMap(std::string name, Map& map) {
176 nodeset_reader.readNodeMap(name, map);
180 template <typename Map>
181 GraphReader& readNodeMap(std::string name, const Map& map) {
182 nodeset_reader.readNodeMap(name, map);
186 /// \brief Give a new node map reading command to the reader.
188 /// Give a new node map reading command to the reader.
189 template <typename Reader, typename Map>
190 GraphReader& readNodeMap(std::string name, Map& map,
191 const Reader& reader = Reader()) {
192 nodeset_reader.readNodeMap(name, map, reader);
196 template <typename Reader, typename Map>
197 GraphReader& readNodeMap(std::string name, const Map& map,
198 const Reader& reader = Reader()) {
199 nodeset_reader.readNodeMap(name, map, reader);
203 /// \brief Give a new node map skipping command to the reader.
205 /// Give a new node map skipping command to the reader.
206 template <typename Reader>
207 GraphReader& skipNodeMap(std::string name,
208 const Reader& reader = Reader()) {
209 nodeset_reader.skipNodeMap(name, reader);
213 /// \brief Give a new edge map reading command to the reader.
215 /// Give a new edge map reading command to the reader.
216 template <typename Map>
217 GraphReader& readEdgeMap(std::string name, Map& map) {
218 edgeset_reader.readEdgeMap(name, map);
222 template <typename Map>
223 GraphReader& readEdgeMap(std::string name, const Map& map) {
224 edgeset_reader.readEdgeMap(name, map);
229 /// \brief Give a new edge map reading command to the reader.
231 /// Give a new edge map reading command to the reader.
232 template <typename Reader, typename Map>
233 GraphReader& readEdgeMap(std::string name, Map& map,
234 const Reader& reader = Reader()) {
235 edgeset_reader.readEdgeMap(name, map, reader);
239 template <typename Reader, typename Map>
240 GraphReader& readEdgeMap(std::string name, const Map& map,
241 const Reader& reader = Reader()) {
242 edgeset_reader.readEdgeMap(name, map, reader);
246 /// \brief Give a new edge map skipping command to the reader.
248 /// Give a new edge map skipping command to the reader.
249 template <typename Reader>
250 GraphReader& skipEdgeMap(std::string name,
251 const Reader& reader = Reader()) {
252 edgeset_reader.skipEdgeMap(name, reader);
256 /// \brief Give a new labeled node reading command to the reader.
258 /// Give a new labeled node reading command to the reader.
259 GraphReader& readNode(std::string name, Node& node) {
260 node_reader.readNode(name, node);
264 /// \brief Give a new labeled edge reading command to the reader.
266 /// Give a new labeled edge reading command to the reader.
267 GraphReader& readEdge(std::string name, Edge& edge) {
268 edge_reader.readEdge(name, edge);
272 /// \brief Give a new attribute reading command.
274 /// Give a new attribute reading command.
275 template <typename Value>
276 GraphReader& readAttribute(std::string name, Value& value) {
277 attribute_reader.readAttribute(name, value);
281 /// \brief Give a new attribute reading command.
283 /// Give a new attribute reading command.
284 template <typename Reader, typename Value>
285 GraphReader& readAttribute(std::string name, Value& value,
286 const Reader& reader) {
287 attribute_reader.readAttribute<Reader>(name, value, reader);
291 /// \brief Conversion operator to LemonReader.
293 /// Conversion operator to LemonReader. It makes possible to access the
294 /// encapsulated \e LemonReader, this way you can attach to this reader
295 /// new instances of \e LemonReader::SectionReader. For more details see
296 /// the \ref rwbackground "Background of Reading and Writing".
297 operator LemonReader&() {
301 /// \brief Executes the reading commands.
303 /// Executes the reading commands.
309 /// \brief Returns true if the reader can give back the items by its label.
311 /// \brief Returns true if the reader can give back the items by its label.
312 bool isLabelReader() const {
313 return nodeset_reader.isLabelReader() && edgeset_reader.isLabelReader();
316 /// \brief Gives back the node by its label.
318 /// It reads an label from the stream and gives back which node belongs to
319 /// it. It is possible only if there was read an "label" named node map.
320 void readLabel(std::istream& is, Node& node) const {
321 nodeset_reader.readLabel(is, node);
324 /// \brief Gives back the edge by its label.
326 /// It reads an label from the stream and gives back which edge belongs to
327 /// it. It is possible only if there was read an "label" named edge map.
328 void readLabel(std::istream& is, Edge& edge) const {
329 return edgeset_reader.readLabel(is, edge);
337 DefaultSkipper skipper;
339 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
340 EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
342 NodeReader<Graph> node_reader;
343 EdgeReader<Graph> edge_reader;
345 AttributeReader<ReaderTraits> attribute_reader;
349 /// \brief Read a graph from the input.
351 /// It is a helper function to read a graph from the given input
352 /// stream. It gives back an GraphReader object and this object
353 /// can read more maps, labeled nodes, edges and attributes.
355 /// \warning Do not forget to call the \c run() function.
357 /// \param is The input stream.
358 /// \param g The graph.
359 template<typename Graph>
360 GraphReader<Graph> graphReader(std::istream& is, Graph &g) {
361 return GraphReader<Graph>(is, g);
364 /// \brief Read a graph from the input.
366 /// It is a helper function to read a graph from the given input
367 /// file. It gives back an GraphReader object and this object
368 /// can read more maps, labeled nodes, edges and attributes.
370 /// \warning Do not forget to call the \c run() function.
372 /// \param fn The input filename.
373 /// \param g The graph.
374 template<typename Graph>
375 GraphReader<Graph> graphReader(const std::string& fn, Graph &g) {
376 return GraphReader<Graph>(fn, g);
379 /// \brief The undirected graph reader class.
381 /// The \c UndirGraphReader class provides the graph input.
382 /// Before you read this documentation it might be useful to read the general
383 /// description of \ref graph-io-page "Graph Input-Output".
385 /// If you don't need very sophisticated
386 /// behaviour then you can use the versions of the public function
387 /// \ref readGraph() to read a graph (or a max flow instance etc).
389 /// The given file format may contain several maps and labeled nodes or
392 /// If you read a graph you need not read all the maps and items just those
393 /// that you need. The interface of the \c UndirGraphReader is very similar
394 /// to the UndirGraphWriter but the reading method does not depend on the
395 /// order of the given commands.
397 /// The reader object suppose that each not readed value does not contain
398 /// whitespaces, therefore it has some extra possibilities to control how
399 /// it should skip the values when the string representation contains spaces.
402 /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
405 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
406 /// If there is a map that you do not want to read from the file and there is
407 /// whitespace in the string represenation of the values then you should
408 /// call the \c skipNodeMap() template member function with proper
412 /// reader.readNodeMap("coords", coords);
414 /// reader.skipNodeMap("description", desc);
416 /// reader.readNodeMap("color", colorMap);
419 /// With the \c readUndirEdgeMap() member function you can give an
420 /// undir edge map reading command similar to the NodeMaps.
423 /// reader.readUndirEdgeMap("capacity", capacityMap);
426 /// The reading of the directed edge maps is just a syntactical sugar.
427 /// It reads two undirected edgemaps into a directed edge map. The
428 /// undirected edge maps' name should be start with the \c '+' and the
429 /// \c '-' character and the same.
432 /// reader.readEdgeMap("flow", flowMap);
435 /// With \c readNode() and \c readUndirEdge() functions you can read
436 /// labeled Nodes and UndirEdges.
439 /// reader.readNode("source", sourceNode);
440 /// reader.readNode("target", targetNode);
442 /// reader.readUndirEdge("observed", undirEdge);
445 /// With the \c readAttribute() functions you can read an attribute
446 /// in a variable. You can specify the reader for the attribute as
449 /// After you give all read commands you must call the \c run() member
450 /// function, which execute all the commands.
457 /// \see DefaultReaderTraits
458 /// \see \ref UndirGraphWriter
459 /// \see \ref graph-io-page
461 /// \author Balazs Dezso
462 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
463 class UndirGraphReader {
466 typedef _Graph Graph;
467 typedef typename Graph::Node Node;
468 typedef typename Graph::Edge Edge;
469 typedef typename Graph::UndirEdge UndirEdge;
471 typedef _ReaderTraits ReaderTraits;
472 typedef typename ReaderTraits::Skipper DefaultSkipper;
474 /// \brief Construct a new UndirGraphReader.
476 /// Construct a new UndirGraphReader. It reads into the given graph
477 /// and it use the given reader as the default skipper.
478 UndirGraphReader(std::istream& _is, Graph& _graph,
479 const DefaultSkipper& _skipper = DefaultSkipper())
480 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
481 nodeset_reader(*reader, _graph, std::string(), skipper),
482 undir_edgeset_reader(*reader, _graph, nodeset_reader,
483 std::string(), skipper),
484 node_reader(*reader, nodeset_reader, std::string()),
485 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
486 attribute_reader(*reader, std::string()) {}
488 /// \brief Construct a new UndirGraphReader.
490 /// Construct a new UndirGraphReader. It reads into the given graph
491 /// and it use the given reader as the default skipper.
492 UndirGraphReader(const std::string& _filename, Graph& _graph,
493 const DefaultSkipper& _skipper = DefaultSkipper())
494 : reader(new LemonReader(_filename)), own_reader(true),
496 nodeset_reader(*reader, _graph, std::string(), skipper),
497 undir_edgeset_reader(*reader, _graph, nodeset_reader,
498 std::string(), skipper),
499 node_reader(*reader, nodeset_reader, std::string()),
500 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
501 attribute_reader(*reader, std::string()) {}
503 /// \brief Construct a new UndirGraphReader.
505 /// Construct a new UndirGraphReader. It reads into the given graph
506 /// and it use the given reader as the default skipper.
507 UndirGraphReader(LemonReader& _reader, Graph& _graph,
508 const DefaultSkipper& _skipper = DefaultSkipper())
509 : reader(_reader), own_reader(false), skipper(_skipper),
510 nodeset_reader(*reader, _graph, std::string(), skipper),
511 undir_edgeset_reader(*reader, _graph, nodeset_reader,
512 std::string(), skipper),
513 node_reader(*reader, nodeset_reader, std::string()),
514 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
515 attribute_reader(*reader, std::string()) {}
517 /// \brief Destruct the graph reader.
519 /// Destruct the graph reader.
520 ~UndirGraphReader() {
525 /// \brief Give a new node map reading command to the reader.
527 /// Give a new node map reading command to the reader.
528 template <typename Map>
529 UndirGraphReader& readNodeMap(std::string name, Map& map) {
530 nodeset_reader.readNodeMap(name, map);
534 template <typename Map>
535 UndirGraphReader& readNodeMap(std::string name, const Map& map) {
536 nodeset_reader.readNodeMap(name, map);
540 /// \brief Give a new node map reading command to the reader.
542 /// Give a new node map reading command to the reader.
543 template <typename Reader, typename Map>
544 UndirGraphReader& readNodeMap(std::string name, Map& map,
545 const Reader& reader = Reader()) {
546 nodeset_reader.readNodeMap(name, map, reader);
550 template <typename Reader, typename Map>
551 UndirGraphReader& readNodeMap(std::string name, const Map& map,
552 const Reader& reader = Reader()) {
553 nodeset_reader.readNodeMap(name, map, reader);
557 /// \brief Give a new node map skipping command to the reader.
559 /// Give a new node map skipping command to the reader.
560 template <typename Reader>
561 UndirGraphReader& skipNodeMap(std::string name,
562 const Reader& reader = Reader()) {
563 nodeset_reader.skipNodeMap(name, reader);
567 /// \brief Give a new undirected edge map reading command to the reader.
569 /// Give a new undirected edge map reading command to the reader.
570 template <typename Map>
571 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
572 undir_edgeset_reader.readUndirEdgeMap(name, map);
576 template <typename Map>
577 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
578 undir_edgeset_reader.readUndirEdgeMap(name, map);
583 /// \brief Give a new undirected edge map reading command to the reader.
585 /// Give a new undirected edge map reading command to the reader.
586 template <typename Reader, typename Map>
587 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
588 const Reader& reader = Reader()) {
589 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
593 template <typename Reader, typename Map>
594 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
595 const Reader& reader = Reader()) {
596 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
600 /// \brief Give a new undirected edge map skipping command to the reader.
602 /// Give a new undirected edge map skipping command to the reader.
603 template <typename Reader>
604 UndirGraphReader& skipUndirEdgeMap(std::string name,
605 const Reader& reader = Reader()) {
606 undir_edgeset_reader.skipUndirMap(name, reader);
611 /// \brief Give a new edge map reading command to the reader.
613 /// Give a new edge map reading command to the reader.
614 template <typename Map>
615 UndirGraphReader& readEdgeMap(std::string name, Map& map) {
616 undir_edgeset_reader.readEdgeMap(name, map);
620 template <typename Map>
621 UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
622 undir_edgeset_reader.readEdgeMap(name, map);
627 /// \brief Give a new edge map reading command to the reader.
629 /// Give a new edge map reading command to the reader.
630 template <typename Reader, typename Map>
631 UndirGraphReader& readEdgeMap(std::string name, Map& map,
632 const Reader& reader = Reader()) {
633 undir_edgeset_reader.readEdgeMap(name, map, reader);
637 template <typename Reader, typename Map>
638 UndirGraphReader& readEdgeMap(std::string name, const Map& map,
639 const Reader& reader = Reader()) {
640 undir_edgeset_reader.readEdgeMap(name, map, reader);
644 /// \brief Give a new edge map skipping command to the reader.
646 /// Give a new edge map skipping command to the reader.
647 template <typename Reader>
648 UndirGraphReader& skipEdgeMap(std::string name,
649 const Reader& reader = Reader()) {
650 undir_edgeset_reader.skipEdgeMap(name, reader);
654 /// \brief Give a new labeled node reading command to the reader.
656 /// Give a new labeled node reading command to the reader.
657 UndirGraphReader& readNode(std::string name, Node& node) {
658 node_reader.readNode(name, node);
662 /// \brief Give a new labeled edge reading command to the reader.
664 /// Give a new labeled edge reading command to the reader.
665 UndirGraphReader& readEdge(std::string name, Edge& edge) {
666 undir_edge_reader.readEdge(name, edge);
669 /// \brief Give a new labeled undirected edge reading command to the
672 /// Give a new labeled undirected edge reading command to the reader.
673 UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
674 undir_edge_reader.readUndirEdge(name, edge);
677 /// \brief Give a new attribute reading command.
679 /// Give a new attribute reading command.
680 template <typename Value>
681 UndirGraphReader& readAttribute(std::string name, Value& value) {
682 attribute_reader.readAttribute(name, value);
686 /// \brief Give a new attribute reading command.
688 /// Give a new attribute reading command.
689 template <typename Reader, typename Value>
690 UndirGraphReader& readAttribute(std::string name, Value& value,
691 const Reader& reader) {
692 attribute_reader.readAttribute<Reader>(name, value, reader);
696 /// \brief Conversion operator to LemonReader.
698 /// Conversion operator to LemonReader. It make possible
699 /// to access the encapsulated \e LemonReader, this way
700 /// you can attach to this reader new instances of
701 /// \e LemonReader::SectionReader.
702 operator LemonReader&() {
706 /// \brief Executes the reading commands.
708 /// Executes the reading commands.
714 /// \brief Returns true if the reader can give back the items by its label.
716 /// \brief Returns true if the reader can give back the items by its label.
717 bool isLabelReader() const {
718 return nodeset_reader.isLabelReader() &&
719 undir_edgeset_reader.isLabelReader();
722 /// \brief Gives back the node by its label.
724 /// It reads an label from the stream and gives back which node belongs to
725 /// it. It is possible only if there was read an "label" named node map.
726 void readLabel(std::istream& is, Node& node) const {
727 return nodeset_reader.readLabel(is, node);
730 /// \brief Gives back the edge by its label.
732 /// It reads an label from the stream and gives back which edge belongs to
733 /// it. It is possible only if there was read an "label" named edge map.
734 void readLabel(std::istream& is, Edge& edge) const {
735 return undir_edgeset_reader.readLabel(is, edge);
738 /// \brief Gives back the undirected edge by its label.
740 /// It reads an label from the stream and gives back which undirected edge
741 /// belongs to it. It is possible only if there was read an "label" named
743 void readLabel(std::istream& is, UndirEdge& uedge) const {
744 return undir_edgeset_reader.readLabel(is, uedge);
753 DefaultSkipper skipper;
755 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
756 UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
758 NodeReader<Graph> node_reader;
759 UndirEdgeReader<Graph> undir_edge_reader;
761 AttributeReader<ReaderTraits> attribute_reader;
764 /// \brief Read an undirected graph from the input.
766 /// It is a helper function to read an undirected graph from the given input
767 /// stream. It gives back an UndirGraphReader object and this object
768 /// can read more maps, labeled nodes, edges, undirected edges and
771 /// \warning Do not forget to call the \c run() function.
773 /// \param is The input stream.
774 /// \param g The graph.
775 template<typename Graph>
776 UndirGraphReader<Graph> undirGraphReader(std::istream& is, Graph &g) {
777 return GraphReader<Graph>(is, g);
780 /// \brief Read an undirected graph from the input.
782 /// It is a helper function to read an undirected graph from the given input
783 /// file. It gives back an UndirGraphReader object and this object
784 /// can read more maps, labeled nodes, edges, undirected edges and
787 /// \warning Do not forget to call the \c run() function.
789 /// \param fn The input filename.
790 /// \param g The graph.
791 template<typename Graph>
792 UndirGraphReader<Graph> undirGraphReader(const std::string& fn, Graph &g) {
793 return GraphReader<Graph>(fn, g);