/* -*- C++ -*- * * This file is a part of LEMON, a generic C++ optimization library * * Copyright (C) 2003-2006 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Research Group on Combinatorial Optimization, EGRES). * * Permission to use, modify and distribute this software is granted * provided that this copyright notice appears in all copies. For * precise terms see the accompanying LICENSE file. * * This software is provided "AS IS" with no warranty of any kind, * express or implied, and with no claim as to its suitability for any * purpose. * */ ///\ingroup io_group ///\file ///\brief Lemon Graph Format writer. /// #ifndef LEMON_GRAPH_WRITER_H #define LEMON_GRAPH_WRITER_H #include #include #include namespace lemon { /// \addtogroup io_group /// @{ /// \brief The graph writer class. /// /// The \c GraphWriter class provides the graph output. /// Before you read this documentation it might be useful to read the general /// description of \ref graph-io-page "Graph Input-Output". /// /// If you don't need very sophisticated /// behaviour then you can use the versions of the public function /// \ref writeGraph() to output a graph (or a max flow instance etc). /// /// To write a graph /// you should first give writing commands to the writer. You can declare /// write commands as \c NodeMap or \c EdgeMap writing and labeled Node and /// Edge writing. /// ///\code /// GraphWriter writer(std::cout, graph); ///\endcode /// /// The \c writeNodeMap() function declares a \c NodeMap writing /// command in the \c GraphWriter. You should give as parameter /// the name of the map and the map object. The NodeMap writing /// command with name "label" should write a unique map because it /// is regarded as label map (such a map is essential if the graph has edges). /// ///\code /// IdMap nodeLabelMap; /// writer.writeNodeMap("label", nodeLabelMap); /// /// writer.writeNodeMap("coords", coords); /// writer.writeNodeMap("color", colorMap); ///\endcode /// /// With the \c writeEdgeMap() member function you can give an edge map /// writing command similar to the NodeMaps. /// ///\code /// DescriptorMap > /// edgeDescMap(graph); /// writer.writeEdgeMap("descriptor", edgeDescMap); /// /// writer.writeEdgeMap("weight", weightMap); /// writer.writeEdgeMap("label", labelMap); ///\endcode /// /// With \c writeNode() and \c writeEdge() functions you can /// point out Nodes and Edges in the graph. For example, you can /// write out the source and target of a maximum flow instance. /// ///\code /// writer.writeNode("source", sourceNode); /// writer.writeNode("target", targetNode); /// /// writer.writeEdge("observed", edge); ///\endcode /// /// After you give all write commands you must call the \c run() member /// function, which executes all the writing commands. /// ///\code /// writer.run(); ///\endcode /// /// \see DefaultWriterTraits /// \see QuotedStringWriter /// \see IdMap /// \see DescriptorMap /// \see \ref GraphReader /// \see \ref graph-io-page /// \author Balazs Dezso template class GraphWriter { public: typedef _Graph Graph; typedef typename Graph::Node Node; typedef typename Graph::Edge Edge; typedef _WriterTraits WriterTraits; /// \brief Construct a new GraphWriter. /// /// This function constructs a new GraphWriter to write the given graph /// to the given stream. GraphWriter(std::ostream& _os, const Graph& _graph) : writer(new LemonWriter(_os)), own_writer(true), nodeset_writer(*writer, _graph, std::string()), edgeset_writer(*writer, _graph, nodeset_writer, std::string()), node_writer(*writer, nodeset_writer, std::string()), edge_writer(*writer, edgeset_writer, std::string()), attribute_writer(*writer, std::string()) {} /// \brief Construct a new GraphWriter. /// /// This function constructs a new GraphWriter to write the given graph /// to the given file. GraphWriter(const std::string& _filename, const Graph& _graph) : writer(new LemonWriter(_filename)), own_writer(true), nodeset_writer(*writer, _graph, std::string()), edgeset_writer(*writer, _graph, nodeset_writer, std::string()), node_writer(*writer, nodeset_writer, std::string()), edge_writer(*writer, edgeset_writer, std::string()), attribute_writer(*writer, std::string()) {} /// \brief Construct a new GraphWriter. /// /// This function constructs a new GraphWriter to write the given graph /// to the given LemonReader. GraphWriter(LemonWriter& _writer, const Graph& _graph) : writer(_writer), own_writer(false), nodeset_writer(*writer, _graph, std::string()), edgeset_writer(*writer, _graph, nodeset_writer, std::string()), node_writer(*writer, nodeset_writer, std::string()), edge_writer(*writer, edgeset_writer, std::string()), attribute_writer(*writer, std::string()) {} /// \brief Destruct the graph writer. /// /// This function destructs the graph writer. ~GraphWriter() { if (own_writer) delete writer; } /// \brief Issue a new node map writing command for the writer. /// /// This function issues a new node map writing command to the writer. template GraphWriter& writeNodeMap(std::string name, const Map& map) { nodeset_writer.writeNodeMap(name, map); return *this; } /// \brief Issue a new node map writing command for the writer. /// /// This function issues a new node map writing command to the writer. template GraphWriter& writeNodeMap(std::string name, const Map& map, const Writer& writer = Writer()) { nodeset_writer.writeNodeMap(name, map, writer); return *this; } /// \brief Issue a new edge map writing command for the writer. /// /// This function issues a new edge map writing command to the writer. template GraphWriter& writeEdgeMap(std::string name, const Map& map) { edgeset_writer.writeEdgeMap(name, map); return *this; } /// \brief Issue a new edge map writing command for the writer. /// /// This function issues a new edge map writing command to the writer. template GraphWriter& writeEdgeMap(std::string name, const Map& map, const Writer& writer = Writer()) { edgeset_writer.writeEdgeMap(name, map, writer); return *this; } /// \brief Issue a new labeled node writing command to the writer. /// /// This function issues a new labeled node writing command /// to the writer. GraphWriter& writeNode(std::string name, const Node& node) { node_writer.writeNode(name, node); return *this; } /// \brief Issue a new labeled edge writing command to the writer. /// /// This function issues a new labeled edge writing command /// to the writer. GraphWriter& writeEdge(std::string name, const Edge& edge) { edge_writer.writeEdge(name, edge); } /// \brief Issue a new attribute writing command. /// /// This function issues a new attribute writing command /// to the writer. template GraphWriter& writeAttribute(std::string name, const Value& value) { attribute_writer.writeAttribute(name, value); return *this; } /// \brief Issue a new attribute writing command. /// /// This function issues a new attribute writing command /// to the writer. template GraphWriter& writeAttribute(std::string name, const Value& value, const Writer& writer) { attribute_writer.writeAttribute(name, value, writer); return *this; } /// \brief Conversion operator to LemonWriter. /// /// Conversion operator to LemonWriter. It makes possible /// to access the encapsulated \e LemonWriter, this way /// you can attach to this writer new instances of /// \e LemonWriter::SectionWriter. For more details see /// the \ref rwbackground "Background of Reading and Writing". operator LemonWriter&() { return *writer; } /// \brief Executes the writing commands. /// /// Executes the writing commands. void run() { writer->run(); } /// \brief Write the label of the given node. /// /// It writes the label of the given node. If there was written an "label" /// named node map then it will write the map value belonging to the node. void writeLabel(std::ostream& os, const Node& item) const { nodeset_writer.writeLabel(os, item); } /// \brief Write the label of the given edge. /// /// It writes the label of the given edge. If there was written an "label" /// named edge map then it will write the map value belonging to the edge. void writeLabel(std::ostream& os, const Edge& item) const { edgeset_writer.writeLabel(os, item); } private: LemonWriter* writer; bool own_writer; NodeSetWriter nodeset_writer; EdgeSetWriter edgeset_writer; NodeWriter node_writer; EdgeWriter edge_writer; AttributeWriter attribute_writer; }; /// \brief Write a graph to the output. /// /// It is a helper function to write a graph to the given output /// stream. It gives back a GraphWriter object and this object /// can write more maps, labeled nodes and edges and attributes. /// \warning Do not forget to call the \c run() function. /// /// \param os The output stream. /// \param g The graph. template GraphWriter graphWriter(std::ostream& os, const Graph &g) { return GraphWriter(os, g); } /// \brief Write a graph to the output. /// /// It is a helper function to write a graph to the given output /// file. It gives back a GraphWriter object and this object /// can write more maps, labeled nodes and edges and attributes. /// \warning Do not forget to call the \c run() function. /// /// \param fn The filename. /// \param g The graph. template GraphWriter graphWriter(const std::string& fn, const Graph &g) { return GraphWriter(fn, g); } /// \brief The undirected graph writer class. /// /// The \c UGraphWriter class provides the ugraph output. To write /// a graph you should first give writing commands to the writer. You can /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap /// writing and labeled Node, Edge or UEdge writing. /// ///\code /// UGraphWriter writer(std::cout, graph); ///\endcode /// /// The \c writeNodeMap() function declares a \c NodeMap writing /// command in the \c UGraphWriter. You should give as parameter /// the name of the map and the map object. The NodeMap writing /// command with name "label" should write a unique map because it /// is regarded as label map. /// ///\code /// IdMap nodeLabelMap; /// writer.writeNodeMap("label", nodeLabelMap); /// /// writer.writeNodeMap("coords", coords); /// writer.writeNodeMap("color", colorMap); ///\endcode /// /// With the \c writeUEdgeMap() member function you can give an /// undirected edge map writing command similar to the NodeMaps. /// ///\code /// DescriptorMap > /// edgeDescMap(graph); /// writer.writeUEdgeMap("descriptor", edgeDescMap); /// /// writer.writeUEdgeMap("weight", weightMap); /// writer.writeUEdgeMap("label", labelMap); ///\endcode /// /// The EdgeMap handling is just a syntactical sugar. It writes /// two undirected edge map with '+' and '-' prefix in the name. /// ///\code /// writer.writeEdgeMap("capacity", capacityMap); ///\endcode /// /// /// With \c writeNode() and \c writeUEdge() functions you can /// designate nodes and undirected edges in the graph. For example, you can /// write out the source and target of the graph. /// ///\code /// writer.writeNode("source", sourceNode); /// writer.writeNode("target", targetNode); /// /// writer.writeUEdge("observed", uEdge); ///\endcode /// /// After you give all write commands you must call the \c run() member /// function, which executes all the writing commands. /// ///\code /// writer.run(); ///\endcode /// /// \see DefaultWriterTraits /// \see QuotedStringWriter /// \see IdMap /// \see DescriptorMap /// \see \ref GraphWriter /// \see \ref graph-io-page /// \author Balazs Dezso template class UGraphWriter { public: typedef _Graph Graph; typedef typename Graph::Node Node; typedef typename Graph::Edge Edge; typedef typename Graph::UEdge UEdge; typedef _WriterTraits WriterTraits; /// \brief Construct a new UGraphWriter. /// /// Construct a new UGraphWriter. It writes the given graph /// to the given stream. UGraphWriter(std::ostream& _os, const Graph& _graph) : writer(new LemonWriter(_os)), own_writer(true), nodeset_writer(*writer, _graph, std::string()), u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), node_writer(*writer, nodeset_writer, std::string()), u_edge_writer(*writer, u_edgeset_writer, std::string()), attribute_writer(*writer, std::string()) {} /// \brief Construct a new UGraphWriter. /// /// Construct a new UGraphWriter. It writes the given graph /// to the given file. UGraphWriter(const std::string& _filename, const Graph& _graph) : writer(new LemonWriter(_filename)), own_writer(true), nodeset_writer(*writer, _graph, std::string()), u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), node_writer(*writer, nodeset_writer, std::string()), u_edge_writer(*writer, u_edgeset_writer, std::string()), attribute_writer(*writer, std::string()) {} /// \brief Construct a new UGraphWriter. /// /// Construct a new UGraphWriter. It writes the given graph /// to given LemonReader. UGraphWriter(LemonWriter& _writer, const Graph& _graph) : writer(_writer), own_writer(false), nodeset_writer(*writer, _graph, std::string()), u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), node_writer(*writer, nodeset_writer, std::string()), u_edge_writer(*writer, u_edgeset_writer, std::string()), attribute_writer(*writer, std::string()) {} /// \brief Destruct the graph writer. /// /// Destruct the graph writer. ~UGraphWriter() { if (own_writer) delete writer; } /// \brief Issue a new node map writing command to the writer. /// /// This function issues a new node map writing command to the writer. template UGraphWriter& writeNodeMap(std::string name, const Map& map) { nodeset_writer.writeNodeMap(name, map); return *this; } /// \brief Issue a new node map writing command to the writer. /// /// This function issues a new node map writing command to the writer. template UGraphWriter& writeNodeMap(std::string name, const Map& map, const Writer& writer = Writer()) { nodeset_writer.writeNodeMap(name, map, writer); return *this; } /// \brief Issue a new edge map writing command to the writer. /// /// This function issues a new edge map writing command to the writer. template UGraphWriter& writeEdgeMap(std::string name, const Map& map) { u_edgeset_writer.writeEdgeMap(name, map); return *this; } /// \brief Issue a new edge map writing command to the writer. /// /// This function issues a new edge map writing command to the writer. template UGraphWriter& writeEdgeMap(std::string name, const Map& map, const Writer& writer = Writer()) { u_edgeset_writer.writeEdgeMap(name, map, writer); return *this; } /// \brief Issue a new undirected edge map writing command to the writer. /// /// This function issues a new undirected edge map writing /// command to the writer. template UGraphWriter& writeUEdgeMap(std::string name, const Map& map) { u_edgeset_writer.writeUEdgeMap(name, map); return *this; } /// \brief Issue a new undirected edge map writing command to the writer. /// /// This function issues a new undirected edge map writing /// command to the writer. template UGraphWriter& writeUEdgeMap(std::string name, const Map& map, const Writer& writer = Writer()) { u_edgeset_writer.writeUEdgeMap(name, map, writer); return *this; } /// \brief Issue a new labeled node writer to the writer. /// /// This function issues a new labeled node writing /// command to the writer. UGraphWriter& writeNode(std::string name, const Node& node) { node_writer.writeNode(name, node); return *this; } /// \brief Issue a new labeled edge writer to the writer. /// /// This function issues a new labeled edge writing /// command to the writer. UGraphWriter& writeEdge(std::string name, const Edge& edge) { u_edge_writer.writeEdge(name, edge); } /// \brief Issue a new labeled undirected edge writing command to /// the writer. /// /// Issue a new labeled undirected edge writing command to /// the writer. UGraphWriter& writeUEdge(std::string name, const UEdge& edge) { u_edge_writer.writeUEdge(name, edge); } /// \brief Issue a new attribute writing command. /// /// This function issues a new attribute writing /// command to the writer. template UGraphWriter& writeAttribute(std::string name, const Value& value) { attribute_writer.writeAttribute(name, value); return *this; } /// \brief Issue a new attribute writing command. /// /// This function issues a new attribute writing /// command to the writer. template UGraphWriter& writeAttribute(std::string name, const Value& value, const Writer& writer) { attribute_writer.writeAttribute(name, value, writer); return *this; } /// \brief Conversion operator to LemonWriter. /// /// Conversion operator to LemonWriter. It makes possible /// to access the encapsulated \e LemonWriter, this way /// you can attach to this writer new instances of /// \e LemonWriter::SectionWriter. operator LemonWriter&() { return *writer; } /// \brief Executes the writing commands. /// /// Executes the writing commands. void run() { writer->run(); } /// \brief Write the label of the given node. /// /// It writes the label of the given node. If there was written an "label" /// named node map then it will write the map value belonging to the node. void writeLabel(std::ostream& os, const Node& item) const { nodeset_writer.writeLabel(os, item); } /// \brief Write the label of the given edge. /// /// It writes the label of the given edge. If there was written an "label" /// named edge map then it will write the map value belonging to the edge. void writeLabel(std::ostream& os, const Edge& item) const { u_edgeset_writer.writeLabel(os, item); } /// \brief Write the label of the given undirected edge. /// /// It writes the label of the given undirected edge. If there was written /// an "label" named edge map then it will write the map value belonging to /// the edge. void writeLabel(std::ostream& os, const UEdge& item) const { u_edgeset_writer.writeLabel(os, item); } private: LemonWriter* writer; bool own_writer; NodeSetWriter nodeset_writer; UEdgeSetWriter u_edgeset_writer; NodeWriter node_writer; UEdgeWriter u_edge_writer; AttributeWriter attribute_writer; }; /// \brief Write an undirected graph to the output. /// /// It is a helper function to write an undirected graph to the given output /// stream. It gives back an UGraphWriter object and this object /// can write more maps, labeled nodes and edges and attributes. /// \warning Do not forget to call the \c run() function. /// /// \param os The output stream. /// \param g The graph. template UGraphWriter uGraphWriter(std::ostream& os, const Graph &g) { return UGraphWriter(os, g); } /// \brief Write an undirected graph to the output. /// /// It is a helper function to write an undirected graph to the given output /// file. It gives back an UGraphWriter object and this object /// can write more maps, labeled nodes, edges, undirected edges and /// attributes. /// /// \warning Do not forget to call the \c run() function. /// /// \param fn The output file. /// \param g The graph. template UGraphWriter uGraphWriter(const std::string& fn, const Graph &g) { return UGraphWriter(fn, g); } /// @} } #endif