COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_reader.h @ 1705:3f63d9db307b

Last change on this file since 1705:3f63d9db307b was 1705:3f63d9db307b, checked in by Balazs Dezso, 14 years ago

Removing smart references

File size: 28.1 KB
Line 
1/* -*- C++ -*-
2 * lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
6 *
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.
10 *
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
13 * purpose.
14 *
15 */
16
17///\ingroup io_group
18///\file
19///\brief Lemon Graph Format reader.
20
21#ifndef LEMON_GRAPH_READER_H
22#define LEMON_GRAPH_READER_H
23
24#include <iostream>
25
26#include <lemon/error.h>
27#include <lemon/lemon_reader.h>
28
29namespace lemon {
30
31  /// \addtogroup io_group
32  /// @{
33
34  /// \brief The graph reader class.
35  ///
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".
39  ///
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).
43  ///
44  /// The file to be read may contain several maps and labeled nodes or
45  /// edges.
46  ///
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).
52  ///
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.
56  ///
57  /// \code
58  /// GraphReader<ListGraph> reader(std::cin, graph);
59  /// \endcode
60  ///
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
65  /// parameters.
66  ///
67  /// \code
68  /// reader.readNodeMap("coords", coords);
69  ///
70  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
71  /// reader.skipNodeMap<QuotedStringReader>("description");
72  ///
73  /// reader.readNodeMap("color", colorMap);
74  /// \endcode
75  ///
76  /// With the \c readEdgeMap() member function you can give an edge map
77  /// reading command similar to the NodeMaps.
78  ///
79  /// \code
80  /// reader.readEdgeMap("weight", weightMap);
81  /// reader.readEdgeMap("label", labelMap);
82  /// \endcode
83  ///
84  /// With \c readNode() and \c readEdge() functions you can read
85  /// labeled Nodes and Edges.
86  ///
87  /// \code
88  /// reader.readNode("source", sourceNode);
89  /// reader.readNode("target", targetNode);
90  ///
91  /// reader.readEdge("observed", edge);
92  /// \endcode
93  ///
94  /// With the \c readAttribute() functions you can read an attribute
95  /// into a variable. You can specify the reader for the attribute as
96  /// the nodemaps.
97  ///
98  /// After you give all read commands you must call the \c run() member
99  /// function, which executes all the commands.
100  ///
101  /// \code
102  /// reader.run();
103  /// \endcode
104  ///
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>
111  class GraphReader {
112  public:
113   
114    typedef _Graph Graph;
115    typedef typename Graph::Node Node;
116    typedef typename Graph::Edge Edge;
117
118    typedef _ReaderTraits ReaderTraits;
119    typedef typename ReaderTraits::Skipper DefaultSkipper;
120
121    /// \brief Construct a new GraphReader.
122    ///
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, Graph& _graph,
126                const DefaultSkipper& _skipper = DefaultSkipper())
127      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
128        nodeset_reader(*reader, _graph, std::string(), skipper),
129        edgeset_reader(*reader, _graph, nodeset_reader,
130                       std::string(), skipper),
131        node_reader(*reader, nodeset_reader, std::string()),
132        edge_reader(*reader, edgeset_reader, std::string()),
133        attribute_reader(*reader, std::string()) {}
134
135    /// \brief Construct a new GraphReader.
136    ///
137    /// Construct a new GraphReader. It reads into the given graph
138    /// and it uses the given reader as the default skipper.
139    GraphReader(const std::string& _filename, Graph& _graph,
140                const DefaultSkipper& _skipper = DefaultSkipper())
141      : reader(new LemonReader(_filename)), own_reader(true),
142        skipper(_skipper),
143        nodeset_reader(*reader, _graph, std::string(), skipper),
144        edgeset_reader(*reader, _graph, nodeset_reader,
145                       std::string(), skipper),
146        node_reader(*reader, nodeset_reader, std::string()),
147        edge_reader(*reader, edgeset_reader, std::string()),
148        attribute_reader(*reader, std::string()) {}
149
150    /// \brief Construct a new GraphReader.
151    ///
152    /// Construct a new GraphReader. It reads into the given graph
153    /// and it uses the given reader as the default skipper.
154    GraphReader(LemonReader& _reader, Graph& _graph,
155                const DefaultSkipper& _skipper = DefaultSkipper())
156      : reader(_reader), own_reader(false), skipper(_skipper),
157        nodeset_reader(*reader, _graph, std::string(), skipper),
158        edgeset_reader(*reader, _graph, nodeset_reader,
159                       std::string(), skipper),
160        node_reader(*reader, nodeset_reader, std::string()),
161        edge_reader(*reader, edgeset_reader, std::string()),
162        attribute_reader(*reader, std::string()) {}
163
164    /// \brief Destruct the graph reader.
165    ///
166    /// Destruct the graph reader.
167    ~GraphReader() {
168      if (own_reader)
169        delete reader;
170    }
171
172    /// \brief Give a new node map reading command to the reader.
173    ///
174    /// Give a new node map reading command to the reader.
175    template <typename Map>
176    GraphReader& readNodeMap(std::string name, Map& map) {
177      nodeset_reader.readNodeMap(name, map);
178      return *this;
179    }
180
181    template <typename Map>
182    GraphReader& readNodeMap(std::string name, const Map& map) {
183      nodeset_reader.readNodeMap(name, map);
184      return *this;
185    }
186
187    /// \brief Give a new node map reading command to the reader.
188    ///
189    /// Give a new node map reading command to the reader.
190    template <typename Reader, typename Map>
191    GraphReader& readNodeMap(std::string name, Map& map,
192                             const Reader& reader = Reader()) {
193      nodeset_reader.readNodeMap(name, map, reader);
194      return *this;
195    }
196
197    template <typename Reader, typename Map>
198    GraphReader& readNodeMap(std::string name, const Map& map,
199                             const Reader& reader = Reader()) {
200      nodeset_reader.readNodeMap(name, map, reader);
201      return *this;
202    }
203
204    /// \brief Give a new node map skipping command to the reader.
205    ///
206    /// Give a new node map skipping command to the reader.
207    template <typename Reader>
208    GraphReader& skipNodeMap(std::string name,
209                             const Reader& reader = Reader()) {
210      nodeset_reader.skipNodeMap(name, reader);
211      return *this;
212    }
213
214    /// \brief Give a new edge map reading command to the reader.
215    ///
216    /// Give a new edge map reading command to the reader.
217    template <typename Map>
218    GraphReader& readEdgeMap(std::string name, Map& map) {
219      edgeset_reader.readEdgeMap(name, map);
220      return *this;
221    }
222
223    template <typename Map>
224    GraphReader& readEdgeMap(std::string name, const Map& map) {
225      edgeset_reader.readEdgeMap(name, map);
226      return *this;
227    }
228
229
230    /// \brief Give a new edge map reading command to the reader.
231    ///
232    /// Give a new edge map reading command to the reader.
233    template <typename Reader, typename Map>
234    GraphReader& readEdgeMap(std::string name, Map& map,
235                             const Reader& reader = Reader()) {
236      edgeset_reader.readEdgeMap(name, map, reader);
237      return *this;
238    }
239
240    template <typename Reader, typename Map>
241    GraphReader& readEdgeMap(std::string name, const Map& map,
242                             const Reader& reader = Reader()) {
243      edgeset_reader.readEdgeMap(name, map, reader);
244      return *this;
245    }
246
247    /// \brief Give a new edge map skipping command to the reader.
248    ///
249    /// Give a new edge map skipping command to the reader.
250    template <typename Reader>
251    GraphReader& skipEdgeMap(std::string name,
252                             const Reader& reader = Reader()) {
253      edgeset_reader.skipEdgeMap(name, reader);
254      return *this;
255    }
256
257    /// \brief Give a new labeled node reading command to the reader.
258    ///
259    /// Give a new labeled node reading command to the reader.
260    GraphReader& readNode(std::string name, Node& node) {
261      node_reader.readNode(name, node);
262      return *this;
263    }
264
265    /// \brief Give a new labeled edge reading command to the reader.
266    ///
267    /// Give a new labeled edge reading command to the reader.
268    GraphReader& readEdge(std::string name, Edge& edge) {
269      edge_reader.readEdge(name, edge);
270      return *this;
271    }
272
273    /// \brief Give a new attribute reading command.
274    ///
275    ///  Give a new attribute reading command.
276    template <typename Value>
277    GraphReader& readAttribute(std::string name, Value& value) {
278      attribute_reader.readAttribute(name, value);
279      return *this;
280    }
281   
282    /// \brief Give a new attribute reading command.
283    ///
284    ///  Give a new attribute reading command.
285    template <typename Reader, typename Value>
286    GraphReader& readAttribute(std::string name, Value& value,
287                               const Reader& reader) {
288      attribute_reader.readAttribute<Reader>(name, value, reader);
289      return *this;
290    }
291
292    /// \brief Conversion operator to LemonReader.
293    ///
294    /// Conversion operator to LemonReader. It makes possible to access the
295    /// encapsulated \e LemonReader, this way you can attach to this reader
296    /// new instances of \e LemonReader::SectionReader. For more details see
297    /// the \ref rwbackground "Background of Reading and Writing".
298    operator LemonReader&() {
299      return *reader;
300    }
301
302    /// \brief Executes the reading commands.
303    ///
304    /// Executes the reading commands.
305    void run() {
306      reader->run();
307    }
308
309    /// \brief Gives back the node by its id.
310    ///
311    /// It reads an id from the stream and gives back which node belongs to
312    /// it. It is possible only if there was read an "id" named node map.
313    Node readId(std::istream& is, Node) const {
314      return nodeset_reader.readId(is, Node());
315    }
316
317    /// \brief Gives back the edge by its id.
318    ///
319    /// It reads an id from the stream and gives back which edge belongs to
320    /// it. It is possible only if there was read an "id" named edge map.
321    Edge readId(std::istream& is, Edge) const {
322      return edgeset_reader.readId(is, Edge());
323    }
324
325  private:
326
327    LemonReader* reader;
328    bool own_reader;
329
330    DefaultSkipper skipper;
331
332    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
333    EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
334
335    NodeReader<Graph> node_reader;
336    EdgeReader<Graph> edge_reader;
337   
338    AttributeReader<ReaderTraits> attribute_reader;
339  };
340
341
342  ///\anchor readGraph()
343  ///
344  /// \brief Read a graph from an input stream.
345  ///
346  /// Read a graph from an input stream.
347  /// \param is The input stream.
348  /// \param g The graph.
349  template<typename Graph>
350  void readGraph(std::istream& is, Graph &g) {
351    GraphReader<Graph> reader(is, g);
352    reader.run();
353  }
354
355  /// \brief Read a capacitated graph instance from an input stream.
356  ///
357  /// Read a capacitated graph (graph+capacity on the
358  /// edges) from an input stream.
359  /// \param is The input stream.
360  /// \param g The graph.
361  /// \param capacity The capacity map.
362  template<typename Graph, typename CapacityMap>
363  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
364    GraphReader<Graph> reader(is, g);
365    reader.readEdgeMap("capacity", capacity);
366    reader.run();
367  }
368
369  /// \brief Read a shortest path instance from an input stream.
370  ///
371  /// Read a shortest path instance (graph+capacity on the
372  /// edges+designated source) from an input stream.
373  /// \param is The input stream.
374  /// \param g The graph.
375  /// \param capacity The capacity map.
376  /// \param s The source node.
377  template<typename Graph, typename CapacityMap>
378  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
379                  typename Graph::Node &s) {
380    GraphReader<Graph> reader(is, g);
381    reader.readEdgeMap("capacity", capacity);
382    reader.readNode("source", s);
383    reader.run();
384  }
385
386
387
388  /// \brief Read a max flow instance from an input stream.
389  ///
390  /// Read a max flow instance (graph+capacity on the
391  /// edges+designated source and target) from an input stream.
392  ///
393  /// \param is The input stream.
394  /// \param g The graph.
395  /// \param capacity The capacity map.
396  /// \param s The source node.
397  /// \param t The target node.
398  template<typename Graph, typename CapacityMap>
399  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
400                  typename Graph::Node &s, typename Graph::Node &t) {
401    GraphReader<Graph> reader(is, g);
402    reader.readEdgeMap("capacity", capacity);
403    reader.readNode("source", s);
404    reader.readNode("target", t);
405    reader.run();
406  }
407
408  /// \brief Read a min cost flow instance from an input stream.
409  ///
410  /// Read a min cost flow instance (graph+capacity on the edges+cost
411  /// function on the edges+designated source and target) from an input stream.
412  ///
413  /// \param is The input stream.
414  /// \param g The graph.
415  /// \param capacity The capacity map.
416  /// \param s The source node.
417  /// \param t The target node.
418  /// \param cost The cost map.
419  template<typename Graph, typename CapacityMap, typename CostMap>
420  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
421                  typename Graph::Node &s, typename Graph::Node &t,
422                  CostMap& cost) {
423    GraphReader<Graph> reader(is, g);
424    reader.readEdgeMap("capacity", capacity);
425    reader.readEdgeMap("cost", cost);
426    reader.readNode("source", s);
427    reader.readNode("target", t);
428    reader.run();
429  }
430
431
432  /// \brief The undir graph reader class.
433  ///
434  /// The \c UndirGraphReader class provides the graph input.
435  /// Before you read this documentation it might be useful to read the general
436  /// description of  \ref graph-io-page "Graph Input-Output".
437  ///
438  /// If you don't need very sophisticated
439  /// behaviour then you can use the versions of the public function
440  /// \ref readGraph() to read a graph (or a max flow instance etc).
441  ///
442  /// The given file format may contain several maps and labeled nodes or
443  /// edges.
444  ///
445  /// If you read a graph you need not read all the maps and items just those
446  /// that you need. The interface of the \c UndirGraphReader is very similar
447  /// to the UndirGraphWriter but the reading method does not depend on the
448  /// order of the given commands.
449  ///
450  /// The reader object suppose that each not readed value does not contain
451  /// whitespaces, therefore it has some extra possibilities to control how
452  /// it should skip the values when the string representation contains spaces.
453  ///
454  /// \code
455  /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
456  /// \endcode
457  ///
458  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
459  /// If there is a map that you do not want to read from the file and there is
460  /// whitespace in the string represenation of the values then you should
461  /// call the \c skipNodeMap() template member function with proper
462  /// parameters.
463  ///
464  /// \code
465  /// reader.readNodeMap("coords", coords);
466  ///
467  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
468  /// reader.skipNodeMap<QuotedStringReader>("description");
469  ///
470  /// reader.readNodeMap("color", colorMap);
471  /// \endcode
472  ///
473  /// With the \c readUndirEdgeMap() member function you can give an
474  /// undir edge map reading command similar to the NodeMaps.
475  ///
476  /// \code
477  /// reader.readUndirEdgeMap("capacity", capacityMap);
478  /// \endcode
479  ///
480  /// The reading of the directed edge maps is just a syntactical sugar.
481  /// It reads two undirected edgemaps into a directed edge map. The
482  /// undirected edge maps' name should be start with the \c '+' and the
483  /// \c '-' character and the same.
484  ///
485  /// \code
486  /// reader.readEdgeMap("flow", flowMap);
487  /// \endcode
488  ///
489  /// With \c readNode() and \c readUndirEdge() functions you can read
490  /// labeled Nodes and UndirEdges.
491  ///
492  /// \code
493  /// reader.readNode("source", sourceNode);
494  /// reader.readNode("target", targetNode);
495  ///
496  /// reader.readUndirEdge("observed", undirEdge);
497  /// \endcode
498  ///
499  /// With the \c readAttribute() functions you can read an attribute
500  /// in a variable. You can specify the reader for the attribute as
501  /// the nodemaps.
502  ///
503  /// After you give all read commands you must call the \c run() member
504  /// function, which execute all the commands.
505  ///
506  /// \code
507  /// reader.run();
508  /// \endcode
509  ///
510  /// \see GraphReader
511  /// \see DefaultReaderTraits
512  /// \see \ref UndirGraphWriter
513  /// \see \ref graph-io-page
514  ///
515  /// \author Balazs Dezso
516  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
517  class UndirGraphReader {
518  public:
519   
520    typedef _Graph Graph;
521    typedef typename Graph::Node Node;
522    typedef typename Graph::Edge Edge;
523    typedef typename Graph::UndirEdge UndirEdge;
524
525    typedef _ReaderTraits ReaderTraits;
526    typedef typename ReaderTraits::Skipper DefaultSkipper;
527
528    /// \brief Construct a new UndirGraphReader.
529    ///
530    /// Construct a new UndirGraphReader. It reads into the given graph
531    /// and it use the given reader as the default skipper.
532    UndirGraphReader(std::istream& _is, Graph& _graph,
533                     const DefaultSkipper& _skipper = DefaultSkipper())
534      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
535        nodeset_reader(*reader, _graph, std::string(), skipper),
536        undir_edgeset_reader(*reader, _graph, nodeset_reader,
537                             std::string(), skipper),
538        node_reader(*reader, nodeset_reader, std::string()),
539        undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
540        attribute_reader(*reader, std::string()) {}
541
542    /// \brief Construct a new UndirGraphReader.
543    ///
544    /// Construct a new UndirGraphReader. It reads into the given graph
545    /// and it use the given reader as the default skipper.
546    UndirGraphReader(const std::string& _filename, Graph& _graph,
547                     const DefaultSkipper& _skipper = DefaultSkipper())
548      : reader(new LemonReader(_filename)), own_reader(true),
549        skipper(_skipper),
550        nodeset_reader(*reader, _graph, std::string(), skipper),
551        undir_edgeset_reader(*reader, _graph, nodeset_reader,
552                             std::string(), skipper),
553        node_reader(*reader, nodeset_reader, std::string()),
554        undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
555        attribute_reader(*reader, std::string()) {}
556
557    /// \brief Construct a new UndirGraphReader.
558    ///
559    /// Construct a new UndirGraphReader. It reads into the given graph
560    /// and it use the given reader as the default skipper.
561    UndirGraphReader(LemonReader& _reader, Graph& _graph,
562                     const DefaultSkipper& _skipper = DefaultSkipper())
563      : reader(_reader), own_reader(false), skipper(_skipper),
564        nodeset_reader(*reader, _graph, std::string(), skipper),
565        undir_edgeset_reader(*reader, _graph, nodeset_reader,
566                             std::string(), skipper),
567        node_reader(*reader, nodeset_reader, std::string()),
568        undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
569        attribute_reader(*reader, std::string()) {}
570
571    /// \brief Destruct the graph reader.
572    ///
573    /// Destruct the graph reader.
574    ~UndirGraphReader() {
575      if (own_reader)
576        delete reader;
577    }
578
579    /// \brief Give a new node map reading command to the reader.
580    ///
581    /// Give a new node map reading command to the reader.
582    template <typename Map>
583    UndirGraphReader& readNodeMap(std::string name, Map& map) {
584      nodeset_reader.readNodeMap(name, map);
585      return *this;
586    }
587
588    template <typename Map>
589    UndirGraphReader& readNodeMap(std::string name, const Map& map) {
590      nodeset_reader.readNodeMap(name, map);
591      return *this;
592    }
593
594    /// \brief Give a new node map reading command to the reader.
595    ///
596    /// Give a new node map reading command to the reader.
597    template <typename Reader, typename Map>
598    UndirGraphReader& readNodeMap(std::string name, Map& map,
599                                  const Reader& reader = Reader()) {
600      nodeset_reader.readNodeMap(name, map, reader);
601      return *this;
602    }
603
604    template <typename Reader, typename Map>
605    UndirGraphReader& readNodeMap(std::string name, const Map& map,
606                                  const Reader& reader = Reader()) {
607      nodeset_reader.readNodeMap(name, map, reader);
608      return *this;
609    }
610
611    /// \brief Give a new node map skipping command to the reader.
612    ///
613    /// Give a new node map skipping command to the reader.
614    template <typename Reader>
615    UndirGraphReader& skipNodeMap(std::string name,
616                             const Reader& reader = Reader()) {
617      nodeset_reader.skipNodeMap(name, reader);
618      return *this;
619    }
620
621    /// \brief Give a new undirected edge map reading command to the reader.
622    ///
623    /// Give a new undirected edge map reading command to the reader.
624    template <typename Map>
625    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
626      undir_edgeset_reader.readUndirEdgeMap(name, map);
627      return *this;
628    }
629
630    template <typename Map>
631    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
632      undir_edgeset_reader.readUndirEdgeMap(name, map);
633      return *this;
634    }
635
636
637    /// \brief Give a new undirected edge map reading command to the reader.
638    ///
639    /// Give a new undirected edge map reading command to the reader.
640    template <typename Reader, typename Map>
641    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
642                                       const Reader& reader = Reader()) {
643      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
644      return *this;
645    }
646
647    template <typename Reader, typename Map>
648    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
649                                       const Reader& reader = Reader()) {
650      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
651      return *this;
652    }
653
654    /// \brief Give a new undirected edge map skipping command to the reader.
655    ///
656    /// Give a new undirected edge map skipping command to the reader.
657    template <typename Reader>
658    UndirGraphReader& skipUndirEdgeMap(std::string name,
659                                       const Reader& reader = Reader()) {
660      undir_edgeset_reader.skipUndirMap(name, reader);
661      return *this;
662    }
663
664
665    /// \brief Give a new edge map reading command to the reader.
666    ///
667    /// Give a new edge map reading command to the reader.
668    template <typename Map>
669    UndirGraphReader& readEdgeMap(std::string name, Map& map) {
670      undir_edgeset_reader.readEdgeMap(name, map);
671      return *this;
672    }
673
674    template <typename Map>
675    UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
676      undir_edgeset_reader.readEdgeMap(name, map);
677      return *this;
678    }
679
680
681    /// \brief Give a new edge map reading command to the reader.
682    ///
683    /// Give a new edge map reading command to the reader.
684    template <typename Reader, typename Map>
685    UndirGraphReader& readEdgeMap(std::string name, Map& map,
686                                       const Reader& reader = Reader()) {
687      undir_edgeset_reader.readEdgeMap(name, map, reader);
688      return *this;
689    }
690
691    template <typename Reader, typename Map>
692    UndirGraphReader& readEdgeMap(std::string name, const Map& map,
693                                       const Reader& reader = Reader()) {
694      undir_edgeset_reader.readEdgeMap(name, map, reader);
695      return *this;
696    }
697
698    /// \brief Give a new edge map skipping command to the reader.
699    ///
700    /// Give a new edge map skipping command to the reader.
701    template <typename Reader>
702    UndirGraphReader& skipEdgeMap(std::string name,
703                                       const Reader& reader = Reader()) {
704      undir_edgeset_reader.skipEdgeMap(name, reader);
705      return *this;
706    }
707
708    /// \brief Give a new labeled node reading command to the reader.
709    ///
710    /// Give a new labeled node reading command to the reader.
711    UndirGraphReader& readNode(std::string name, Node& node) {
712      node_reader.readNode(name, node);
713      return *this;
714    }
715
716    /// \brief Give a new labeled edge reading command to the reader.
717    ///
718    /// Give a new labeled edge reading command to the reader.
719    UndirGraphReader& readEdge(std::string name, Edge& edge) {
720      undir_edge_reader.readEdge(name, edge);
721    }
722
723    /// \brief Give a new labeled undirected edge reading command to the
724    /// reader.
725    ///
726    /// Give a new labeled undirected edge reading command to the reader.
727    UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
728      undir_edge_reader.readUndirEdge(name, edge);
729    }
730
731    /// \brief Give a new attribute reading command.
732    ///
733    ///  Give a new attribute reading command.
734    template <typename Value>
735    UndirGraphReader& readAttribute(std::string name, Value& value) {
736      attribute_reader.readAttribute(name, value);
737      return *this;
738    }
739   
740    /// \brief Give a new attribute reading command.
741    ///
742    ///  Give a new attribute reading command.
743    template <typename Reader, typename Value>
744    UndirGraphReader& readAttribute(std::string name, Value& value,
745                               const Reader& reader) {
746      attribute_reader.readAttribute<Reader>(name, value, reader);
747      return *this;
748    }
749
750    /// \brief Conversion operator to LemonReader.
751    ///
752    /// Conversion operator to LemonReader. It make possible
753    /// to access the encapsulated \e LemonReader, this way
754    /// you can attach to this reader new instances of
755    /// \e LemonReader::SectionReader.
756    operator LemonReader&() {
757      return *reader;
758    }
759
760    /// \brief Executes the reading commands.
761    ///
762    /// Executes the reading commands.
763    void run() {
764      reader->run();
765    }
766
767    /// \brief Gives back the node by its id.
768    ///
769    /// It reads an id from the stream and gives back which node belongs to
770    /// it. It is possible only if there was read an "id" named node map.
771    Node readId(std::istream& is, Node) const {
772      return nodeset_reader.readId(is, Node());
773    }
774
775    /// \brief Gives back the edge by its id.
776    ///
777    /// It reads an id from the stream and gives back which edge belongs to
778    /// it. It is possible only if there was read an "id" named edge map.
779    Edge readId(std::istream& is, Edge) const {
780      return undir_edgeset_reader.readId(is, Edge());
781    }
782
783    /// \brief Gives back the undirected edge by its id.
784    ///
785    /// It reads an id from the stream and gives back which undirected edge
786    /// belongs to it. It is possible only if there was read an "id" named
787    /// edge map.
788    UndirEdge readId(std::istream& is, UndirEdge) const {
789      return undir_edgeset_reader.readId(is, UndirEdge());
790    }
791   
792
793  private:
794
795    LemonReader* reader;
796    bool own_reader;
797
798    DefaultSkipper skipper;
799
800    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
801    UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
802
803    NodeReader<Graph> node_reader;
804    UndirEdgeReader<Graph> undir_edge_reader;
805   
806    AttributeReader<ReaderTraits> attribute_reader;
807  };
808
809  /// \brief Read an undirected graph from an input stream.
810  ///
811  /// Read an undirected graph from an input stream.
812  /// \param is The input stream.
813  /// \param g The graph.
814  template<typename Graph>
815  void readUndirGraph(std::istream& is, Graph &g) {
816    UndirGraphReader<Graph> reader(is, g);
817    reader.run();
818  }
819
820  /// \brief Read an undirected multigraph (undirected graph + capacity
821  /// map on the edges) from an input stream.
822  ///
823  /// Read an undirected multigraph (undirected graph + capacity
824  /// map on the edges) from an input stream.
825  /// \param is The input stream.
826  /// \param g The graph.
827  /// \param capacity The capacity map.
828  template<typename Graph, typename CapacityMap>
829  void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
830    UndirGraphReader<Graph> reader(is, g);
831    reader.readUndirEdgeMap("capacity", capacity);
832    reader.run();
833  }
834
835
836  /// @}
837}
838
839#endif
Note: See TracBrowser for help on using the repository browser.