COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_reader.h @ 1933:a876a3d6a4c7

Last change on this file since 1933:a876a3d6a4c7 was 1909:2d806130e700, checked in by Mihaly Barasz, 18 years ago

Undir -> U transition

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