COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/graph_reader.h @ 1427:14c75970840e

Last change on this file since 1427:14c75970840e was 1421:7a21e1414c38, checked in by Balazs Dezso, 19 years ago

IO with undirected edgesets and undirected graphs.
Missing features:

InfoReader?,
aliased edges in undir edgesets

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