COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_reader.h @ 1534:b86aad11f842

Last change on this file since 1534:b86aad11f842 was 1534:b86aad11f842, checked in by athos, 14 years ago

Doc.

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