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