COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_reader.h @ 1891:56a718d144c4

Last change on this file since 1891:56a718d144c4 was 1875:98698b69a902, checked in by Alpar Juttner, 18 years ago

Happy new year to LEMON

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