deba@1137: /* -*- C++ -*- deba@1137: * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library deba@1137: * alpar@1164: * Copyright (C) 2005 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: /// deba@1333: /// The given file format 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 deba@1333: /// given commands. deba@1333: /// deba@1333: /// The reader object suppose that each not readed value does 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@1394: /// reader.readNodeMap("label", labelMap); deba@1333: /// reader.skipNodeMap("description"); 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 deba@1408: /// in 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 deba@1333: /// function, which execute 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 deba@1208: /// and it use the given reader as the default skipper. deba@1421: GraphReader(std::istream& _is, deba@1421: typename SmartParameter::Type _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 deba@1408: /// and it use the given reader as the default skipper. deba@1421: GraphReader(const std::string& _filename, deba@1421: typename SmartParameter::Type _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 deba@1408: /// and it use the given reader as the default skipper. deba@1421: GraphReader(LemonReader& _reader, deba@1421: typename SmartParameter::Type _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: deba@1137: /// \brief Add a new node map reader command for the reader. deba@1137: /// deba@1137: /// Add a new node map reader command for 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: deba@1137: /// \brief Add a new node map reader command for the reader. deba@1137: /// deba@1137: /// Add a new node map reader command for 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: deba@1137: /// \brief Add a new node map skipper command for the reader. deba@1137: /// deba@1137: /// Add a new node map skipper command for 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: deba@1137: /// \brief Add a new edge map reader command for the reader. deba@1137: /// deba@1137: /// Add a new edge map reader command for 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: deba@1137: /// \brief Add a new edge map reader command for the reader. deba@1137: /// deba@1137: /// Add a new edge map reader command for 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: deba@1137: /// \brief Add a new edge map skipper command for the reader. deba@1137: /// deba@1137: /// Add a new edge map skipper command for 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: deba@1137: /// \brief Add a new labeled node reader for the reader. deba@1137: /// deba@1137: /// Add a new labeled node reader for 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: deba@1137: /// \brief Add a new labeled edge reader for the reader. deba@1137: /// deba@1137: /// Add a new labeled edge reader for the reader. deba@1394: GraphReader& readEdge(std::string name, Edge& edge) { deba@1408: edge_reader.readEdge(name, edge); deba@1408: } deba@1408: deba@1408: /// \brief Add a new attribute reader command. deba@1408: /// deba@1408: /// Add a new attribute reader 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: deba@1408: /// \brief Add a new attribute reader command. deba@1408: /// deba@1408: /// Add a new attribute reader 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: /// deba@1408: /// Conversion operator to LemonReader. It make possible deba@1408: /// to access the encapsulated \e LemonReader, this way deba@1408: /// you can attach to this reader new instances of deba@1408: /// \e LemonReader::SectionReader. deba@1408: operator LemonReader&() { deba@1408: return *reader; deba@1408: } deba@1137: deba@1137: /// \brief Executes the reader commands. deba@1137: /// deba@1137: /// Executes the reader commands. deba@1137: void run() { deba@1408: reader->run(); deba@1396: } deba@1396: 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: deba@1333: /// \brief Read a graph from the input. deba@1333: /// deba@1333: /// Read a graph from the input. deba@1333: /// \param is The input stream. deba@1333: /// \param g The graph. deba@1333: /// \param capacity The capacity map. deba@1333: /// \param s The source node. deba@1333: /// \param t The target node. deba@1333: /// \param cost The cost map. deba@1208: template deba@1208: void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, deba@1208: typename Graph::Node &s, typename Graph::Node &t, deba@1208: CostMap& cost) { deba@1208: GraphReader reader(is, g); deba@1394: reader.readEdgeMap("capacity", capacity); deba@1394: reader.readEdgeMap("cost", cost); deba@1394: reader.readNode("source", s); deba@1394: reader.readNode("target", t); deba@1208: reader.run(); deba@1208: } deba@1208: deba@1333: /// \brief Read a graph from the input. deba@1333: /// deba@1333: /// Read a graph from the input. deba@1333: /// \param is The input stream. deba@1333: /// \param g The graph. deba@1333: /// \param capacity The capacity map. deba@1333: /// \param s The source node. deba@1333: /// \param t The target node. deba@1208: template deba@1208: void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, deba@1208: typename Graph::Node &s, typename Graph::Node &t) { deba@1208: GraphReader reader(is, g); deba@1394: reader.readEdgeMap("capacity", capacity); deba@1394: reader.readNode("source", s); deba@1394: reader.readNode("target", t); deba@1208: reader.run(); deba@1208: } deba@1208: deba@1333: /// \brief Read a graph from the input. deba@1333: /// deba@1333: /// Read a graph from the input. deba@1333: /// \param is The input stream. deba@1333: /// \param g The graph. deba@1333: /// \param capacity The capacity map. deba@1333: /// \param s The source node. deba@1208: template deba@1208: void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, deba@1208: typename Graph::Node &s) { deba@1208: GraphReader reader(is, g); deba@1394: reader.readEdgeMap("capacity", capacity); deba@1394: reader.readNode("source", s); deba@1208: reader.run(); deba@1208: } deba@1208: deba@1333: /// \brief Read a graph from the input. deba@1333: /// deba@1333: /// Read a graph from the input. deba@1333: /// \param is The input stream. deba@1333: /// \param g The graph. deba@1333: /// \param capacity The capacity map. deba@1208: template deba@1208: void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) { deba@1208: GraphReader reader(is, g); deba@1394: reader.readEdgeMap("capacity", capacity); deba@1208: reader.run(); deba@1208: } deba@1208: deba@1333: /// \brief Read a graph from the input. deba@1333: /// deba@1333: /// Read a graph from the input. deba@1333: /// \param is The input stream. deba@1333: /// \param g The graph. deba@1208: template deba@1208: void readGraph(std::istream& is, Graph &g) { deba@1208: GraphReader reader(is, g); deba@1208: reader.run(); deba@1208: } deba@1208: deba@1421: /// \brief The undir graph reader class. deba@1421: /// 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 deba@1421: /// that you need. The interface of the \c GraphReader is very similar to deba@1421: /// the GraphWriter but the reading method does not depend on the order the deba@1421: /// 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@1421: /// reader.readNodeMap("label", labelMap); deba@1421: /// reader.skipNodeMap("description"); 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: deba@1421: /// \brief Add a new node map reader command for the reader. deba@1421: /// deba@1421: /// Add a new node map reader command for 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: deba@1421: /// \brief Add a new node map reader command for the reader. deba@1421: /// deba@1421: /// Add a new node map reader command for 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: deba@1421: /// \brief Add a new node map skipper command for the reader. deba@1421: /// deba@1421: /// Add a new node map skipper command for 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: deba@1421: /// \brief Add a new undirected edge map reader command for the reader. deba@1421: /// deba@1421: /// Add a new undirected edge map reader command for 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: deba@1421: /// \brief Add a new undirected edge map reader command for the reader. deba@1421: /// deba@1421: /// Add a new undirected edge map reader command for 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: deba@1421: /// \brief Add a new undirected edge map skipper command for the reader. deba@1421: /// deba@1421: /// Add a new undirected edge map skipper command for 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: deba@1421: /// \brief Add a new edge map reader command for the reader. deba@1421: /// deba@1421: /// Add a new edge map reader command for 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: deba@1421: /// \brief Add a new edge map reader command for the reader. deba@1421: /// deba@1421: /// Add a new edge map reader command for 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: deba@1421: /// \brief Add a new edge map skipper command for the reader. deba@1421: /// deba@1421: /// Add a new edge map skipper command for 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: deba@1421: /// \brief Add a new labeled node reader for the reader. deba@1421: /// deba@1421: /// Add a new labeled node reader for 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: deba@1421: /// \brief Add a new labeled edge reader for the reader. deba@1421: /// deba@1421: /// Add a new labeled edge reader for the reader. deba@1421: UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) { deba@1421: undir_edge_reader.readUndirEdge(name, edge); deba@1421: } deba@1421: deba@1421: /// \brief Add a new attribute reader command. deba@1421: /// deba@1421: /// Add a new attribute reader 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: deba@1421: /// \brief Add a new attribute reader command. deba@1421: /// deba@1421: /// Add a new attribute reader 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: deba@1421: /// \brief Executes the reader commands. deba@1421: /// deba@1421: /// Executes the reader commands. deba@1421: void run() { deba@1421: reader->run(); deba@1421: } deba@1421: 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@1421: /// \brief Read an undir graph from the input. deba@1421: /// deba@1421: /// Read an undir graph from the input. deba@1421: /// \param is The input stream. deba@1421: /// \param g The graph. deba@1421: /// \param capacity The capacity map. deba@1421: template deba@1421: void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) { deba@1421: UndirGraphReader reader(is, g); deba@1421: reader.readUndirEdgeMap("capacity", capacity); deba@1421: reader.run(); deba@1421: } deba@1421: deba@1421: /// \brief Read an undir graph from the input. deba@1421: /// deba@1421: /// Read an undir graph from the input. deba@1421: /// \param is The input stream. deba@1421: /// \param g The graph. deba@1421: template deba@1421: void readUndirGraph(std::istream& is, Graph &g) { deba@1421: UndirGraphReader reader(is, g); deba@1421: reader.run(); deba@1421: } deba@1421: deba@1333: /// @} deba@1137: } deba@1214: deba@1214: #endif