COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_reader.h @ 2025:93fcadf94ab0

Last change on this file since 2025:93fcadf94ab0 was 1956:a055123339d5, checked in by Alpar Juttner, 18 years ago

Unified copyright notices

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