deba@1137: /* -*- C++ -*-
deba@1137:  *
alpar@1956:  * This file is a part of LEMON, a generic C++ optimization library
alpar@1956:  *
alpar@1956:  * Copyright (C) 2003-2006
alpar@1956:  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1137:  *
deba@1137:  * Permission to use, modify and distribute this software is granted
deba@1137:  * provided that this copyright notice appears in all copies. For
deba@1137:  * precise terms see the accompanying LICENSE file.
deba@1137:  *
deba@1137:  * This software is provided "AS IS" with no warranty of any kind,
deba@1137:  * express or implied, and with no claim as to its suitability for any
deba@1137:  * purpose.
deba@1137:  *
deba@1137:  */
deba@1137: 
deba@2084: ///\ingroup lemon_io
deba@1137: ///\file
alpar@1287: ///\brief Lemon Graph Format reader.
deba@1137: 
deba@1214: #ifndef LEMON_GRAPH_READER_H
deba@1214: #define LEMON_GRAPH_READER_H
deba@1214: 
deba@1137: #include <iostream>
deba@1137: 
deba@1137: #include <lemon/error.h>
deba@1408: #include <lemon/lemon_reader.h>
deba@1137: 
deba@1137: namespace lemon {
deba@1137: 
deba@2084:   /// \addtogroup lemon_io
deba@1333:   /// @{
deba@1137: 
deba@1137:   /// \brief The graph reader class.
deba@1137:   ///
athos@1534:   /// The \c GraphReader class provides the graph input. 
athos@1534:   /// Before you read this documentation it might be useful to read the general
athos@1534:   /// description of  \ref graph-io-page "Graph Input-Output".
athos@1540:   ///
athos@1540:   /// The file to be read may contain several maps and labeled nodes or 
deba@1333:   /// edges.
deba@1333:   ///
deba@1333:   /// If you read a graph you need not read all the maps and items just those
deba@1333:   /// that you need. The interface of the \c GraphReader is very similar to
deba@1333:   /// the GraphWriter but the reading method does not depend on the order the
athos@1540:   /// given commands (i.e. you don't have to insist on the order in which the
athos@1540:   /// maps are given in the file).
deba@1333:   ///
deba@2100:   /// The reader object assumes that not read values do not contain 
deba@1333:   /// whitespaces, therefore it has some extra possibilities to control how
deba@1333:   /// it should skip the values when the string representation contains spaces.
deba@1333:   ///
alpar@1946:   ///\code
deba@1333:   /// GraphReader<ListGraph> reader(std::cin, graph);
alpar@1946:   ///\endcode
deba@1333:   ///
deba@1394:   /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
deba@1333:   /// If there is a map that you do not want to read from the file and there is
deba@1333:   /// whitespace in the string represenation of the values then you should
deba@1333:   /// call the \c skipNodeMap() template member function with proper 
deba@1333:   /// parameters.
deba@1333:   ///
alpar@1946:   ///\code
deba@1421:   /// reader.readNodeMap("coords", coords);
deba@1333:   ///
deba@1901:   /// reader.skipNodeMap("description", desc);
deba@1333:   ///
deba@1394:   /// reader.readNodeMap("color", colorMap);
alpar@1946:   ///\endcode
deba@1333:   ///
deba@1394:   /// With the \c readEdgeMap() member function you can give an edge map
deba@1333:   /// reading command similar to the NodeMaps. 
deba@1333:   ///
alpar@1946:   ///\code
deba@1394:   /// reader.readEdgeMap("weight", weightMap);
deba@1394:   /// reader.readEdgeMap("label", labelMap);
alpar@1946:   ///\endcode
deba@1333:   ///
deba@1408:   /// With \c readNode() and \c readEdge() functions you can read 
deba@1408:   /// labeled Nodes and Edges.
deba@1333:   ///
alpar@1946:   ///\code
deba@1394:   /// reader.readNode("source", sourceNode);
deba@1394:   /// reader.readNode("target", targetNode);
deba@1333:   ///
deba@1394:   /// reader.readEdge("observed", edge);
alpar@1946:   ///\endcode
deba@1333:   ///
deba@1408:   /// With the \c readAttribute() functions you can read an attribute
athos@1540:   /// into a variable. You can specify the reader for the attribute as
deba@1408:   /// the nodemaps.
deba@1408:   ///
deba@1333:   /// After you give all read commands you must call the \c run() member
athos@1540:   /// function, which executes all the commands.
deba@1333:   ///
alpar@1946:   ///\code
deba@1333:   /// reader.run();
alpar@1946:   ///\endcode
deba@1333:   ///
alpar@1287:   /// \see DefaultReaderTraits
alpar@1287:   /// \see QuotedStringReader
alpar@1138:   /// \see \ref GraphWriter
alpar@1138:   /// \see \ref graph-io-page
deba@1333:   /// \author Balazs Dezso
deba@1137:   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
deba@1137:   class GraphReader {
deba@1137:   public:
deba@1137:     
deba@1137:     typedef _Graph Graph;
deba@1137:     typedef typename Graph::Node Node;
deba@1137:     typedef typename Graph::Edge Edge;
deba@1137: 
deba@1137:     typedef _ReaderTraits ReaderTraits;
deba@1408:     typedef typename ReaderTraits::Skipper DefaultSkipper;
deba@1137: 
deba@1137:     /// \brief Construct a new GraphReader.
deba@1137:     ///
deba@1208:     /// Construct a new GraphReader. It reads into the given graph
athos@1540:     /// and it uses the given reader as the default skipper.
deba@1705:     GraphReader(std::istream& _is, Graph& _graph, 
deba@1408: 		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421:       : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
deba@1421: 	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421: 	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421: 		       std::string(), skipper),
deba@1408: 	node_reader(*reader, nodeset_reader, std::string()),
deba@1408: 	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408: 	attribute_reader(*reader, std::string()) {}
deba@1408: 
deba@1408:     /// \brief Construct a new GraphReader.
deba@1408:     ///
deba@1408:     /// Construct a new GraphReader. It reads into the given graph
athos@1540:     /// and it uses the given reader as the default skipper.
deba@1705:     GraphReader(const std::string& _filename, Graph& _graph, 
deba@1408: 		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1408:       : reader(new LemonReader(_filename)), own_reader(true), 
deba@1421: 	skipper(_skipper),
deba@1421: 	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421: 	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421: 		       std::string(), skipper),
deba@1408: 	node_reader(*reader, nodeset_reader, std::string()),
deba@1408: 	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408: 	attribute_reader(*reader, std::string()) {}
deba@1408: 
deba@1408:     /// \brief Construct a new GraphReader.
deba@1408:     ///
deba@1408:     /// Construct a new GraphReader. It reads into the given graph
athos@1540:     /// and it uses the given reader as the default skipper.
deba@1705:     GraphReader(LemonReader& _reader, Graph& _graph, 
deba@1408: 		const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421:       : reader(_reader), own_reader(false), skipper(_skipper),
deba@1421: 	nodeset_reader(*reader, _graph, std::string(), skipper),
deba@1421: 	edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421: 		       std::string(), skipper),
deba@1408: 	node_reader(*reader, nodeset_reader, std::string()),
deba@1408: 	edge_reader(*reader, edgeset_reader, std::string()),
deba@1408: 	attribute_reader(*reader, std::string()) {}
deba@1137: 
deba@1137:     /// \brief Destruct the graph reader.
deba@1137:     ///
deba@1137:     /// Destruct the graph reader.
deba@1137:     ~GraphReader() {
deba@1408:       if (own_reader) 
deba@1408: 	delete reader;
deba@1137:     }
deba@1137: 
athos@1540:     /// \brief Give a new node map reading command to the reader.
deba@1137:     ///
athos@1540:     /// Give a new node map reading command to the reader.
deba@1137:     template <typename Map>
deba@1394:     GraphReader& readNodeMap(std::string name, Map& map) {
deba@1421:       nodeset_reader.readNodeMap(name, map);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Map>
deba@1421:     GraphReader& readNodeMap(std::string name, const Map& map) {
deba@1421:       nodeset_reader.readNodeMap(name, map);
deba@1408:       return *this;
deba@1137:     }
deba@1137: 
athos@1540:     /// \brief Give a new node map reading command to the reader.
deba@1137:     ///
athos@1540:     /// Give a new node map reading command to the reader.
deba@1137:     template <typename Reader, typename Map>
deba@1394:     GraphReader& readNodeMap(std::string name, Map& map, 
deba@1137: 			     const Reader& reader = Reader()) {
deba@1421:       nodeset_reader.readNodeMap(name, map, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Reader, typename Map>
deba@1421:     GraphReader& readNodeMap(std::string name, const Map& map, 
deba@1421: 			     const Reader& reader = Reader()) {
deba@1421:       nodeset_reader.readNodeMap(name, map, reader);
deba@1137:       return *this;
deba@1137:     }
deba@1137: 
athos@1540:     /// \brief Give a new node map skipping command to the reader.
deba@1137:     ///
athos@1540:     /// Give a new node map skipping command to the reader.
deba@1137:     template <typename Reader>
deba@1137:     GraphReader& skipNodeMap(std::string name, 
deba@1137: 			     const Reader& reader = Reader()) {
deba@1421:       nodeset_reader.skipNodeMap(name, reader);
deba@1137:       return *this;
deba@1137:     }
deba@1137: 
athos@1540:     /// \brief Give a new edge map reading command to the reader.
deba@1137:     ///
athos@1540:     /// Give a new edge map reading command to the reader.
deba@1137:     template <typename Map>
deba@1394:     GraphReader& readEdgeMap(std::string name, Map& map) { 
deba@1421:       edgeset_reader.readEdgeMap(name, map);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Map>
deba@1421:     GraphReader& readEdgeMap(std::string name, const Map& map) { 
deba@1421:       edgeset_reader.readEdgeMap(name, map);
deba@1408:       return *this;
deba@1137:     }
deba@1137: 
deba@1137: 
athos@1540:     /// \brief Give a new edge map reading command to the reader.
deba@1137:     ///
athos@1540:     /// Give a new edge map reading command to the reader.
deba@1137:     template <typename Reader, typename Map>
deba@1394:     GraphReader& readEdgeMap(std::string name, Map& map,
deba@1137: 			     const Reader& reader = Reader()) {
deba@1421:       edgeset_reader.readEdgeMap(name, map, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Reader, typename Map>
deba@1421:     GraphReader& readEdgeMap(std::string name, const Map& map,
deba@1421: 			     const Reader& reader = Reader()) {
deba@1421:       edgeset_reader.readEdgeMap(name, map, reader);
deba@1137:       return *this;
deba@1137:     }
deba@1137: 
athos@1540:     /// \brief Give a new edge map skipping command to the reader.
deba@1137:     ///
athos@1540:     /// Give a new edge map skipping command to the reader.
deba@1137:     template <typename Reader>
deba@1421:     GraphReader& skipEdgeMap(std::string name, 
deba@1137: 			     const Reader& reader = Reader()) {
deba@1421:       edgeset_reader.skipEdgeMap(name, reader);
deba@1137:       return *this;
deba@1137:     }
deba@1137: 
athos@1540:     /// \brief Give a new labeled node reading command to the reader.
deba@1137:     ///
athos@1540:     /// Give a new labeled node reading command to the reader.
deba@1394:     GraphReader& readNode(std::string name, Node& node) {
deba@1408:       node_reader.readNode(name, node);
deba@1137:       return *this;
deba@1137:     }
deba@1137: 
athos@1540:     /// \brief Give a new labeled edge reading command to the reader.
deba@1137:     ///
athos@1540:     /// Give a new labeled edge reading command to the reader.
deba@1394:     GraphReader& readEdge(std::string name, Edge& edge) {
deba@1408:       edge_reader.readEdge(name, edge);
deba@1476:       return *this;
deba@1408:     }
deba@1408: 
athos@1540:     /// \brief Give a new attribute reading command.
deba@1408:     ///
athos@1540:     ///  Give a new attribute reading command.
deba@1408:     template <typename Value>
deba@1408:     GraphReader& readAttribute(std::string name, Value& value) {
deba@1408:       attribute_reader.readAttribute(name, value);
deba@1137:       return *this;
deba@1137:     }
deba@1408:     
athos@1540:     /// \brief Give a new attribute reading command.
deba@1408:     ///
athos@1540:     ///  Give a new attribute reading command.
deba@1408:     template <typename Reader, typename Value>
deba@1408:     GraphReader& readAttribute(std::string name, Value& value, 
deba@1408: 			       const Reader& reader) {
deba@1408:       attribute_reader.readAttribute<Reader>(name, value, reader);
deba@1408:       return *this;
deba@1408:     }
deba@1408: 
deba@1408:     /// \brief Conversion operator to LemonReader.
deba@1408:     ///
athos@1540:     /// Conversion operator to LemonReader. It makes possible to access the
athos@1540:     /// encapsulated \e LemonReader, this way you can attach to this reader
athos@1540:     /// new instances of \e LemonReader::SectionReader. For more details see
athos@1540:     /// the \ref rwbackground "Background of Reading and Writing".
deba@1408:     operator LemonReader&() {
deba@1408:       return *reader;
deba@1408:     }
deba@1137: 
athos@1540:     /// \brief Executes the reading commands.
deba@1137:     ///
athos@1540:     /// Executes the reading commands.
deba@1137:     void run() {
deba@1408:       reader->run();
deba@1396:     }
deba@1396: 
deba@1901: 
deba@1901:     /// \brief Returns true if the reader can give back the items by its label.
deba@1429:     ///
deba@1901:     /// \brief Returns true if the reader can give back the items by its label.
deba@1901:     bool isLabelReader() const {
deba@1901:       return nodeset_reader.isLabelReader() && edgeset_reader.isLabelReader();
deba@1901:     }
deba@1901: 
deba@1901:     /// \brief Gives back the node by its label.
deba@1901:     ///
deba@1901:     /// It reads an label from the stream and gives back which node belongs to
alpar@1935:     /// it. It is possible only if there was read a "label" named node map.
deba@1901:     void readLabel(std::istream& is, Node& node) const {
deba@1901:       nodeset_reader.readLabel(is, node);
deba@1429:     } 
deba@1429: 
deba@1901:     /// \brief Gives back the edge by its label.
deba@1429:     ///
deba@1901:     /// It reads an label from the stream and gives back which edge belongs to
alpar@1935:     /// it. It is possible only if there was read a "label" named edge map.
deba@1901:     void readLabel(std::istream& is, Edge& edge) const {
deba@1901:       return edgeset_reader.readLabel(is, edge);
deba@1429:     } 
deba@1429: 
deba@1137:   private:
deba@1137: 
deba@1408:     LemonReader* reader;
deba@1408:     bool own_reader;
deba@1137: 
deba@1408:     DefaultSkipper skipper;
deba@1137: 
deba@1408:     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
deba@1408:     EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
deba@1408: 
deba@1408:     NodeReader<Graph> node_reader;
deba@1408:     EdgeReader<Graph> edge_reader;
deba@1408:     
deba@1408:     AttributeReader<ReaderTraits> attribute_reader;
deba@1137:   };
deba@1137: 
athos@1534: 
deba@1744:   /// \brief Read a graph from the input.
deba@1333:   ///
deba@1744:   /// It is a helper function to read a graph from the given input
deba@1744:   /// stream. It gives back an GraphReader object and this object
deba@1744:   /// can read more maps, labeled nodes, edges and attributes.
athos@1534:   ///
deba@1744:   /// \warning Do not forget to call the \c run() function.
deba@1744:   ///
athos@1534:   /// \param is The input stream.
athos@1534:   /// \param g The graph.
athos@1534:   template<typename Graph>
deba@1744:   GraphReader<Graph> graphReader(std::istream& is, Graph &g) {
deba@1744:     return GraphReader<Graph>(is, g);
athos@1534:   }
athos@1534: 
deba@1744:   /// \brief Read a graph from the input.
deba@1744:   ///
deba@1744:   /// It is a helper function to read a graph from the given input
deba@1744:   /// file. It gives back an GraphReader object and this object
deba@1744:   /// can read more maps, labeled nodes, edges and attributes.
deba@1744:   ///
deba@1744:   /// \warning Do not forget to call the \c run() function.
deba@1744:   ///
deba@1744:   /// \param fn The input filename.
athos@1534:   /// \param g The graph.
deba@1744:   template<typename Graph>
deba@1744:   GraphReader<Graph> graphReader(const std::string& fn, Graph &g) {
deba@1744:     return GraphReader<Graph>(fn, g);
athos@1534:   }
athos@1534: 
deba@1744:   /// \brief The undirected graph reader class.
deba@1421:   ///
klao@1909:   /// The \c UGraphReader class provides the graph input. 
athos@1540:   /// Before you read this documentation it might be useful to read the general
athos@1540:   /// description of  \ref graph-io-page "Graph Input-Output".
athos@1540:   ///
deba@1421:   /// The given file format may contain several maps and labeled nodes or 
deba@1421:   /// edges.
deba@1421:   ///
deba@1421:   /// If you read a graph you need not read all the maps and items just those
klao@1909:   /// that you need. The interface of the \c UGraphReader is very similar
klao@1909:   /// to the UGraphWriter but the reading method does not depend on the
athos@1540:   /// order of the given commands.
deba@1421:   ///
deba@2100:   /// The reader object suppose that each not read value does not contain 
deba@1421:   /// whitespaces, therefore it has some extra possibilities to control how
deba@1421:   /// it should skip the values when the string representation contains spaces.
deba@1421:   ///
alpar@1946:   ///\code
klao@1909:   /// UGraphReader<ListUGraph> reader(std::cin, graph);
alpar@1946:   ///\endcode
deba@1421:   ///
deba@1421:   /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
deba@1421:   /// If there is a map that you do not want to read from the file and there is
deba@1421:   /// whitespace in the string represenation of the values then you should
deba@1421:   /// call the \c skipNodeMap() template member function with proper 
deba@1421:   /// parameters.
deba@1421:   ///
alpar@1946:   ///\code
deba@1421:   /// reader.readNodeMap("coords", coords);
deba@1421:   ///
deba@1901:   /// reader.skipNodeMap("description", desc);
deba@1421:   ///
deba@1421:   /// reader.readNodeMap("color", colorMap);
alpar@1946:   ///\endcode
deba@1421:   ///
klao@1909:   /// With the \c readUEdgeMap() member function you can give an 
klao@1909:   /// uedge map reading command similar to the NodeMaps. 
deba@1421:   ///
alpar@1946:   ///\code
klao@1909:   /// reader.readUEdgeMap("capacity", capacityMap);
alpar@1946:   ///\endcode
deba@1421:   ///
deba@1421:   /// The reading of the directed edge maps is just a syntactical sugar.
deba@1421:   /// It reads two undirected edgemaps into a directed edge map. The 
deba@1421:   /// undirected edge maps' name should be start with the \c '+' and the
deba@1421:   /// \c '-' character and the same.
deba@1421:   ///
alpar@1946:   ///\code
deba@1421:   /// reader.readEdgeMap("flow", flowMap);
alpar@1946:   ///\endcode 
deba@1421:   ///
klao@1909:   /// With \c readNode() and \c readUEdge() functions you can read 
klao@1909:   /// labeled Nodes and UEdges.
deba@1421:   ///
alpar@1946:   ///\code
deba@1421:   /// reader.readNode("source", sourceNode);
deba@1421:   /// reader.readNode("target", targetNode);
deba@1421:   ///
klao@1909:   /// reader.readUEdge("observed", uEdge);
alpar@1946:   ///\endcode
deba@1421:   ///
deba@1421:   /// With the \c readAttribute() functions you can read an attribute
deba@1421:   /// in a variable. You can specify the reader for the attribute as
deba@1421:   /// the nodemaps.
deba@1421:   ///
deba@1421:   /// After you give all read commands you must call the \c run() member
deba@1421:   /// function, which execute all the commands.
deba@1421:   ///
alpar@1946:   ///\code
deba@1421:   /// reader.run();
alpar@1946:   ///\endcode
deba@1421:   ///
deba@1421:   /// \see GraphReader
deba@1421:   /// \see DefaultReaderTraits
klao@1909:   /// \see \ref UGraphWriter
deba@1421:   /// \see \ref graph-io-page
deba@1421:   ///
deba@1421:   /// \author Balazs Dezso
deba@1421:   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
klao@1909:   class UGraphReader {
deba@1421:   public:
deba@1421:     
deba@1421:     typedef _Graph Graph;
deba@1421:     typedef typename Graph::Node Node;
deba@1421:     typedef typename Graph::Edge Edge;
klao@1909:     typedef typename Graph::UEdge UEdge;
deba@1421: 
deba@1421:     typedef _ReaderTraits ReaderTraits;
deba@1421:     typedef typename ReaderTraits::Skipper DefaultSkipper;
deba@1421: 
klao@1909:     /// \brief Construct a new UGraphReader.
deba@1421:     ///
klao@1909:     /// Construct a new UGraphReader. It reads into the given graph
deba@1421:     /// and it use the given reader as the default skipper.
klao@1909:     UGraphReader(std::istream& _is, Graph& _graph, 
deba@1421: 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421:       : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
deba@1421: 	nodeset_reader(*reader, _graph, std::string(), skipper),
klao@1909: 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421: 			     std::string(), skipper),
deba@1421: 	node_reader(*reader, nodeset_reader, std::string()),
klao@1909: 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
deba@1421: 	attribute_reader(*reader, std::string()) {}
deba@1421: 
klao@1909:     /// \brief Construct a new UGraphReader.
deba@1421:     ///
klao@1909:     /// Construct a new UGraphReader. It reads into the given graph
deba@1421:     /// and it use the given reader as the default skipper.
klao@1909:     UGraphReader(const std::string& _filename, Graph& _graph, 
deba@1421: 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421:       : reader(new LemonReader(_filename)), own_reader(true), 
deba@1421: 	skipper(_skipper),
deba@1421: 	nodeset_reader(*reader, _graph, std::string(), skipper),
klao@1909: 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421: 			     std::string(), skipper),
deba@1421: 	node_reader(*reader, nodeset_reader, std::string()),
klao@1909: 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
deba@1421: 	attribute_reader(*reader, std::string()) {}
deba@1421: 
klao@1909:     /// \brief Construct a new UGraphReader.
deba@1421:     ///
klao@1909:     /// Construct a new UGraphReader. It reads into the given graph
deba@1421:     /// and it use the given reader as the default skipper.
klao@1909:     UGraphReader(LemonReader& _reader, Graph& _graph, 
deba@1421: 		     const DefaultSkipper& _skipper = DefaultSkipper()) 
deba@1421:       : reader(_reader), own_reader(false), skipper(_skipper),
deba@1421: 	nodeset_reader(*reader, _graph, std::string(), skipper),
klao@1909: 	u_edgeset_reader(*reader, _graph, nodeset_reader, 
deba@1421: 			     std::string(), skipper),
deba@1421: 	node_reader(*reader, nodeset_reader, std::string()),
klao@1909: 	u_edge_reader(*reader, u_edgeset_reader, std::string()),
deba@1421: 	attribute_reader(*reader, std::string()) {}
deba@1421: 
deba@1421:     /// \brief Destruct the graph reader.
deba@1421:     ///
deba@1421:     /// Destruct the graph reader.
klao@1909:     ~UGraphReader() {
deba@1421:       if (own_reader) 
deba@1421: 	delete reader;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new node map reading command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new node map reading command to the reader.
deba@1421:     template <typename Map>
klao@1909:     UGraphReader& readNodeMap(std::string name, Map& map) {
deba@1421:       nodeset_reader.readNodeMap(name, map);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Map>
klao@1909:     UGraphReader& readNodeMap(std::string name, const Map& map) {
deba@1421:       nodeset_reader.readNodeMap(name, map);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new node map reading command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new node map reading command to the reader.
deba@1421:     template <typename Reader, typename Map>
klao@1909:     UGraphReader& readNodeMap(std::string name, Map& map, 
deba@1421: 				  const Reader& reader = Reader()) {
deba@1421:       nodeset_reader.readNodeMap(name, map, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Reader, typename Map>
klao@1909:     UGraphReader& readNodeMap(std::string name, const Map& map, 
deba@1421: 				  const Reader& reader = Reader()) {
deba@1421:       nodeset_reader.readNodeMap(name, map, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new node map skipping command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new node map skipping command to the reader.
deba@1421:     template <typename Reader>
klao@1909:     UGraphReader& skipNodeMap(std::string name, 
deba@1421: 			     const Reader& reader = Reader()) {
deba@1421:       nodeset_reader.skipNodeMap(name, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new undirected edge map reading command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new undirected edge map reading command to the reader.
deba@1421:     template <typename Map>
klao@1909:     UGraphReader& readUEdgeMap(std::string name, Map& map) { 
klao@1909:       u_edgeset_reader.readUEdgeMap(name, map);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Map>
klao@1909:     UGraphReader& readUEdgeMap(std::string name, const Map& map) { 
klao@1909:       u_edgeset_reader.readUEdgeMap(name, map);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421: 
athos@1540:     /// \brief Give a new undirected edge map reading command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new undirected edge map reading command to the reader.
deba@1421:     template <typename Reader, typename Map>
klao@1909:     UGraphReader& readUEdgeMap(std::string name, Map& map,
deba@1421: 				       const Reader& reader = Reader()) {
klao@1909:       u_edgeset_reader.readUEdgeMap(name, map, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Reader, typename Map>
klao@1909:     UGraphReader& readUEdgeMap(std::string name, const Map& map,
deba@1421: 				       const Reader& reader = Reader()) {
klao@1909:       u_edgeset_reader.readUEdgeMap(name, map, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new undirected edge map skipping command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new undirected edge map skipping command to the reader.
deba@1421:     template <typename Reader>
klao@1909:     UGraphReader& skipUEdgeMap(std::string name,
deba@1421: 				       const Reader& reader = Reader()) {
klao@1909:       u_edgeset_reader.skipUMap(name, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421: 
athos@1540:     /// \brief Give a new edge map reading command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new edge map reading command to the reader.
deba@1421:     template <typename Map>
klao@1909:     UGraphReader& readEdgeMap(std::string name, Map& map) { 
klao@1909:       u_edgeset_reader.readEdgeMap(name, map);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Map>
klao@1909:     UGraphReader& readEdgeMap(std::string name, const Map& map) { 
klao@1909:       u_edgeset_reader.readEdgeMap(name, map);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421: 
athos@1540:     /// \brief Give a new edge map reading command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new edge map reading command to the reader.
deba@1421:     template <typename Reader, typename Map>
klao@1909:     UGraphReader& readEdgeMap(std::string name, Map& map,
deba@1421: 				       const Reader& reader = Reader()) {
klao@1909:       u_edgeset_reader.readEdgeMap(name, map, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     template <typename Reader, typename Map>
klao@1909:     UGraphReader& readEdgeMap(std::string name, const Map& map,
deba@1421: 				       const Reader& reader = Reader()) {
klao@1909:       u_edgeset_reader.readEdgeMap(name, map, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new edge map skipping command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new edge map skipping command to the reader.
deba@1421:     template <typename Reader>
klao@1909:     UGraphReader& skipEdgeMap(std::string name,
deba@1421: 				       const Reader& reader = Reader()) {
klao@1909:       u_edgeset_reader.skipEdgeMap(name, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new labeled node reading command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new labeled node reading command to the reader.
klao@1909:     UGraphReader& readNode(std::string name, Node& node) {
deba@1421:       node_reader.readNode(name, node);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new labeled edge reading command to the reader.
deba@1421:     ///
athos@1540:     /// Give a new labeled edge reading command to the reader.
klao@1909:     UGraphReader& readEdge(std::string name, Edge& edge) {
klao@1909:       u_edge_reader.readEdge(name, edge);
deba@1429:     }
deba@1429: 
athos@1540:     /// \brief Give a new labeled undirected edge reading command to the
athos@1540:     /// reader.
deba@1429:     ///
athos@1540:     /// Give a new labeled undirected edge reading command to the reader.
klao@1909:     UGraphReader& readUEdge(std::string name, UEdge& edge) {
klao@1909:       u_edge_reader.readUEdge(name, edge);
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Give a new attribute reading command.
deba@1421:     ///
athos@1540:     ///  Give a new attribute reading command.
deba@1421:     template <typename Value>
klao@1909:     UGraphReader& readAttribute(std::string name, Value& value) {
deba@1421:       attribute_reader.readAttribute(name, value);
deba@1421:       return *this;
deba@1421:     }
deba@1421:     
athos@1540:     /// \brief Give a new attribute reading command.
deba@1421:     ///
athos@1540:     ///  Give a new attribute reading command.
deba@1421:     template <typename Reader, typename Value>
klao@1909:     UGraphReader& readAttribute(std::string name, Value& value, 
deba@1421: 			       const Reader& reader) {
deba@1421:       attribute_reader.readAttribute<Reader>(name, value, reader);
deba@1421:       return *this;
deba@1421:     }
deba@1421: 
deba@1421:     /// \brief Conversion operator to LemonReader.
deba@1421:     ///
deba@1421:     /// Conversion operator to LemonReader. It make possible
deba@1421:     /// to access the encapsulated \e LemonReader, this way
deba@1421:     /// you can attach to this reader new instances of 
deba@1421:     /// \e LemonReader::SectionReader.
deba@1421:     operator LemonReader&() {
deba@1421:       return *reader;
deba@1421:     }
deba@1421: 
athos@1540:     /// \brief Executes the reading commands.
deba@1421:     ///
athos@1540:     /// Executes the reading commands.
deba@1421:     void run() {
deba@1421:       reader->run();
deba@1421:     }
deba@1421: 
deba@1901: 
deba@1901:     /// \brief Returns true if the reader can give back the items by its label.
deba@1429:     ///
deba@1901:     /// \brief Returns true if the reader can give back the items by its label.
deba@1901:     bool isLabelReader() const {
deba@1901:       return nodeset_reader.isLabelReader() && 
klao@1909:         u_edgeset_reader.isLabelReader();
deba@1901:     }
deba@1901: 
deba@1901:     /// \brief Gives back the node by its label.
deba@1901:     ///
deba@1901:     /// It reads an label from the stream and gives back which node belongs to
alpar@1935:     /// it. It is possible only if there was read a "label" named node map.
deba@1901:     void readLabel(std::istream& is, Node& node) const {
deba@1901:       return nodeset_reader.readLabel(is, node);
deba@1429:     } 
deba@1429: 
alpar@1935:     /// \brief Gives back the edge by its label
deba@1429:     ///
deba@1901:     /// It reads an label from the stream and gives back which edge belongs to
alpar@1935:     /// it. It is possible only if there was read a "label" named edge map.
deba@1901:     void readLabel(std::istream& is, Edge& edge) const {
klao@1909:       return u_edgeset_reader.readLabel(is, edge);
deba@1429:     } 
deba@1429: 
deba@1901:     /// \brief Gives back the undirected edge by its label.
deba@1429:     ///
deba@1901:     /// It reads an label from the stream and gives back which undirected edge 
alpar@1935:     /// belongs to it. It is possible only if there was read a "label" named 
deba@1429:     /// edge map.
klao@1909:     void readLabel(std::istream& is, UEdge& uedge) const {
klao@1909:       return u_edgeset_reader.readLabel(is, uedge);
deba@1429:     } 
deba@1429:     
deba@1429: 
deba@1421:   private:
deba@1421: 
deba@1421:     LemonReader* reader;
deba@1421:     bool own_reader;
deba@1421: 
deba@1421:     DefaultSkipper skipper;
deba@1421: 
deba@1421:     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
klao@1909:     UEdgeSetReader<Graph, ReaderTraits> u_edgeset_reader;
deba@1421: 
deba@1421:     NodeReader<Graph> node_reader;
klao@1909:     UEdgeReader<Graph> u_edge_reader;
deba@1421:     
deba@1421:     AttributeReader<ReaderTraits> attribute_reader;
deba@1421:   };
deba@1421: 
deba@1744:   /// \brief Read an undirected graph from the input.
deba@1421:   ///
deba@1744:   /// It is a helper function to read an undirected graph from the given input
klao@1909:   /// stream. It gives back an UGraphReader object and this object
deba@1744:   /// can read more maps, labeled nodes, edges, undirected edges and
deba@1744:   /// attributes.
deba@1744:   ///
deba@1744:   /// \warning Do not forget to call the \c run() function.
deba@1744:   ///
athos@1534:   /// \param is The input stream.
athos@1534:   /// \param g The graph.
athos@1534:   template<typename Graph>
klao@1909:   UGraphReader<Graph> uGraphReader(std::istream& is, Graph &g) {
deba@1744:     return GraphReader<Graph>(is, g);
athos@1534:   }
athos@1534: 
deba@1744:   /// \brief Read an undirected graph from the input.
athos@1534:   ///
deba@1744:   /// It is a helper function to read an undirected graph from the given input
klao@1909:   /// file. It gives back an UGraphReader object and this object
deba@1744:   /// can read more maps, labeled nodes, edges, undirected edges and 
deba@1744:   /// attributes.
deba@1744:   ///
deba@1744:   /// \warning Do not forget to call the \c run() function.
deba@1744:   ///
deba@1744:   /// \param fn The input filename.
deba@1421:   /// \param g The graph.
deba@1744:   template<typename Graph>
klao@1909:   UGraphReader<Graph> uGraphReader(const std::string& fn, Graph &g) {
deba@1744:     return GraphReader<Graph>(fn, g);
deba@1421:   }
deba@1421: 
deba@1333:   /// @}
deba@1137: }
deba@1214: 
deba@1214: #endif