vmap.h: Enables one to create maps with a virtual base class.
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 io_group
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 /// If you don't need very sophisticated
43 /// behaviour then you can use the versions of the public function
44 /// \ref readGraph() to read a graph (or a max flow instance etc).
46 /// The file to be read may contain several maps and labeled nodes or
49 /// If you read a graph you need not read all the maps and items just those
50 /// that you need. The interface of the \c GraphReader is very similar to
51 /// the GraphWriter but the reading method does not depend on the order the
52 /// given commands (i.e. you don't have to insist on the order in which the
53 /// maps are given in the file).
55 /// The reader object assumes that not readed values do not contain
56 /// whitespaces, therefore it has some extra possibilities to control how
57 /// it should skip the values when the string representation contains spaces.
60 /// GraphReader<ListGraph> reader(std::cin, graph);
63 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
64 /// If there is a map that you do not want to read from the file and there is
65 /// whitespace in the string represenation of the values then you should
66 /// call the \c skipNodeMap() template member function with proper
70 /// reader.readNodeMap("coords", coords);
72 /// reader.skipNodeMap("description", desc);
74 /// reader.readNodeMap("color", colorMap);
77 /// With the \c readEdgeMap() member function you can give an edge map
78 /// reading command similar to the NodeMaps.
81 /// reader.readEdgeMap("weight", weightMap);
82 /// reader.readEdgeMap("label", labelMap);
85 /// With \c readNode() and \c readEdge() functions you can read
86 /// labeled Nodes and Edges.
89 /// reader.readNode("source", sourceNode);
90 /// reader.readNode("target", targetNode);
92 /// reader.readEdge("observed", edge);
95 /// With the \c readAttribute() functions you can read an attribute
96 /// into a variable. You can specify the reader for the attribute as
99 /// After you give all read commands you must call the \c run() member
100 /// function, which executes all the commands.
106 /// \see DefaultReaderTraits
107 /// \see QuotedStringReader
108 /// \see \ref GraphWriter
109 /// \see \ref graph-io-page
110 /// \author Balazs Dezso
111 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
115 typedef _Graph Graph;
116 typedef typename Graph::Node Node;
117 typedef typename Graph::Edge Edge;
119 typedef _ReaderTraits ReaderTraits;
120 typedef typename ReaderTraits::Skipper DefaultSkipper;
122 /// \brief Construct a new GraphReader.
124 /// Construct a new GraphReader. It reads into the given graph
125 /// and it uses the given reader as the default skipper.
126 GraphReader(std::istream& _is, Graph& _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, Graph& _graph,
141 const DefaultSkipper& _skipper = DefaultSkipper())
142 : reader(new LemonReader(_filename)), own_reader(true),
144 nodeset_reader(*reader, _graph, std::string(), skipper),
145 edgeset_reader(*reader, _graph, nodeset_reader,
146 std::string(), skipper),
147 node_reader(*reader, nodeset_reader, std::string()),
148 edge_reader(*reader, edgeset_reader, std::string()),
149 attribute_reader(*reader, std::string()) {}
151 /// \brief Construct a new GraphReader.
153 /// Construct a new GraphReader. It reads into the given graph
154 /// and it uses the given reader as the default skipper.
155 GraphReader(LemonReader& _reader, Graph& _graph,
156 const DefaultSkipper& _skipper = DefaultSkipper())
157 : reader(_reader), own_reader(false), skipper(_skipper),
158 nodeset_reader(*reader, _graph, std::string(), skipper),
159 edgeset_reader(*reader, _graph, nodeset_reader,
160 std::string(), skipper),
161 node_reader(*reader, nodeset_reader, std::string()),
162 edge_reader(*reader, edgeset_reader, std::string()),
163 attribute_reader(*reader, std::string()) {}
165 /// \brief Destruct the graph reader.
167 /// Destruct the graph reader.
173 /// \brief Give a new node map reading command to the reader.
175 /// Give a new node map reading command to the reader.
176 template <typename Map>
177 GraphReader& readNodeMap(std::string name, Map& map) {
178 nodeset_reader.readNodeMap(name, map);
182 template <typename Map>
183 GraphReader& readNodeMap(std::string name, const Map& map) {
184 nodeset_reader.readNodeMap(name, map);
188 /// \brief Give a new node map reading command to the reader.
190 /// Give a new node map reading command to the reader.
191 template <typename Reader, typename Map>
192 GraphReader& readNodeMap(std::string name, Map& map,
193 const Reader& reader = Reader()) {
194 nodeset_reader.readNodeMap(name, map, reader);
198 template <typename Reader, typename Map>
199 GraphReader& readNodeMap(std::string name, const Map& map,
200 const Reader& reader = Reader()) {
201 nodeset_reader.readNodeMap(name, map, reader);
205 /// \brief Give a new node map skipping command to the reader.
207 /// Give a new node map skipping command to the reader.
208 template <typename Reader>
209 GraphReader& skipNodeMap(std::string name,
210 const Reader& reader = Reader()) {
211 nodeset_reader.skipNodeMap(name, reader);
215 /// \brief Give a new edge map reading command to the reader.
217 /// Give a new edge map reading command to the reader.
218 template <typename Map>
219 GraphReader& readEdgeMap(std::string name, Map& map) {
220 edgeset_reader.readEdgeMap(name, map);
224 template <typename Map>
225 GraphReader& readEdgeMap(std::string name, const Map& map) {
226 edgeset_reader.readEdgeMap(name, map);
231 /// \brief Give a new edge map reading command to the reader.
233 /// Give a new edge map reading command to the reader.
234 template <typename Reader, typename Map>
235 GraphReader& readEdgeMap(std::string name, Map& map,
236 const Reader& reader = Reader()) {
237 edgeset_reader.readEdgeMap(name, map, reader);
241 template <typename Reader, typename Map>
242 GraphReader& readEdgeMap(std::string name, const Map& map,
243 const Reader& reader = Reader()) {
244 edgeset_reader.readEdgeMap(name, map, reader);
248 /// \brief Give a new edge map skipping command to the reader.
250 /// Give a new edge map skipping command to the reader.
251 template <typename Reader>
252 GraphReader& skipEdgeMap(std::string name,
253 const Reader& reader = Reader()) {
254 edgeset_reader.skipEdgeMap(name, reader);
258 /// \brief Give a new labeled node reading command to the reader.
260 /// Give a new labeled node reading command to the reader.
261 GraphReader& readNode(std::string name, Node& node) {
262 node_reader.readNode(name, node);
266 /// \brief Give a new labeled edge reading command to the reader.
268 /// Give a new labeled edge reading command to the reader.
269 GraphReader& readEdge(std::string name, Edge& edge) {
270 edge_reader.readEdge(name, edge);
274 /// \brief Give a new attribute reading command.
276 /// Give a new attribute reading command.
277 template <typename Value>
278 GraphReader& readAttribute(std::string name, Value& value) {
279 attribute_reader.readAttribute(name, value);
283 /// \brief Give a new attribute reading command.
285 /// Give a new attribute reading command.
286 template <typename Reader, typename Value>
287 GraphReader& readAttribute(std::string name, Value& value,
288 const Reader& reader) {
289 attribute_reader.readAttribute<Reader>(name, value, reader);
293 /// \brief Conversion operator to LemonReader.
295 /// Conversion operator to LemonReader. It makes possible to access the
296 /// encapsulated \e LemonReader, this way you can attach to this reader
297 /// new instances of \e LemonReader::SectionReader. For more details see
298 /// the \ref rwbackground "Background of Reading and Writing".
299 operator LemonReader&() {
303 /// \brief Executes the reading commands.
305 /// Executes the reading commands.
311 /// \brief Returns true if the reader can give back the items by its label.
313 /// \brief Returns true if the reader can give back the items by its label.
314 bool isLabelReader() const {
315 return nodeset_reader.isLabelReader() && edgeset_reader.isLabelReader();
318 /// \brief Gives back the node by its label.
320 /// It reads an label from the stream and gives back which node belongs to
321 /// it. It is possible only if there was read a "label" named node map.
322 void readLabel(std::istream& is, Node& node) const {
323 nodeset_reader.readLabel(is, node);
326 /// \brief Gives back the edge by its label.
328 /// It reads an label from the stream and gives back which edge belongs to
329 /// it. It is possible only if there was read a "label" named edge map.
330 void readLabel(std::istream& is, Edge& edge) const {
331 return edgeset_reader.readLabel(is, edge);
339 DefaultSkipper skipper;
341 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
342 EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
344 NodeReader<Graph> node_reader;
345 EdgeReader<Graph> edge_reader;
347 AttributeReader<ReaderTraits> attribute_reader;
351 /// \brief Read a graph from the input.
353 /// It is a helper function to read a graph from the given input
354 /// stream. It gives back an GraphReader object and this object
355 /// can read more maps, labeled nodes, edges and attributes.
357 /// \warning Do not forget to call the \c run() function.
359 /// \param is The input stream.
360 /// \param g The graph.
361 template<typename Graph>
362 GraphReader<Graph> graphReader(std::istream& is, Graph &g) {
363 return GraphReader<Graph>(is, g);
366 /// \brief Read a graph from the input.
368 /// It is a helper function to read a graph from the given input
369 /// file. It gives back an GraphReader object and this object
370 /// can read more maps, labeled nodes, edges and attributes.
372 /// \warning Do not forget to call the \c run() function.
374 /// \param fn The input filename.
375 /// \param g The graph.
376 template<typename Graph>
377 GraphReader<Graph> graphReader(const std::string& fn, Graph &g) {
378 return GraphReader<Graph>(fn, g);
381 /// \brief The undirected graph reader class.
383 /// The \c UGraphReader class provides the graph input.
384 /// Before you read this documentation it might be useful to read the general
385 /// description of \ref graph-io-page "Graph Input-Output".
387 /// If you don't need very sophisticated
388 /// behaviour then you can use the versions of the public function
389 /// \ref readGraph() to read a graph (or a max flow instance etc).
391 /// The given file format may contain several maps and labeled nodes or
394 /// If you read a graph you need not read all the maps and items just those
395 /// that you need. The interface of the \c UGraphReader is very similar
396 /// to the UGraphWriter but the reading method does not depend on the
397 /// order of the given commands.
399 /// The reader object suppose that each not readed value does not contain
400 /// whitespaces, therefore it has some extra possibilities to control how
401 /// it should skip the values when the string representation contains spaces.
404 /// UGraphReader<ListUGraph> reader(std::cin, graph);
407 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
408 /// If there is a map that you do not want to read from the file and there is
409 /// whitespace in the string represenation of the values then you should
410 /// call the \c skipNodeMap() template member function with proper
414 /// reader.readNodeMap("coords", coords);
416 /// reader.skipNodeMap("description", desc);
418 /// reader.readNodeMap("color", colorMap);
421 /// With the \c readUEdgeMap() member function you can give an
422 /// uedge map reading command similar to the NodeMaps.
425 /// reader.readUEdgeMap("capacity", capacityMap);
428 /// The reading of the directed edge maps is just a syntactical sugar.
429 /// It reads two undirected edgemaps into a directed edge map. The
430 /// undirected edge maps' name should be start with the \c '+' and the
431 /// \c '-' character and the same.
434 /// reader.readEdgeMap("flow", flowMap);
437 /// With \c readNode() and \c readUEdge() functions you can read
438 /// labeled Nodes and UEdges.
441 /// reader.readNode("source", sourceNode);
442 /// reader.readNode("target", targetNode);
444 /// reader.readUEdge("observed", uEdge);
447 /// With the \c readAttribute() functions you can read an attribute
448 /// in a variable. You can specify the reader for the attribute as
451 /// After you give all read commands you must call the \c run() member
452 /// function, which execute all the commands.
459 /// \see DefaultReaderTraits
460 /// \see \ref UGraphWriter
461 /// \see \ref graph-io-page
463 /// \author Balazs Dezso
464 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
468 typedef _Graph Graph;
469 typedef typename Graph::Node Node;
470 typedef typename Graph::Edge Edge;
471 typedef typename Graph::UEdge UEdge;
473 typedef _ReaderTraits ReaderTraits;
474 typedef typename ReaderTraits::Skipper DefaultSkipper;
476 /// \brief Construct a new UGraphReader.
478 /// Construct a new UGraphReader. It reads into the given graph
479 /// and it use the given reader as the default skipper.
480 UGraphReader(std::istream& _is, Graph& _graph,
481 const DefaultSkipper& _skipper = DefaultSkipper())
482 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
483 nodeset_reader(*reader, _graph, std::string(), skipper),
484 u_edgeset_reader(*reader, _graph, nodeset_reader,
485 std::string(), skipper),
486 node_reader(*reader, nodeset_reader, std::string()),
487 u_edge_reader(*reader, u_edgeset_reader, std::string()),
488 attribute_reader(*reader, std::string()) {}
490 /// \brief Construct a new UGraphReader.
492 /// Construct a new UGraphReader. It reads into the given graph
493 /// and it use the given reader as the default skipper.
494 UGraphReader(const std::string& _filename, Graph& _graph,
495 const DefaultSkipper& _skipper = DefaultSkipper())
496 : reader(new LemonReader(_filename)), own_reader(true),
498 nodeset_reader(*reader, _graph, std::string(), skipper),
499 u_edgeset_reader(*reader, _graph, nodeset_reader,
500 std::string(), skipper),
501 node_reader(*reader, nodeset_reader, std::string()),
502 u_edge_reader(*reader, u_edgeset_reader, std::string()),
503 attribute_reader(*reader, std::string()) {}
505 /// \brief Construct a new UGraphReader.
507 /// Construct a new UGraphReader. It reads into the given graph
508 /// and it use the given reader as the default skipper.
509 UGraphReader(LemonReader& _reader, Graph& _graph,
510 const DefaultSkipper& _skipper = DefaultSkipper())
511 : reader(_reader), own_reader(false), skipper(_skipper),
512 nodeset_reader(*reader, _graph, std::string(), skipper),
513 u_edgeset_reader(*reader, _graph, nodeset_reader,
514 std::string(), skipper),
515 node_reader(*reader, nodeset_reader, std::string()),
516 u_edge_reader(*reader, u_edgeset_reader, std::string()),
517 attribute_reader(*reader, std::string()) {}
519 /// \brief Destruct the graph reader.
521 /// Destruct the graph reader.
527 /// \brief Give a new node map reading command to the reader.
529 /// Give a new node map reading command to the reader.
530 template <typename Map>
531 UGraphReader& readNodeMap(std::string name, Map& map) {
532 nodeset_reader.readNodeMap(name, map);
536 template <typename Map>
537 UGraphReader& readNodeMap(std::string name, const Map& map) {
538 nodeset_reader.readNodeMap(name, map);
542 /// \brief Give a new node map reading command to the reader.
544 /// Give a new node map reading command to the reader.
545 template <typename Reader, typename Map>
546 UGraphReader& readNodeMap(std::string name, Map& map,
547 const Reader& reader = Reader()) {
548 nodeset_reader.readNodeMap(name, map, reader);
552 template <typename Reader, typename Map>
553 UGraphReader& readNodeMap(std::string name, const Map& map,
554 const Reader& reader = Reader()) {
555 nodeset_reader.readNodeMap(name, map, reader);
559 /// \brief Give a new node map skipping command to the reader.
561 /// Give a new node map skipping command to the reader.
562 template <typename Reader>
563 UGraphReader& skipNodeMap(std::string name,
564 const Reader& reader = Reader()) {
565 nodeset_reader.skipNodeMap(name, reader);
569 /// \brief Give a new undirected edge map reading command to the reader.
571 /// Give a new undirected edge map reading command to the reader.
572 template <typename Map>
573 UGraphReader& readUEdgeMap(std::string name, Map& map) {
574 u_edgeset_reader.readUEdgeMap(name, map);
578 template <typename Map>
579 UGraphReader& readUEdgeMap(std::string name, const Map& map) {
580 u_edgeset_reader.readUEdgeMap(name, map);
585 /// \brief Give a new undirected edge map reading command to the reader.
587 /// Give a new undirected edge map reading command to the reader.
588 template <typename Reader, typename Map>
589 UGraphReader& readUEdgeMap(std::string name, Map& map,
590 const Reader& reader = Reader()) {
591 u_edgeset_reader.readUEdgeMap(name, map, reader);
595 template <typename Reader, typename Map>
596 UGraphReader& readUEdgeMap(std::string name, const Map& map,
597 const Reader& reader = Reader()) {
598 u_edgeset_reader.readUEdgeMap(name, map, reader);
602 /// \brief Give a new undirected edge map skipping command to the reader.
604 /// Give a new undirected edge map skipping command to the reader.
605 template <typename Reader>
606 UGraphReader& skipUEdgeMap(std::string name,
607 const Reader& reader = Reader()) {
608 u_edgeset_reader.skipUMap(name, reader);
613 /// \brief Give a new edge map reading command to the reader.
615 /// Give a new edge map reading command to the reader.
616 template <typename Map>
617 UGraphReader& readEdgeMap(std::string name, Map& map) {
618 u_edgeset_reader.readEdgeMap(name, map);
622 template <typename Map>
623 UGraphReader& readEdgeMap(std::string name, const Map& map) {
624 u_edgeset_reader.readEdgeMap(name, map);
629 /// \brief Give a new edge map reading command to the reader.
631 /// Give a new edge map reading command to the reader.
632 template <typename Reader, typename Map>
633 UGraphReader& readEdgeMap(std::string name, Map& map,
634 const Reader& reader = Reader()) {
635 u_edgeset_reader.readEdgeMap(name, map, reader);
639 template <typename Reader, typename Map>
640 UGraphReader& readEdgeMap(std::string name, const Map& map,
641 const Reader& reader = Reader()) {
642 u_edgeset_reader.readEdgeMap(name, map, reader);
646 /// \brief Give a new edge map skipping command to the reader.
648 /// Give a new edge map skipping command to the reader.
649 template <typename Reader>
650 UGraphReader& skipEdgeMap(std::string name,
651 const Reader& reader = Reader()) {
652 u_edgeset_reader.skipEdgeMap(name, reader);
656 /// \brief Give a new labeled node reading command to the reader.
658 /// Give a new labeled node reading command to the reader.
659 UGraphReader& readNode(std::string name, Node& node) {
660 node_reader.readNode(name, node);
664 /// \brief Give a new labeled edge reading command to the reader.
666 /// Give a new labeled edge reading command to the reader.
667 UGraphReader& readEdge(std::string name, Edge& edge) {
668 u_edge_reader.readEdge(name, edge);
671 /// \brief Give a new labeled undirected edge reading command to the
674 /// Give a new labeled undirected edge reading command to the reader.
675 UGraphReader& readUEdge(std::string name, UEdge& edge) {
676 u_edge_reader.readUEdge(name, edge);
679 /// \brief Give a new attribute reading command.
681 /// Give a new attribute reading command.
682 template <typename Value>
683 UGraphReader& readAttribute(std::string name, Value& value) {
684 attribute_reader.readAttribute(name, value);
688 /// \brief Give a new attribute reading command.
690 /// Give a new attribute reading command.
691 template <typename Reader, typename Value>
692 UGraphReader& readAttribute(std::string name, Value& value,
693 const Reader& reader) {
694 attribute_reader.readAttribute<Reader>(name, value, reader);
698 /// \brief Conversion operator to LemonReader.
700 /// Conversion operator to LemonReader. It make possible
701 /// to access the encapsulated \e LemonReader, this way
702 /// you can attach to this reader new instances of
703 /// \e LemonReader::SectionReader.
704 operator LemonReader&() {
708 /// \brief Executes the reading commands.
710 /// Executes the reading commands.
716 /// \brief Returns true if the reader can give back the items by its label.
718 /// \brief Returns true if the reader can give back the items by its label.
719 bool isLabelReader() const {
720 return nodeset_reader.isLabelReader() &&
721 u_edgeset_reader.isLabelReader();
724 /// \brief Gives back the node by its label.
726 /// It reads an label from the stream and gives back which node belongs to
727 /// it. It is possible only if there was read a "label" named node map.
728 void readLabel(std::istream& is, Node& node) const {
729 return nodeset_reader.readLabel(is, node);
732 /// \brief Gives back the edge by its label
734 /// It reads an label from the stream and gives back which edge belongs to
735 /// it. It is possible only if there was read a "label" named edge map.
736 void readLabel(std::istream& is, Edge& edge) const {
737 return u_edgeset_reader.readLabel(is, edge);
740 /// \brief Gives back the undirected edge by its label.
742 /// It reads an label from the stream and gives back which undirected edge
743 /// belongs to it. It is possible only if there was read a "label" named
745 void readLabel(std::istream& is, UEdge& uedge) const {
746 return u_edgeset_reader.readLabel(is, uedge);
755 DefaultSkipper skipper;
757 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
758 UEdgeSetReader<Graph, ReaderTraits> u_edgeset_reader;
760 NodeReader<Graph> node_reader;
761 UEdgeReader<Graph> u_edge_reader;
763 AttributeReader<ReaderTraits> attribute_reader;
766 /// \brief Read an undirected graph from the input.
768 /// It is a helper function to read an undirected graph from the given input
769 /// stream. It gives back an UGraphReader object and this object
770 /// can read more maps, labeled nodes, edges, undirected edges and
773 /// \warning Do not forget to call the \c run() function.
775 /// \param is The input stream.
776 /// \param g The graph.
777 template<typename Graph>
778 UGraphReader<Graph> uGraphReader(std::istream& is, Graph &g) {
779 return GraphReader<Graph>(is, g);
782 /// \brief Read an undirected graph from the input.
784 /// It is a helper function to read an undirected graph from the given input
785 /// file. It gives back an UGraphReader object and this object
786 /// can read more maps, labeled nodes, edges, undirected edges and
789 /// \warning Do not forget to call the \c run() function.
791 /// \param fn The input filename.
792 /// \param g The graph.
793 template<typename Graph>
794 UGraphReader<Graph> uGraphReader(const std::string& fn, Graph &g) {
795 return GraphReader<Graph>(fn, g);