COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_reader.h @ 1440:3d2e3cfb2a6c

Last change on this file since 1440:3d2e3cfb2a6c was 1435:8e85e6bbefdf, checked in by Akos Ladanyi, 19 years ago

trunk/src/* move to trunk/

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