deba@1137: /* -*- C++ -*- deba@1137: * alpar@1956: * This file is a part of LEMON, a generic C++ optimization library alpar@1956: * alpar@2553: * Copyright (C) 2003-2008 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: /// deba@2502: /// This function issues a new node map writing command to the writer. deba@1137: template deba@2386: GraphWriter& writeNodeMap(std::string label, const Map& map) { deba@2386: nodeset_writer.writeNodeMap(label, 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: /// deba@2502: /// This function issues a new node map writing command to the writer. deba@2386: template deba@2386: GraphWriter& writeNodeMap(std::string label, const Map& map, deba@2386: const ItemWriter& iw = ItemWriter()) { deba@2386: nodeset_writer.writeNodeMap(label, map, iw); 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@2386: GraphWriter& writeEdgeMap(std::string label, const Map& map) { deba@2386: edgeset_writer.writeEdgeMap(label, 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@2386: template deba@2386: GraphWriter& writeEdgeMap(std::string label, const Map& map, deba@2386: const ItemWriter& iw = ItemWriter()) { deba@2386: edgeset_writer.writeEdgeMap(label, map, iw); 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@2386: GraphWriter& writeNode(std::string label, const Node& node) { deba@2386: node_writer.writeNode(label, 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@2386: GraphWriter& writeEdge(std::string label, const Edge& edge) { deba@2386: edge_writer.writeEdge(label, 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@2386: GraphWriter& writeAttribute(std::string label, const Value& value) { deba@2386: attribute_writer.writeAttribute(label, 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@2386: template deba@2386: GraphWriter& writeAttribute(std::string label, const Value& value, deba@2386: const ItemWriter& iw = ItemWriter()) { deba@2386: attribute_writer.writeAttribute(label, value, iw); 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@2467: /// \brief Returns true if the writer can give back the labels by the items. deba@2467: /// deba@2467: /// Returns true if the writer can give back the the labels by the items. deba@2467: bool isLabelWriter() const { deba@2467: return nodeset_writer.isLabelWriter() && deba@2467: edgeset_writer.isLabelWriter(); deba@2467: } deba@2467: deba@1901: /// \brief Write the label of the given node. deba@1429: /// deba@2467: /// It writes the label of the given node. If there was written a "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@2467: /// It writes the label of the given edge. If there was written a "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@2467: /// \brief Sorts the given node vector by label. deba@2467: /// deba@2467: /// Sorts the given node vector by label. If there was written an deba@2467: /// "label" named map then the vector will be sorted by the values deba@2467: /// of this map. Otherwise if the \c forceLabel parameter was true deba@2467: /// it will be sorted by its id in the graph. deba@2467: void sortByLabel(std::vector& nodes) const { deba@2467: nodeset_writer.sortByLabel(nodes); deba@2467: } deba@2467: deba@2467: /// \brief Sorts the given edge vector by label. deba@2467: /// deba@2467: /// Sorts the given edge vector by label. If there was written an deba@2467: /// "label" named map then the vector will be sorted by the values deba@2467: /// of this map. Otherwise if the \c forceLabel parameter was true deba@2467: /// it will be sorted by its id in the graph. deba@2467: void sortByLabel(std::vector& edges) const { deba@2467: edgeset_writer.sortByLabel(edges); deba@2467: } deba@2467: 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()), deba@2467: uedgeset_writer(*writer, _graph, nodeset_writer, std::string()), deba@1421: node_writer(*writer, nodeset_writer, std::string()), deba@2467: uedge_writer(*writer, uedgeset_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()), deba@2467: uedgeset_writer(*writer, _graph, nodeset_writer, std::string()), deba@1421: node_writer(*writer, nodeset_writer, std::string()), deba@2467: uedge_writer(*writer, uedgeset_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@2467: /// to given LemonWriter. klao@1909: UGraphWriter(LemonWriter& _writer, const Graph& _graph) deba@1421: : writer(_writer), own_writer(false), deba@1421: nodeset_writer(*writer, _graph, std::string()), deba@2467: uedgeset_writer(*writer, _graph, nodeset_writer, std::string()), deba@1421: node_writer(*writer, nodeset_writer, std::string()), deba@2467: uedge_writer(*writer, uedgeset_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 deba@2386: UGraphWriter& writeNodeMap(std::string label, const Map& map) { deba@2386: nodeset_writer.writeNodeMap(label, 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@2386: template deba@2386: UGraphWriter& writeNodeMap(std::string label, const Map& map, deba@2386: const ItemWriter& iw = ItemWriter()) { deba@2386: nodeset_writer.writeNodeMap(label, map, iw); 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 deba@2386: UGraphWriter& writeEdgeMap(std::string label, const Map& map) { deba@2467: uedgeset_writer.writeEdgeMap(label, 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@2386: template deba@2386: UGraphWriter& writeEdgeMap(std::string label, const Map& map, deba@2386: const ItemWriter& iw = ItemWriter()) { deba@2467: uedgeset_writer.writeEdgeMap(label, map, iw); 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 deba@2386: UGraphWriter& writeUEdgeMap(std::string label, const Map& map) { deba@2467: uedgeset_writer.writeUEdgeMap(label, 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. deba@2386: template deba@2386: UGraphWriter& writeUEdgeMap(std::string label, const Map& map, deba@2386: const ItemWriter& iw = ItemWriter()) { deba@2467: uedgeset_writer.writeUEdgeMap(label, map, iw); 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. deba@2386: UGraphWriter& writeNode(std::string label, const Node& node) { deba@2386: node_writer.writeNode(label, 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. deba@2386: UGraphWriter& writeEdge(std::string label, const Edge& edge) { deba@2467: uedge_writer.writeEdge(label, 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. deba@2386: UGraphWriter& writeUEdge(std::string label, const UEdge& edge) { deba@2467: uedge_writer.writeUEdge(label, 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 deba@2386: UGraphWriter& writeAttribute(std::string label, const Value& value) { deba@2386: attribute_writer.writeAttribute(label, 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@2386: template deba@2386: UGraphWriter& writeAttribute(std::string label, const Value& value, deba@2386: const ItemWriter& iw = ItemWriter()) { deba@2386: attribute_writer.writeAttribute(label, value, iw); 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@2467: /// \brief Returns true if the writer can give back the labels by the items. deba@2467: /// deba@2467: /// Returns true if the writer can give back the the labels by the items. deba@2467: bool isLabelWriter() const { deba@2467: return nodeset_writer.isLabelWriter() && deba@2467: uedgeset_writer.isLabelWriter(); deba@2467: } deba@2467: deba@1901: /// \brief Write the label of the given node. deba@1429: /// deba@2467: /// It writes the label of the given node. If there was written a "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@2467: /// It writes the label of the given edge. If there was written a "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@2467: uedgeset_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@2467: /// written a "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 { deba@2467: uedgeset_writer.writeLabel(os, item); deba@1429: } deba@1429: deba@2467: /// \brief Sorts the given node vector by label. deba@2467: /// deba@2467: /// Sorts the given node vector by label. If there was written an deba@2467: /// "label" named map then the vector will be sorted by the values deba@2467: /// of this map. Otherwise if the \c forceLabel parameter was true deba@2467: /// it will be sorted by its id in the graph. deba@2467: void sortByLabel(std::vector& nodes) const { deba@2467: nodeset_writer.sortByLabel(nodes); deba@2467: } deba@2467: deba@2467: /// \brief Sorts the given edge vector by label. deba@2467: /// deba@2467: /// Sorts the given edge vector by label. If there was written an deba@2467: /// "label" named map then the vector will be sorted by the values deba@2467: /// of this map. Otherwise if the \c forceLabel parameter was true deba@2467: /// it will be sorted by its id in the graph. deba@2467: void sortByLabel(std::vector& edges) const { deba@2467: uedgeset_writer.sortByLabel(edges); deba@2467: } deba@2467: deba@2467: /// \brief Sorts the given undirected edge vector by label. deba@2467: /// deba@2467: /// Sorts the given undirected edge vector by label. If there was deba@2467: /// written an "label" named map then the vector will be sorted by deba@2467: /// the values of this map. Otherwise if the \c forceLabel deba@2467: /// parameter was true it will be sorted by its id in the graph. deba@2467: void sortByLabel(std::vector& uedges) const { deba@2467: uedgeset_writer.sortByLabel(uedges); deba@2467: } deba@1429: deba@1421: private: deba@1421: deba@1421: LemonWriter* writer; deba@1421: bool own_writer; deba@1421: deba@1421: NodeSetWriter nodeset_writer; deba@2467: UEdgeSetWriter uedgeset_writer; deba@1421: deba@1421: NodeWriter node_writer; deba@2467: UEdgeWriter uedge_writer; deba@1421: deba@1421: AttributeWriter attribute_writer; deba@1421: }; deba@1421: deba@2502: /// \brief The bipartite graph writer class. deba@2502: /// deba@2502: /// The \c BpUGraphWriter class provides the ugraph output. To write deba@2502: /// a graph you should first give writing commands to the writer. You can deba@2502: /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap deba@2502: /// writing and labeled Node, Edge or UEdge writing. deba@2502: /// deba@2502: ///\code deba@2502: /// BpUGraphWriter writer(std::cout, graph); deba@2502: ///\endcode deba@2502: /// deba@2502: /// The \c writeNodeMap() function declares a \c NodeMap writing deba@2502: /// command in the \c BpUGraphWriter. You should give as parameter deba@2502: /// the name of the map and the map object. The NodeMap writing deba@2502: /// command with name "label" should write a unique map because it deba@2502: /// is regarded as label map. deba@2502: /// deba@2502: ///\code deba@2502: /// IdMap nodeLabelMap; deba@2502: /// writer.writeNodeMap("label", nodeLabelMap); deba@2502: /// deba@2502: /// writer.writeNodeMap("coords", coords); deba@2502: /// writer.writeNodeMap("color", colorMap); deba@2502: ///\endcode deba@2502: /// deba@2502: /// With the \c writeUEdgeMap() member function you can give an deba@2502: /// undirected edge map writing command similar to the NodeMaps. deba@2502: /// deba@2502: ///\code deba@2502: /// DescriptorMap > deba@2502: /// edgeDescMap(graph); deba@2502: /// writer.writeUEdgeMap("descriptor", edgeDescMap); deba@2502: /// deba@2502: /// writer.writeUEdgeMap("weight", weightMap); deba@2502: /// writer.writeUEdgeMap("label", labelMap); deba@2502: ///\endcode deba@2502: /// deba@2502: /// The EdgeMap handling is just a syntactical sugar. It writes deba@2502: /// two undirected edge map with '+' and '-' prefix in the name. deba@2502: /// deba@2502: ///\code deba@2502: /// writer.writeEdgeMap("capacity", capacityMap); deba@2502: ///\endcode deba@2502: /// deba@2502: /// deba@2502: /// With \c writeNode() and \c writeUEdge() functions you can deba@2502: /// designate nodes and undirected edges in the graph. For example, you can deba@2502: /// write out the source and target of the graph. deba@2502: /// deba@2502: ///\code deba@2502: /// writer.writeNode("source", sourceNode); deba@2502: /// writer.writeNode("target", targetNode); deba@2502: /// deba@2502: /// writer.writeUEdge("observed", uEdge); deba@2502: ///\endcode deba@2502: /// deba@2502: /// After you give all write commands you must call the \c run() member deba@2502: /// function, which executes all the writing commands. deba@2502: /// deba@2502: ///\code deba@2502: /// writer.run(); deba@2502: ///\endcode deba@2502: /// deba@2502: /// \see DefaultWriterTraits deba@2502: /// \see QuotedStringWriter deba@2502: /// \see IdMap deba@2502: /// \see DescriptorMap deba@2502: /// \see \ref GraphWriter deba@2502: /// \see \ref graph-io-page deba@2502: /// \author Balazs Dezso deba@2502: template deba@2502: class BpUGraphWriter { deba@2502: public: deba@2502: deba@2502: typedef _Graph Graph; deba@2502: typedef typename Graph::Node Node; deba@2502: typedef typename Graph::Edge Edge; deba@2502: typedef typename Graph::UEdge UEdge; deba@2502: deba@2502: typedef _WriterTraits WriterTraits; deba@2502: deba@2502: /// \brief Construct a new BpUGraphWriter. deba@2502: /// deba@2502: /// Construct a new BpUGraphWriter. It writes the given graph deba@2502: /// to the given stream. deba@2502: BpUGraphWriter(std::ostream& _os, const Graph& _graph) deba@2502: : writer(new LemonWriter(_os)), own_writer(true), deba@2502: nodeset_writer(*writer, _graph, std::string()), deba@2502: uedgeset_writer(*writer, _graph, nodeset_writer, std::string()), deba@2502: node_writer(*writer, nodeset_writer, std::string()), deba@2502: uedge_writer(*writer, uedgeset_writer, std::string()), deba@2502: attribute_writer(*writer, std::string()) {} deba@2502: deba@2502: /// \brief Construct a new BpUGraphWriter. deba@2502: /// deba@2502: /// Construct a new BpUGraphWriter. It writes the given graph deba@2502: /// to the given file. deba@2502: BpUGraphWriter(const std::string& _filename, const Graph& _graph) deba@2502: : writer(new LemonWriter(_filename)), own_writer(true), deba@2502: nodeset_writer(*writer, _graph, std::string()), deba@2502: uedgeset_writer(*writer, _graph, nodeset_writer, std::string()), deba@2502: node_writer(*writer, nodeset_writer, std::string()), deba@2502: uedge_writer(*writer, uedgeset_writer, std::string()), deba@2502: attribute_writer(*writer, std::string()) {} deba@2502: deba@2502: /// \brief Construct a new BpUGraphWriter. deba@2502: /// deba@2502: /// Construct a new BpUGraphWriter. It writes the given graph deba@2502: /// to given LemonWriter. deba@2502: BpUGraphWriter(LemonWriter& _writer, const Graph& _graph) deba@2502: : writer(_writer), own_writer(false), deba@2502: nodeset_writer(*writer, _graph, std::string()), deba@2502: uedgeset_writer(*writer, _graph, nodeset_writer, std::string()), deba@2502: node_writer(*writer, nodeset_writer, std::string()), deba@2502: uedge_writer(*writer, uedgeset_writer, std::string()), deba@2502: attribute_writer(*writer, std::string()) {} deba@2502: deba@2502: /// \brief Destruct the graph writer. deba@2502: /// deba@2502: /// Destruct the graph writer. deba@2502: ~BpUGraphWriter() { deba@2502: if (own_writer) deba@2502: delete writer; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new node map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new node map writing command to deba@2502: /// the writer. deba@2502: template deba@2502: BpUGraphWriter& writeNodeMap(std::string label, const Map& map) { deba@2502: nodeset_writer.writeNodeMap(label, map); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new node map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new node map writing command to deba@2502: /// the writer. deba@2502: template deba@2502: BpUGraphWriter& writeNodeMap(std::string label, const Map& map, deba@2502: const ItemWriter& iw = ItemWriter()) { deba@2502: nodeset_writer.writeNodeMap(label, map, iw); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new A-node map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new A-node map writing command to deba@2502: /// the writer. deba@2502: template deba@2502: BpUGraphWriter& writeANodeMap(std::string label, const Map& map) { deba@2502: nodeset_writer.writeANodeMap(label, map); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new A-node map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new A-node map writing command to deba@2502: /// the writer. deba@2502: template deba@2502: BpUGraphWriter& writeANodeMap(std::string label, const Map& map, deba@2502: const ItemWriter& iw = ItemWriter()) { deba@2502: nodeset_writer.writeANodeMap(label, map, iw); deba@2502: return *this; deba@2502: } deba@2502: /// \brief Issue a new B-node map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new B-node map writing command to deba@2502: /// the writer. deba@2502: template deba@2502: BpUGraphWriter& writeBNodeMap(std::string label, const Map& map) { deba@2502: nodeset_writer.writeBNodeMap(label, map); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new B-node map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new B-node map writing command to deba@2502: /// the writer. deba@2502: template deba@2502: BpUGraphWriter& writeBNodeMap(std::string label, const Map& map, deba@2502: const ItemWriter& iw = ItemWriter()) { deba@2502: nodeset_writer.writeBNodeMap(label, map, iw); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new edge map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new edge map writing command to deba@2502: /// the writer. deba@2502: template deba@2502: BpUGraphWriter& writeEdgeMap(std::string label, const Map& map) { deba@2502: uedgeset_writer.writeEdgeMap(label, map); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new edge map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new edge map writing command to deba@2502: /// the writer. deba@2502: template deba@2502: BpUGraphWriter& writeEdgeMap(std::string label, const Map& map, deba@2502: const ItemWriter& iw = ItemWriter()) { deba@2502: uedgeset_writer.writeEdgeMap(label, map, iw); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new undirected edge map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new undirected edge map writing deba@2502: /// command to the writer. deba@2502: template deba@2502: BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map) { deba@2502: uedgeset_writer.writeUEdgeMap(label, map); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new undirected edge map writing command to the writer. deba@2502: /// deba@2502: /// This function issues a new undirected edge map writing deba@2502: /// command to the writer. deba@2502: template deba@2502: BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map, deba@2502: const ItemWriter& iw = ItemWriter()) { deba@2502: uedgeset_writer.writeUEdgeMap(label, map, iw); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new labeled node writer to the writer. deba@2502: /// deba@2502: /// This function issues a new labeled node writing deba@2502: /// command to the writer. deba@2502: BpUGraphWriter& writeNode(std::string label, const Node& node) { deba@2502: node_writer.writeNode(label, node); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new labeled edge writer to the writer. deba@2502: /// deba@2502: /// This function issues a new labeled edge writing deba@2502: /// command to the writer. deba@2502: BpUGraphWriter& writeEdge(std::string label, const Edge& edge) { deba@2502: uedge_writer.writeEdge(label, edge); deba@2502: } deba@2502: deba@2502: /// \brief Issue a new labeled undirected edge writing command to deba@2502: /// the writer. deba@2502: /// deba@2502: /// Issue a new labeled undirected edge writing command to deba@2502: /// the writer. deba@2502: BpUGraphWriter& writeUEdge(std::string label, const UEdge& edge) { deba@2502: uedge_writer.writeUEdge(label, edge); deba@2502: } deba@2502: deba@2502: /// \brief Issue a new attribute writing command. deba@2502: /// deba@2502: /// This function issues a new attribute writing deba@2502: /// command to the writer. deba@2502: template deba@2502: BpUGraphWriter& writeAttribute(std::string label, const Value& value) { deba@2502: attribute_writer.writeAttribute(label, value); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Issue a new attribute writing command. deba@2502: /// deba@2502: /// This function issues a new attribute writing deba@2502: /// command to the writer. deba@2502: template deba@2502: BpUGraphWriter& writeAttribute(std::string label, const Value& value, deba@2502: const ItemWriter& iw = ItemWriter()) { deba@2502: attribute_writer.writeAttribute(label, value, iw); deba@2502: return *this; deba@2502: } deba@2502: deba@2502: /// \brief Conversion operator to LemonWriter. deba@2502: /// deba@2502: /// Conversion operator to LemonWriter. It makes possible deba@2502: /// to access the encapsulated \e LemonWriter, this way deba@2502: /// you can attach to this writer new instances of deba@2502: /// \e LemonWriter::SectionWriter. deba@2502: operator LemonWriter&() { deba@2502: return *writer; deba@2502: } deba@2502: deba@2502: /// \brief Executes the writing commands. deba@2502: /// deba@2502: /// Executes the writing commands. deba@2502: void run() { deba@2502: writer->run(); deba@2502: } deba@2502: deba@2502: /// \brief Returns true if the writer can give back the labels by the items. deba@2502: /// deba@2502: /// Returns true if the writer can give back the the labels by the items. deba@2502: bool isLabelWriter() const { deba@2502: return nodeset_writer.isLabelWriter() && deba@2502: uedgeset_writer.isLabelWriter(); deba@2502: } deba@2502: deba@2502: /// \brief Write the label of the given node. deba@2502: /// deba@2502: /// It writes the label of the given node. If there was written a "label" deba@2502: /// named node map then it will write the map value belonging to the node. deba@2502: void writeLabel(std::ostream& os, const Node& item) const { deba@2502: nodeset_writer.writeLabel(os, item); deba@2502: } deba@2502: deba@2502: /// \brief Write the label of the given edge. deba@2502: /// deba@2502: /// It writes the label of the given edge. If there was written a "label" deba@2502: /// named edge map then it will write the map value belonging to the edge. deba@2502: void writeLabel(std::ostream& os, const Edge& item) const { deba@2502: uedgeset_writer.writeLabel(os, item); deba@2502: } deba@2502: deba@2502: /// \brief Write the label of the given undirected edge. deba@2502: /// deba@2502: /// It writes the label of the given undirected edge. If there was deba@2502: /// written a "label" named edge map then it will write the map deba@2502: /// value belonging to the edge. deba@2502: void writeLabel(std::ostream& os, const UEdge& item) const { deba@2502: uedgeset_writer.writeLabel(os, item); deba@2502: } deba@2502: deba@2502: /// \brief Sorts the given node vector by label. deba@2502: /// deba@2502: /// Sorts the given node vector by label. If there was written an deba@2502: /// "label" named map then the vector will be sorted by the values deba@2502: /// of this map. Otherwise if the \c forceLabel parameter was true deba@2502: /// it will be sorted by its id in the graph. deba@2502: void sortByLabel(std::vector& nodes) const { deba@2502: nodeset_writer.sortByLabel(nodes); deba@2502: } deba@2502: deba@2502: /// \brief Sorts the given edge vector by label. deba@2502: /// deba@2502: /// Sorts the given edge vector by label. If there was written an deba@2502: /// "label" named map then the vector will be sorted by the values deba@2502: /// of this map. Otherwise if the \c forceLabel parameter was true deba@2502: /// it will be sorted by its id in the graph. deba@2502: void sortByLabel(std::vector& edges) const { deba@2502: uedgeset_writer.sortByLabel(edges); deba@2502: } deba@2502: deba@2502: /// \brief Sorts the given undirected edge vector by label. deba@2502: /// deba@2502: /// Sorts the given undirected edge vector by label. If there was deba@2502: /// written an "label" named map then the vector will be sorted by deba@2502: /// the values of this map. Otherwise if the \c forceLabel deba@2502: /// parameter was true it will be sorted by its id in the graph. deba@2502: void sortByLabel(std::vector& uedges) const { deba@2502: uedgeset_writer.sortByLabel(uedges); deba@2502: } deba@2502: deba@2502: private: deba@2502: deba@2502: LemonWriter* writer; deba@2502: bool own_writer; deba@2502: deba@2502: BpNodeSetWriter nodeset_writer; deba@2502: UEdgeSetWriter uedgeset_writer; deba@2502: deba@2502: NodeWriter node_writer; deba@2502: UEdgeWriter uedge_writer; deba@2502: deba@2502: AttributeWriter attribute_writer; deba@2502: }; deba@2502: deba@1333: /// @} deba@1137: deba@1137: } deba@1214: deba@1214: #endif