deba@1137: /* -*- C++ -*- ladanyi@1435: * lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library deba@1137: * alpar@1875: * Copyright (C) 2006 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: alpar@1287: ///\ingroup io_group 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 deba@1137: deba@1137: #include deba@1408: #include deba@1137: deba@1137: namespace lemon { deba@1137: deba@1333: /// \addtogroup io_group 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@1534: /// If you don't need very sophisticated athos@1534: /// behaviour then you can use the versions of the public function athos@1534: /// \ref readGraph() to read a graph (or a max flow instance etc). athos@1534: /// 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: /// athos@1540: /// The reader object assumes that not readed 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: /// deba@1333: /// \code deba@1333: /// GraphReader reader(std::cin, graph); deba@1333: /// \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: /// deba@1333: /// \code deba@1421: /// reader.readNodeMap("coords", coords); deba@1333: /// deba@1901: /// reader.skipNodeMap("description", desc); deba@1333: /// deba@1394: /// reader.readNodeMap("color", colorMap); deba@1333: /// \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: /// deba@1333: /// \code deba@1394: /// reader.readEdgeMap("weight", weightMap); deba@1394: /// reader.readEdgeMap("label", labelMap); deba@1333: /// \endcode deba@1333: /// deba@1408: /// With \c readNode() and \c readEdge() functions you can read deba@1408: /// labeled Nodes and Edges. deba@1333: /// deba@1333: /// \code deba@1394: /// reader.readNode("source", sourceNode); deba@1394: /// reader.readNode("target", targetNode); deba@1333: /// deba@1394: /// reader.readEdge("observed", edge); deba@1333: /// \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: /// deba@1333: /// \code deba@1333: /// reader.run(); deba@1333: /// \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 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 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 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 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 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 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 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 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 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 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 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 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 deba@1408: GraphReader& readAttribute(std::string name, Value& value, deba@1408: const Reader& reader) { deba@1408: attribute_reader.readAttribute(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 deba@1901: /// it. It is possible only if there was read an "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 deba@1901: /// it. It is possible only if there was read an "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 nodeset_reader; deba@1408: EdgeSetReader edgeset_reader; deba@1408: deba@1408: NodeReader node_reader; deba@1408: EdgeReader edge_reader; deba@1408: deba@1408: AttributeReader 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 deba@1744: GraphReader graphReader(std::istream& is, Graph &g) { deba@1744: return GraphReader(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 deba@1744: GraphReader graphReader(const std::string& fn, Graph &g) { deba@1744: return GraphReader(fn, g); athos@1534: } athos@1534: deba@1744: /// \brief The undirected graph reader class. deba@1421: /// athos@1540: /// The \c UndirGraphReader 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: /// athos@1540: /// If you don't need very sophisticated athos@1540: /// behaviour then you can use the versions of the public function athos@1540: /// \ref readGraph() to read a graph (or a max flow instance etc). 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 athos@1540: /// that you need. The interface of the \c UndirGraphReader is very similar athos@1540: /// to the UndirGraphWriter but the reading method does not depend on the athos@1540: /// order of the given commands. deba@1421: /// deba@1421: /// The reader object suppose that each not readed 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: /// deba@1421: /// \code deba@1421: /// UndirGraphReader reader(std::cin, graph); deba@1421: /// \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: /// deba@1421: /// \code deba@1421: /// reader.readNodeMap("coords", coords); deba@1421: /// deba@1901: /// reader.skipNodeMap("description", desc); deba@1421: /// deba@1421: /// reader.readNodeMap("color", colorMap); deba@1421: /// \endcode deba@1421: /// deba@1421: /// With the \c readUndirEdgeMap() member function you can give an deba@1421: /// undir edge map reading command similar to the NodeMaps. deba@1421: /// deba@1421: /// \code deba@1421: /// reader.readUndirEdgeMap("capacity", capacityMap); deba@1421: /// \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: /// deba@1421: /// \code deba@1421: /// reader.readEdgeMap("flow", flowMap); deba@1421: /// \endcode deba@1421: /// deba@1421: /// With \c readNode() and \c readUndirEdge() functions you can read deba@1421: /// labeled Nodes and UndirEdges. deba@1421: /// deba@1421: /// \code deba@1421: /// reader.readNode("source", sourceNode); deba@1421: /// reader.readNode("target", targetNode); deba@1421: /// deba@1421: /// reader.readUndirEdge("observed", undirEdge); deba@1421: /// \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: /// deba@1421: /// \code deba@1421: /// reader.run(); deba@1421: /// \endcode deba@1421: /// deba@1421: /// \see GraphReader deba@1421: /// \see DefaultReaderTraits deba@1421: /// \see \ref UndirGraphWriter deba@1421: /// \see \ref graph-io-page deba@1421: /// deba@1421: /// \author Balazs Dezso deba@1421: template deba@1421: class UndirGraphReader { deba@1421: public: deba@1421: deba@1421: typedef _Graph Graph; deba@1421: typedef typename Graph::Node Node; deba@1421: typedef typename Graph::Edge Edge; deba@1421: typedef typename Graph::UndirEdge UndirEdge; deba@1421: deba@1421: typedef _ReaderTraits ReaderTraits; deba@1421: typedef typename ReaderTraits::Skipper DefaultSkipper; deba@1421: deba@1421: /// \brief Construct a new UndirGraphReader. deba@1421: /// deba@1421: /// Construct a new UndirGraphReader. It reads into the given graph deba@1421: /// and it use the given reader as the default skipper. deba@1421: UndirGraphReader(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), deba@1421: undir_edgeset_reader(*reader, _graph, nodeset_reader, deba@1421: std::string(), skipper), deba@1421: node_reader(*reader, nodeset_reader, std::string()), deba@1421: undir_edge_reader(*reader, undir_edgeset_reader, std::string()), deba@1421: attribute_reader(*reader, std::string()) {} deba@1421: deba@1421: /// \brief Construct a new UndirGraphReader. deba@1421: /// deba@1421: /// Construct a new UndirGraphReader. It reads into the given graph deba@1421: /// and it use the given reader as the default skipper. deba@1421: UndirGraphReader(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), deba@1421: undir_edgeset_reader(*reader, _graph, nodeset_reader, deba@1421: std::string(), skipper), deba@1421: node_reader(*reader, nodeset_reader, std::string()), deba@1421: undir_edge_reader(*reader, undir_edgeset_reader, std::string()), deba@1421: attribute_reader(*reader, std::string()) {} deba@1421: deba@1421: /// \brief Construct a new UndirGraphReader. deba@1421: /// deba@1421: /// Construct a new UndirGraphReader. It reads into the given graph deba@1421: /// and it use the given reader as the default skipper. deba@1421: UndirGraphReader(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), deba@1421: undir_edgeset_reader(*reader, _graph, nodeset_reader, deba@1421: std::string(), skipper), deba@1421: node_reader(*reader, nodeset_reader, std::string()), deba@1421: undir_edge_reader(*reader, undir_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. deba@1421: ~UndirGraphReader() { 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 deba@1421: UndirGraphReader& readNodeMap(std::string name, Map& map) { deba@1421: nodeset_reader.readNodeMap(name, map); deba@1421: return *this; deba@1421: } deba@1421: deba@1421: template deba@1421: UndirGraphReader& 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 deba@1421: UndirGraphReader& 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 deba@1421: UndirGraphReader& 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 deba@1421: UndirGraphReader& 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 deba@1421: UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) { deba@1421: undir_edgeset_reader.readUndirEdgeMap(name, map); deba@1421: return *this; deba@1421: } deba@1421: deba@1421: template deba@1421: UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) { deba@1421: undir_edgeset_reader.readUndirEdgeMap(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 deba@1421: UndirGraphReader& readUndirEdgeMap(std::string name, Map& map, deba@1421: const Reader& reader = Reader()) { deba@1421: undir_edgeset_reader.readUndirEdgeMap(name, map, reader); deba@1421: return *this; deba@1421: } deba@1421: deba@1421: template deba@1421: UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map, deba@1421: const Reader& reader = Reader()) { deba@1421: undir_edgeset_reader.readUndirEdgeMap(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 deba@1421: UndirGraphReader& skipUndirEdgeMap(std::string name, deba@1421: const Reader& reader = Reader()) { deba@1421: undir_edgeset_reader.skipUndirMap(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 deba@1421: UndirGraphReader& readEdgeMap(std::string name, Map& map) { deba@1421: undir_edgeset_reader.readEdgeMap(name, map); deba@1421: return *this; deba@1421: } deba@1421: deba@1421: template deba@1421: UndirGraphReader& readEdgeMap(std::string name, const Map& map) { deba@1421: undir_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 deba@1421: UndirGraphReader& readEdgeMap(std::string name, Map& map, deba@1421: const Reader& reader = Reader()) { deba@1421: undir_edgeset_reader.readEdgeMap(name, map, reader); deba@1421: return *this; deba@1421: } deba@1421: deba@1421: template deba@1421: UndirGraphReader& readEdgeMap(std::string name, const Map& map, deba@1421: const Reader& reader = Reader()) { deba@1421: undir_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 deba@1421: UndirGraphReader& skipEdgeMap(std::string name, deba@1421: const Reader& reader = Reader()) { deba@1421: undir_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. deba@1421: UndirGraphReader& 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. deba@1429: UndirGraphReader& readEdge(std::string name, Edge& edge) { deba@1429: undir_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. deba@1421: UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) { deba@1421: undir_edge_reader.readUndirEdge(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 deba@1421: UndirGraphReader& 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 deba@1421: UndirGraphReader& readAttribute(std::string name, Value& value, deba@1421: const Reader& reader) { deba@1421: attribute_reader.readAttribute(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() && deba@1901: undir_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 deba@1901: /// it. It is possible only if there was read an "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: 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 deba@1901: /// it. It is possible only if there was read an "label" named edge map. deba@1901: void readLabel(std::istream& is, Edge& edge) const { deba@1901: return undir_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 deba@1901: /// belongs to it. It is possible only if there was read an "label" named deba@1429: /// edge map. deba@1901: void readLabel(std::istream& is, UndirEdge& uedge) const { deba@1901: return undir_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 nodeset_reader; deba@1421: UndirEdgeSetReader undir_edgeset_reader; deba@1421: deba@1421: NodeReader node_reader; deba@1421: UndirEdgeReader undir_edge_reader; deba@1421: deba@1421: AttributeReader 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 deba@1744: /// stream. It gives back an UndirGraphReader 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 deba@1744: UndirGraphReader undirGraphReader(std::istream& is, Graph &g) { deba@1744: return GraphReader(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 deba@1744: /// file. It gives back an UndirGraphReader 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 deba@1744: UndirGraphReader undirGraphReader(const std::string& fn, Graph &g) { deba@1744: return GraphReader(fn, g); deba@1421: } deba@1421: deba@1333: /// @} deba@1137: } deba@1214: deba@1214: #endif