COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_reader.h @ 1523:144ab0e4b09c

Last change on this file since 1523:144ab0e4b09c was 1476:182da222fceb, checked in by Balazs Dezso, 19 years ago

Some bug fix.

Added: Concept check for maps and IdReader/Writer? classes

Some runtime check

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      return *this;
265    }
266
267    /// \brief Add a new attribute reader command.
268    ///
269    ///  Add a new attribute reader command.
270    template <typename Value>
271    GraphReader& readAttribute(std::string name, Value& value) {
272      attribute_reader.readAttribute(name, value);
273      return *this;
274    }
275   
276    /// \brief Add a new attribute reader command.
277    ///
278    ///  Add a new attribute reader command.
279    template <typename Reader, typename Value>
280    GraphReader& readAttribute(std::string name, Value& value,
281                               const Reader& reader) {
282      attribute_reader.readAttribute<Reader>(name, value, reader);
283      return *this;
284    }
285
286    /// \brief Conversion operator to LemonReader.
287    ///
288    /// Conversion operator to LemonReader. It make possible
289    /// to access the encapsulated \e LemonReader, this way
290    /// you can attach to this reader new instances of
291    /// \e LemonReader::SectionReader.
292    operator LemonReader&() {
293      return *reader;
294    }
295
296    /// \brief Executes the reader commands.
297    ///
298    /// Executes the reader commands.
299    void run() {
300      reader->run();
301    }
302
303    /// \brief Gives back the node by its id.
304    ///
305    /// It reads an id from the stream and gives back which node belongs to
306    /// it. It is possible only if there was read an "id" named node map.
307    Node readId(std::istream& is, Node) const {
308      return nodeset_reader.readId(is, Node());
309    }
310
311    /// \brief Gives back the edge by its id.
312    ///
313    /// It reads an id from the stream and gives back which edge belongs to
314    /// it. It is possible only if there was read an "id" named edge map.
315    Edge readId(std::istream& is, Edge) const {
316      return edgeset_reader.readId(is, Edge());
317    }
318
319  private:
320
321    LemonReader* reader;
322    bool own_reader;
323
324    DefaultSkipper skipper;
325
326    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
327    EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
328
329    NodeReader<Graph> node_reader;
330    EdgeReader<Graph> edge_reader;
331   
332    AttributeReader<ReaderTraits> attribute_reader;
333  };
334
335  /// \brief Read a graph from the input.
336  ///
337  /// Read a graph from the input.
338  /// \param is The input stream.
339  /// \param g The graph.
340  /// \param capacity The capacity map.
341  /// \param s The source node.
342  /// \param t The target node.
343  /// \param cost The cost map.
344  template<typename Graph, typename CapacityMap, typename CostMap>
345  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
346                  typename Graph::Node &s, typename Graph::Node &t,
347                  CostMap& cost) {
348    GraphReader<Graph> reader(is, g);
349    reader.readEdgeMap("capacity", capacity);
350    reader.readEdgeMap("cost", cost);
351    reader.readNode("source", s);
352    reader.readNode("target", t);
353    reader.run();
354  }
355
356  /// \brief Read a graph from the input.
357  ///
358  /// Read a graph from the input.
359  /// \param is The input stream.
360  /// \param g The graph.
361  /// \param capacity The capacity map.
362  /// \param s The source node.
363  /// \param t The target node.
364  template<typename Graph, typename CapacityMap>
365  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
366                  typename Graph::Node &s, typename Graph::Node &t) {
367    GraphReader<Graph> reader(is, g);
368    reader.readEdgeMap("capacity", capacity);
369    reader.readNode("source", s);
370    reader.readNode("target", t);
371    reader.run();
372  }
373
374  /// \brief Read a graph from the input.
375  ///
376  /// Read a graph from the input.
377  /// \param is The input stream.
378  /// \param g The graph.
379  /// \param capacity The capacity map.
380  /// \param s The source node.
381  template<typename Graph, typename CapacityMap>
382  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
383                  typename Graph::Node &s) {
384    GraphReader<Graph> reader(is, g);
385    reader.readEdgeMap("capacity", capacity);
386    reader.readNode("source", s);
387    reader.run();
388  }
389
390  /// \brief Read a graph from the input.
391  ///
392  /// Read a graph from the input.
393  /// \param is The input stream.
394  /// \param g The graph.
395  /// \param capacity The capacity map.
396  template<typename Graph, typename CapacityMap>
397  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
398    GraphReader<Graph> reader(is, g);
399    reader.readEdgeMap("capacity", capacity);
400    reader.run();
401  }
402
403  /// \brief Read a graph from the input.
404  ///
405  /// Read a graph from the input.
406  /// \param is The input stream.
407  /// \param g The graph.
408  template<typename Graph>
409  void readGraph(std::istream& is, Graph &g) {
410    GraphReader<Graph> reader(is, g);
411    reader.run();
412  }
413
414  /// \brief The undir graph reader class.
415  ///
416  /// The given file format may contain several maps and labeled nodes or
417  /// edges.
418  ///
419  /// If you read a graph you need not read all the maps and items just those
420  /// that you need. The interface of the \c GraphReader is very similar to
421  /// the GraphWriter but the reading method does not depend on the order the
422  /// given commands.
423  ///
424  /// The reader object suppose that each not readed value does not contain
425  /// whitespaces, therefore it has some extra possibilities to control how
426  /// it should skip the values when the string representation contains spaces.
427  ///
428  /// \code
429  /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
430  /// \endcode
431  ///
432  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
433  /// If there is a map that you do not want to read from the file and there is
434  /// whitespace in the string represenation of the values then you should
435  /// call the \c skipNodeMap() template member function with proper
436  /// parameters.
437  ///
438  /// \code
439  /// reader.readNodeMap("coords", coords);
440  ///
441  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
442  /// reader.skipNodeMap<QuotedStringReader>("description");
443  ///
444  /// reader.readNodeMap("color", colorMap);
445  /// \endcode
446  ///
447  /// With the \c readUndirEdgeMap() member function you can give an
448  /// undir edge map reading command similar to the NodeMaps.
449  ///
450  /// \code
451  /// reader.readUndirEdgeMap("capacity", capacityMap);
452  /// \endcode
453  ///
454  /// The reading of the directed edge maps is just a syntactical sugar.
455  /// It reads two undirected edgemaps into a directed edge map. The
456  /// undirected edge maps' name should be start with the \c '+' and the
457  /// \c '-' character and the same.
458  ///
459  /// \code
460  /// reader.readEdgeMap("flow", flowMap);
461  /// \endcode
462  ///
463  /// With \c readNode() and \c readUndirEdge() functions you can read
464  /// labeled Nodes and UndirEdges.
465  ///
466  /// \code
467  /// reader.readNode("source", sourceNode);
468  /// reader.readNode("target", targetNode);
469  ///
470  /// reader.readUndirEdge("observed", undirEdge);
471  /// \endcode
472  ///
473  /// With the \c readAttribute() functions you can read an attribute
474  /// in a variable. You can specify the reader for the attribute as
475  /// the nodemaps.
476  ///
477  /// After you give all read commands you must call the \c run() member
478  /// function, which execute all the commands.
479  ///
480  /// \code
481  /// reader.run();
482  /// \endcode
483  ///
484  /// \see GraphReader
485  /// \see DefaultReaderTraits
486  /// \see \ref UndirGraphWriter
487  /// \see \ref graph-io-page
488  ///
489  /// \author Balazs Dezso
490  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
491  class UndirGraphReader {
492  public:
493   
494    typedef _Graph Graph;
495    typedef typename Graph::Node Node;
496    typedef typename Graph::Edge Edge;
497    typedef typename Graph::UndirEdge UndirEdge;
498
499    typedef _ReaderTraits ReaderTraits;
500    typedef typename ReaderTraits::Skipper DefaultSkipper;
501
502    /// \brief Construct a new UndirGraphReader.
503    ///
504    /// Construct a new UndirGraphReader. It reads into the given graph
505    /// and it use the given reader as the default skipper.
506    UndirGraphReader(std::istream& _is, Graph& _graph,
507                     const DefaultSkipper& _skipper = DefaultSkipper())
508      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
509        nodeset_reader(*reader, _graph, std::string(), skipper),
510        undir_edgeset_reader(*reader, _graph, nodeset_reader,
511                             std::string(), skipper),
512        node_reader(*reader, nodeset_reader, std::string()),
513        undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
514        attribute_reader(*reader, std::string()) {}
515
516    /// \brief Construct a new UndirGraphReader.
517    ///
518    /// Construct a new UndirGraphReader. It reads into the given graph
519    /// and it use the given reader as the default skipper.
520    UndirGraphReader(const std::string& _filename, Graph& _graph,
521                     const DefaultSkipper& _skipper = DefaultSkipper())
522      : reader(new LemonReader(_filename)), own_reader(true),
523        skipper(_skipper),
524        nodeset_reader(*reader, _graph, std::string(), skipper),
525        undir_edgeset_reader(*reader, _graph, nodeset_reader,
526                             std::string(), skipper),
527        node_reader(*reader, nodeset_reader, std::string()),
528        undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
529        attribute_reader(*reader, std::string()) {}
530
531    /// \brief Construct a new UndirGraphReader.
532    ///
533    /// Construct a new UndirGraphReader. It reads into the given graph
534    /// and it use the given reader as the default skipper.
535    UndirGraphReader(LemonReader& _reader, Graph& _graph,
536                     const DefaultSkipper& _skipper = DefaultSkipper())
537      : reader(_reader), own_reader(false), skipper(_skipper),
538        nodeset_reader(*reader, _graph, std::string(), skipper),
539        undir_edgeset_reader(*reader, _graph, nodeset_reader,
540                             std::string(), skipper),
541        node_reader(*reader, nodeset_reader, std::string()),
542        undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
543        attribute_reader(*reader, std::string()) {}
544
545    /// \brief Destruct the graph reader.
546    ///
547    /// Destruct the graph reader.
548    ~UndirGraphReader() {
549      if (own_reader)
550        delete reader;
551    }
552
553    /// \brief Add a new node map reader command for the reader.
554    ///
555    /// Add a new node map reader command for the reader.
556    template <typename Map>
557    UndirGraphReader& readNodeMap(std::string name, Map& map) {
558      nodeset_reader.readNodeMap(name, map);
559      return *this;
560    }
561
562    template <typename Map>
563    UndirGraphReader& readNodeMap(std::string name, const Map& map) {
564      nodeset_reader.readNodeMap(name, map);
565      return *this;
566    }
567
568    /// \brief Add a new node map reader command for the reader.
569    ///
570    /// Add a new node map reader command for the reader.
571    template <typename Reader, typename Map>
572    UndirGraphReader& readNodeMap(std::string name, Map& map,
573                                  const Reader& reader = Reader()) {
574      nodeset_reader.readNodeMap(name, map, reader);
575      return *this;
576    }
577
578    template <typename Reader, typename Map>
579    UndirGraphReader& readNodeMap(std::string name, const Map& map,
580                                  const Reader& reader = Reader()) {
581      nodeset_reader.readNodeMap(name, map, reader);
582      return *this;
583    }
584
585    /// \brief Add a new node map skipper command for the reader.
586    ///
587    /// Add a new node map skipper command for the reader.
588    template <typename Reader>
589    UndirGraphReader& skipNodeMap(std::string name,
590                             const Reader& reader = Reader()) {
591      nodeset_reader.skipNodeMap(name, reader);
592      return *this;
593    }
594
595    /// \brief Add a new undirected edge map reader command for the reader.
596    ///
597    /// Add a new undirected edge map reader command for the reader.
598    template <typename Map>
599    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
600      undir_edgeset_reader.readUndirEdgeMap(name, map);
601      return *this;
602    }
603
604    template <typename Map>
605    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
606      undir_edgeset_reader.readUndirEdgeMap(name, map);
607      return *this;
608    }
609
610
611    /// \brief Add a new undirected edge map reader command for the reader.
612    ///
613    /// Add a new undirected edge map reader command for the reader.
614    template <typename Reader, typename Map>
615    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
616                                       const Reader& reader = Reader()) {
617      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
618      return *this;
619    }
620
621    template <typename Reader, typename Map>
622    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
623                                       const Reader& reader = Reader()) {
624      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
625      return *this;
626    }
627
628    /// \brief Add a new undirected edge map skipper command for the reader.
629    ///
630    /// Add a new undirected edge map skipper command for the reader.
631    template <typename Reader>
632    UndirGraphReader& skipUndirEdgeMap(std::string name,
633                                       const Reader& reader = Reader()) {
634      undir_edgeset_reader.skipUndirMap(name, reader);
635      return *this;
636    }
637
638
639    /// \brief Add a new edge map reader command for the reader.
640    ///
641    /// Add a new edge map reader command for the reader.
642    template <typename Map>
643    UndirGraphReader& readEdgeMap(std::string name, Map& map) {
644      undir_edgeset_reader.readEdgeMap(name, map);
645      return *this;
646    }
647
648    template <typename Map>
649    UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
650      undir_edgeset_reader.readEdgeMap(name, map);
651      return *this;
652    }
653
654
655    /// \brief Add a new edge map reader command for the reader.
656    ///
657    /// Add a new edge map reader command for the reader.
658    template <typename Reader, typename Map>
659    UndirGraphReader& readEdgeMap(std::string name, Map& map,
660                                       const Reader& reader = Reader()) {
661      undir_edgeset_reader.readEdgeMap(name, map, reader);
662      return *this;
663    }
664
665    template <typename Reader, typename Map>
666    UndirGraphReader& readEdgeMap(std::string name, const Map& map,
667                                       const Reader& reader = Reader()) {
668      undir_edgeset_reader.readEdgeMap(name, map, reader);
669      return *this;
670    }
671
672    /// \brief Add a new edge map skipper command for the reader.
673    ///
674    /// Add a new edge map skipper command for the reader.
675    template <typename Reader>
676    UndirGraphReader& skipEdgeMap(std::string name,
677                                       const Reader& reader = Reader()) {
678      undir_edgeset_reader.skipEdgeMap(name, reader);
679      return *this;
680    }
681
682    /// \brief Add a new labeled node reader for the reader.
683    ///
684    /// Add a new labeled node reader for the reader.
685    UndirGraphReader& readNode(std::string name, Node& node) {
686      node_reader.readNode(name, node);
687      return *this;
688    }
689
690    /// \brief Add a new labeled edge reader for the reader.
691    ///
692    /// Add a new labeled edge reader for the reader.
693    UndirGraphReader& readEdge(std::string name, Edge& edge) {
694      undir_edge_reader.readEdge(name, edge);
695    }
696
697    /// \brief Add a new labeled undirected edge reader for the reader.
698    ///
699    /// Add a new labeled undirected edge reader for the reader.
700    UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
701      undir_edge_reader.readUndirEdge(name, edge);
702    }
703
704    /// \brief Add a new attribute reader command.
705    ///
706    ///  Add a new attribute reader command.
707    template <typename Value>
708    UndirGraphReader& readAttribute(std::string name, Value& value) {
709      attribute_reader.readAttribute(name, value);
710      return *this;
711    }
712   
713    /// \brief Add a new attribute reader command.
714    ///
715    ///  Add a new attribute reader command.
716    template <typename Reader, typename Value>
717    UndirGraphReader& readAttribute(std::string name, Value& value,
718                               const Reader& reader) {
719      attribute_reader.readAttribute<Reader>(name, value, reader);
720      return *this;
721    }
722
723    /// \brief Conversion operator to LemonReader.
724    ///
725    /// Conversion operator to LemonReader. It make possible
726    /// to access the encapsulated \e LemonReader, this way
727    /// you can attach to this reader new instances of
728    /// \e LemonReader::SectionReader.
729    operator LemonReader&() {
730      return *reader;
731    }
732
733    /// \brief Executes the reader commands.
734    ///
735    /// Executes the reader commands.
736    void run() {
737      reader->run();
738    }
739
740    /// \brief Gives back the node by its id.
741    ///
742    /// It reads an id from the stream and gives back which node belongs to
743    /// it. It is possible only if there was read an "id" named node map.
744    Node readId(std::istream& is, Node) const {
745      return nodeset_reader.readId(is, Node());
746    }
747
748    /// \brief Gives back the edge by its id.
749    ///
750    /// It reads an id from the stream and gives back which edge belongs to
751    /// it. It is possible only if there was read an "id" named edge map.
752    Edge readId(std::istream& is, Edge) const {
753      return undir_edgeset_reader.readId(is, Edge());
754    }
755
756    /// \brief Gives back the undirected edge by its id.
757    ///
758    /// It reads an id from the stream and gives back which undirected edge
759    /// belongs to it. It is possible only if there was read an "id" named
760    /// edge map.
761    UndirEdge readId(std::istream& is, UndirEdge) const {
762      return undir_edgeset_reader.readId(is, UndirEdge());
763    }
764   
765
766  private:
767
768    LemonReader* reader;
769    bool own_reader;
770
771    DefaultSkipper skipper;
772
773    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
774    UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
775
776    NodeReader<Graph> node_reader;
777    UndirEdgeReader<Graph> undir_edge_reader;
778   
779    AttributeReader<ReaderTraits> attribute_reader;
780  };
781
782  /// \brief Read an undir graph from the input.
783  ///
784  /// Read an undir graph from the input.
785  /// \param is The input stream.
786  /// \param g The graph.
787  /// \param capacity The capacity map.
788  template<typename Graph, typename CapacityMap>
789  void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
790    UndirGraphReader<Graph> reader(is, g);
791    reader.readUndirEdgeMap("capacity", capacity);
792    reader.run();
793  }
794
795  /// \brief Read an undir graph from the input.
796  ///
797  /// Read an undir graph from the input.
798  /// \param is The input stream.
799  /// \param g The graph.
800  template<typename Graph>
801  void readUndirGraph(std::istream& is, Graph &g) {
802    UndirGraphReader<Graph> reader(is, g);
803    reader.run();
804  }
805
806  /// @}
807}
808
809#endif
Note: See TracBrowser for help on using the repository browser.