diff -r e37cca875667 -r 7a21e1414c38 src/lemon/graph_reader.h --- a/src/lemon/graph_reader.h Sat May 14 17:37:33 2005 +0000 +++ b/src/lemon/graph_reader.h Sat May 14 17:39:37 2005 +0000 @@ -56,8 +56,7 @@ /// parameters. /// /// \code - /// reader.readNodeMap("x-coord", xCoordMap); - /// reader.readNodeMap("y-coord", yCoordMap); + /// reader.readNodeMap("coords", coords); /// /// reader.readNodeMap("label", labelMap); /// reader.skipNodeMap("description"); @@ -114,12 +113,13 @@ /// /// Construct a new GraphReader. It reads into the given graph /// and it use the given reader as the default skipper. - GraphReader(std::istream& _is, Graph& _graph, + GraphReader(std::istream& _is, + typename SmartParameter::Type _graph, const DefaultSkipper& _skipper = DefaultSkipper()) - : reader(new LemonReader(_is)), own_reader(true), - graph(_graph), skipper(_skipper), - nodeset_reader(*reader, graph, std::string(), skipper), - edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper), + : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper), + nodeset_reader(*reader, _graph, std::string(), skipper), + edgeset_reader(*reader, _graph, nodeset_reader, + std::string(), skipper), node_reader(*reader, nodeset_reader, std::string()), edge_reader(*reader, edgeset_reader, std::string()), attribute_reader(*reader, std::string()) {} @@ -128,12 +128,14 @@ /// /// Construct a new GraphReader. It reads into the given graph /// and it use the given reader as the default skipper. - GraphReader(const std::string& _filename, Graph& _graph, + GraphReader(const std::string& _filename, + typename SmartParameter::Type _graph, const DefaultSkipper& _skipper = DefaultSkipper()) : reader(new LemonReader(_filename)), own_reader(true), - graph(_graph), skipper(_skipper), - nodeset_reader(*reader, graph, std::string(), skipper), - edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper), + skipper(_skipper), + nodeset_reader(*reader, _graph, std::string(), skipper), + edgeset_reader(*reader, _graph, nodeset_reader, + std::string(), skipper), node_reader(*reader, nodeset_reader, std::string()), edge_reader(*reader, edgeset_reader, std::string()), attribute_reader(*reader, std::string()) {} @@ -142,12 +144,13 @@ /// /// Construct a new GraphReader. It reads into the given graph /// and it use the given reader as the default skipper. - GraphReader(LemonReader& _reader, Graph& _graph, + GraphReader(LemonReader& _reader, + typename SmartParameter::Type _graph, const DefaultSkipper& _skipper = DefaultSkipper()) - : reader(_reader), own_reader(false), - graph(_graph), skipper(_skipper), - nodeset_reader(*reader, graph, std::string(), skipper), - edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper), + : reader(_reader), own_reader(false), skipper(_skipper), + nodeset_reader(*reader, _graph, std::string(), skipper), + edgeset_reader(*reader, _graph, nodeset_reader, + std::string(), skipper), node_reader(*reader, nodeset_reader, std::string()), edge_reader(*reader, edgeset_reader, std::string()), attribute_reader(*reader, std::string()) {} @@ -165,7 +168,13 @@ /// Add a new node map reader command for the reader. template GraphReader& readNodeMap(std::string name, Map& map) { - nodeset_reader.readMap(name, map); + nodeset_reader.readNodeMap(name, map); + return *this; + } + + template + GraphReader& readNodeMap(std::string name, const Map& map) { + nodeset_reader.readNodeMap(name, map); return *this; } @@ -175,7 +184,14 @@ template GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { - nodeset_reader.readMap(name, map, reader); + nodeset_reader.readNodeMap(name, map, reader); + return *this; + } + + template + GraphReader& readNodeMap(std::string name, const Map& map, + const Reader& reader = Reader()) { + nodeset_reader.readNodeMap(name, map, reader); return *this; } @@ -185,7 +201,7 @@ template GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) { - nodeset_reader.skipMap(name, reader); + nodeset_reader.skipNodeMap(name, reader); return *this; } @@ -194,7 +210,13 @@ /// Add a new edge map reader command for the reader. template GraphReader& readEdgeMap(std::string name, Map& map) { - edgeset_reader.readMap(name, map); + edgeset_reader.readEdgeMap(name, map); + return *this; + } + + template + GraphReader& readEdgeMap(std::string name, const Map& map) { + edgeset_reader.readEdgeMap(name, map); return *this; } @@ -205,7 +227,14 @@ template GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { - edgeset_reader.readMap(name, map, reader); + edgeset_reader.readEdgeMap(name, map, reader); + return *this; + } + + template + GraphReader& readEdgeMap(std::string name, const Map& map, + const Reader& reader = Reader()) { + edgeset_reader.readEdgeMap(name, map, reader); return *this; } @@ -213,10 +242,9 @@ /// /// Add a new edge map skipper command for the reader. template - GraphReader& skipEdgeMap(std::string name, + GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) { - - edgeset_reader.skipMap(name, reader); + edgeset_reader.skipEdgeMap(name, reader); return *this; } @@ -276,8 +304,6 @@ LemonReader* reader; bool own_reader; - Graph& graph; - DefaultSkipper skipper; NodeSetReader nodeset_reader; @@ -368,6 +394,365 @@ reader.run(); } + /// \brief The undir graph reader class. + /// + /// The given file format may contain several maps and labeled nodes or + /// edges. + /// + /// If you read a graph you need not read all the maps and items just those + /// that you need. The interface of the \c GraphReader is very similar to + /// the GraphWriter but the reading method does not depend on the order the + /// given commands. + /// + /// The reader object suppose that each not readed value does not contain + /// whitespaces, therefore it has some extra possibilities to control how + /// it should skip the values when the string representation contains spaces. + /// + /// \code + /// UndirGraphReader reader(std::cin, graph); + /// \endcode + /// + /// The \c readNodeMap() function reads a map from the \c \@nodeset section. + /// If there is a map that you do not want to read from the file and there is + /// whitespace in the string represenation of the values then you should + /// call the \c skipNodeMap() template member function with proper + /// parameters. + /// + /// \code + /// reader.readNodeMap("coords", coords); + /// + /// reader.readNodeMap("label", labelMap); + /// reader.skipNodeMap("description"); + /// + /// reader.readNodeMap("color", colorMap); + /// \endcode + /// + /// With the \c readUndirEdgeMap() member function you can give an + /// undir edge map reading command similar to the NodeMaps. + /// + /// \code + /// reader.readUndirEdgeMap("capacity", capacityMap); + /// \endcode + /// + /// The reading of the directed edge maps is just a syntactical sugar. + /// It reads two undirected edgemaps into a directed edge map. The + /// undirected edge maps' name should be start with the \c '+' and the + /// \c '-' character and the same. + /// + /// \code + /// reader.readEdgeMap("flow", flowMap); + /// \endcode + /// + /// With \c readNode() and \c readUndirEdge() functions you can read + /// labeled Nodes and UndirEdges. + /// + /// \code + /// reader.readNode("source", sourceNode); + /// reader.readNode("target", targetNode); + /// + /// reader.readUndirEdge("observed", undirEdge); + /// \endcode + /// + /// With the \c readAttribute() functions you can read an attribute + /// in a variable. You can specify the reader for the attribute as + /// the nodemaps. + /// + /// After you give all read commands you must call the \c run() member + /// function, which execute all the commands. + /// + /// \code + /// reader.run(); + /// \endcode + /// + /// \see GraphReader + /// \see DefaultReaderTraits + /// \see \ref UndirGraphWriter + /// \see \ref graph-io-page + /// + /// \author Balazs Dezso + template + class UndirGraphReader { + public: + + typedef _Graph Graph; + typedef typename Graph::Node Node; + typedef typename Graph::Edge Edge; + typedef typename Graph::UndirEdge UndirEdge; + + typedef _ReaderTraits ReaderTraits; + typedef typename ReaderTraits::Skipper DefaultSkipper; + + /// \brief Construct a new UndirGraphReader. + /// + /// Construct a new UndirGraphReader. It reads into the given graph + /// and it use the given reader as the default skipper. + UndirGraphReader(std::istream& _is, Graph& _graph, + const DefaultSkipper& _skipper = DefaultSkipper()) + : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper), + nodeset_reader(*reader, _graph, std::string(), skipper), + undir_edgeset_reader(*reader, _graph, nodeset_reader, + std::string(), skipper), + node_reader(*reader, nodeset_reader, std::string()), + undir_edge_reader(*reader, undir_edgeset_reader, std::string()), + attribute_reader(*reader, std::string()) {} + + /// \brief Construct a new UndirGraphReader. + /// + /// Construct a new UndirGraphReader. It reads into the given graph + /// and it use the given reader as the default skipper. + UndirGraphReader(const std::string& _filename, Graph& _graph, + const DefaultSkipper& _skipper = DefaultSkipper()) + : reader(new LemonReader(_filename)), own_reader(true), + skipper(_skipper), + nodeset_reader(*reader, _graph, std::string(), skipper), + undir_edgeset_reader(*reader, _graph, nodeset_reader, + std::string(), skipper), + node_reader(*reader, nodeset_reader, std::string()), + undir_edge_reader(*reader, undir_edgeset_reader, std::string()), + attribute_reader(*reader, std::string()) {} + + /// \brief Construct a new UndirGraphReader. + /// + /// Construct a new UndirGraphReader. It reads into the given graph + /// and it use the given reader as the default skipper. + UndirGraphReader(LemonReader& _reader, Graph& _graph, + const DefaultSkipper& _skipper = DefaultSkipper()) + : reader(_reader), own_reader(false), skipper(_skipper), + nodeset_reader(*reader, _graph, std::string(), skipper), + undir_edgeset_reader(*reader, _graph, nodeset_reader, + std::string(), skipper), + node_reader(*reader, nodeset_reader, std::string()), + undir_edge_reader(*reader, undir_edgeset_reader, std::string()), + attribute_reader(*reader, std::string()) {} + + /// \brief Destruct the graph reader. + /// + /// Destruct the graph reader. + ~UndirGraphReader() { + if (own_reader) + delete reader; + } + + /// \brief Add a new node map reader command for the reader. + /// + /// Add a new node map reader command for the reader. + template + UndirGraphReader& readNodeMap(std::string name, Map& map) { + nodeset_reader.readNodeMap(name, map); + return *this; + } + + template + UndirGraphReader& readNodeMap(std::string name, const Map& map) { + nodeset_reader.readNodeMap(name, map); + return *this; + } + + /// \brief Add a new node map reader command for the reader. + /// + /// Add a new node map reader command for the reader. + template + UndirGraphReader& readNodeMap(std::string name, Map& map, + const Reader& reader = Reader()) { + nodeset_reader.readNodeMap(name, map, reader); + return *this; + } + + template + UndirGraphReader& readNodeMap(std::string name, const Map& map, + const Reader& reader = Reader()) { + nodeset_reader.readNodeMap(name, map, reader); + return *this; + } + + /// \brief Add a new node map skipper command for the reader. + /// + /// Add a new node map skipper command for the reader. + template + UndirGraphReader& skipNodeMap(std::string name, + const Reader& reader = Reader()) { + nodeset_reader.skipNodeMap(name, reader); + return *this; + } + + /// \brief Add a new undirected edge map reader command for the reader. + /// + /// Add a new undirected edge map reader command for the reader. + template + UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) { + undir_edgeset_reader.readUndirEdgeMap(name, map); + return *this; + } + + template + UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) { + undir_edgeset_reader.readUndirEdgeMap(name, map); + return *this; + } + + + /// \brief Add a new undirected edge map reader command for the reader. + /// + /// Add a new undirected edge map reader command for the reader. + template + UndirGraphReader& readUndirEdgeMap(std::string name, Map& map, + const Reader& reader = Reader()) { + undir_edgeset_reader.readUndirEdgeMap(name, map, reader); + return *this; + } + + template + UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map, + const Reader& reader = Reader()) { + undir_edgeset_reader.readUndirEdgeMap(name, map, reader); + return *this; + } + + /// \brief Add a new undirected edge map skipper command for the reader. + /// + /// Add a new undirected edge map skipper command for the reader. + template + UndirGraphReader& skipUndirEdgeMap(std::string name, + const Reader& reader = Reader()) { + undir_edgeset_reader.skipUndirMap(name, reader); + return *this; + } + + + /// \brief Add a new edge map reader command for the reader. + /// + /// Add a new edge map reader command for the reader. + template + UndirGraphReader& readEdgeMap(std::string name, Map& map) { + undir_edgeset_reader.readEdgeMap(name, map); + return *this; + } + + template + UndirGraphReader& readEdgeMap(std::string name, const Map& map) { + undir_edgeset_reader.readEdgeMap(name, map); + return *this; + } + + + /// \brief Add a new edge map reader command for the reader. + /// + /// Add a new edge map reader command for the reader. + template + UndirGraphReader& readEdgeMap(std::string name, Map& map, + const Reader& reader = Reader()) { + undir_edgeset_reader.readEdgeMap(name, map, reader); + return *this; + } + + template + UndirGraphReader& readEdgeMap(std::string name, const Map& map, + const Reader& reader = Reader()) { + undir_edgeset_reader.readEdgeMap(name, map, reader); + return *this; + } + + /// \brief Add a new edge map skipper command for the reader. + /// + /// Add a new edge map skipper command for the reader. + template + UndirGraphReader& skipEdgeMap(std::string name, + const Reader& reader = Reader()) { + undir_edgeset_reader.skipEdgeMap(name, reader); + return *this; + } + + /// \brief Add a new labeled node reader for the reader. + /// + /// Add a new labeled node reader for the reader. + UndirGraphReader& readNode(std::string name, Node& node) { + node_reader.readNode(name, node); + return *this; + } + + /// \brief Add a new labeled edge reader for the reader. + /// + /// Add a new labeled edge reader for the reader. + UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) { + undir_edge_reader.readUndirEdge(name, edge); + } + + /// \brief Add a new attribute reader command. + /// + /// Add a new attribute reader command. + template + UndirGraphReader& readAttribute(std::string name, Value& value) { + attribute_reader.readAttribute(name, value); + return *this; + } + + /// \brief Add a new attribute reader command. + /// + /// Add a new attribute reader command. + template + UndirGraphReader& readAttribute(std::string name, Value& value, + const Reader& reader) { + attribute_reader.readAttribute(name, value, reader); + return *this; + } + + /// \brief Conversion operator to LemonReader. + /// + /// Conversion operator to LemonReader. It make possible + /// to access the encapsulated \e LemonReader, this way + /// you can attach to this reader new instances of + /// \e LemonReader::SectionReader. + operator LemonReader&() { + return *reader; + } + + /// \brief Executes the reader commands. + /// + /// Executes the reader commands. + void run() { + reader->run(); + } + + private: + + LemonReader* reader; + bool own_reader; + + DefaultSkipper skipper; + + NodeSetReader nodeset_reader; + UndirEdgeSetReader undir_edgeset_reader; + + NodeReader node_reader; + UndirEdgeReader undir_edge_reader; + + AttributeReader attribute_reader; + }; + + /// \brief Read an undir graph from the input. + /// + /// Read an undir graph from the input. + /// \param is The input stream. + /// \param g The graph. + /// \param capacity The capacity map. + template + void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) { + UndirGraphReader reader(is, g); + reader.readUndirEdgeMap("capacity", capacity); + reader.run(); + } + + /// \brief Read an undir graph from the input. + /// + /// Read an undir graph from the input. + /// \param is The input stream. + /// \param g The graph. + template + void readUndirGraph(std::istream& is, Graph &g) { + UndirGraphReader reader(is, g); + reader.run(); + } + /// @} }