lemon/graph_writer.h
author deba
Fri, 19 Oct 2007 15:21:07 +0000
changeset 2498 290e43cddc1a
parent 2391 14a343be7a5a
child 2502 9c23c3762bc5
permissions -rw-r--r--
Bug fix in undirected graphs (adding loops)
Bug fix in undirected edgesets (alteration notifying)

Redesigned undirected edgesets (like the smart or ugraph)
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2007
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 ///\ingroup lemon_io
    20 ///\file
    21 ///\brief Lemon Graph Format writer.
    22 ///
    23 
    24 #ifndef LEMON_GRAPH_WRITER_H
    25 #define LEMON_GRAPH_WRITER_H
    26 
    27 #include <iostream>
    28 
    29 #include <lemon/error.h>
    30 #include <lemon/lemon_writer.h>
    31 
    32 namespace lemon {
    33 
    34   /// \addtogroup lemon_io
    35   /// @{
    36 
    37   /// \brief The graph writer class.
    38   ///
    39   /// The \c GraphWriter class provides the graph output.  Before you
    40   /// read this documentation it might be useful to read the general
    41   /// description of \ref graph-io-page "Graph Input-Output".
    42   ///
    43   /// To write a graph you should first give writing commands to the
    44   /// writer. You can declare write commands as \c NodeMap or \c
    45   /// EdgeMap writing and labeled Node and Edge writing.
    46   ///
    47   ///\code
    48   /// GraphWriter<ListGraph> writer(std::cout, graph);
    49   ///\endcode
    50   ///
    51   /// The \c writeNodeMap() function declares a \c NodeMap writing
    52   /// command in the \c GraphWriter. You should give as parameter the
    53   /// name of the map and the map object. The NodeMap writing command
    54   /// with name "label" should write a unique map because it is
    55   /// regarded as label map (such a map is essential if the graph has
    56   /// edges).
    57   ///
    58   ///\code
    59   /// IdMap<ListGraph, Node> nodeLabelMap;
    60   /// writer.writeNodeMap("label", nodeLabelMap);
    61   ///
    62   /// writer.writeNodeMap("coords", coords);
    63   /// writer.writeNodeMap("color", colorMap);
    64   ///\endcode
    65   ///
    66   /// With the \c writeEdgeMap() member function you can give an edge map
    67   /// writing command similar to the NodeMaps.
    68   ///
    69   ///\code
    70   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
    71   ///   edgeDescMap(graph);
    72   /// writer.writeEdgeMap("descriptor", edgeDescMap);
    73   ///
    74   /// writer.writeEdgeMap("weight", weightMap);
    75   /// writer.writeEdgeMap("label", labelMap);
    76   ///\endcode
    77   ///
    78   /// With \c writeNode() and \c writeEdge() functions you can 
    79   /// point out Nodes and Edges in the graph. For example, you can 
    80   /// write out the source and target of a maximum flow instance.
    81   ///
    82   ///\code
    83   /// writer.writeNode("source", sourceNode);
    84   /// writer.writeNode("target", targetNode);
    85   ///
    86   /// writer.writeEdge("observed", edge);
    87   ///\endcode
    88   ///
    89   /// After you give all write commands you must call the \c run() member
    90   /// function, which executes all the writing commands.
    91   ///
    92   ///\code
    93   /// writer.run();
    94   ///\endcode
    95   ///
    96   /// \see DefaultWriterTraits
    97   /// \see QuotedStringWriter
    98   /// \see IdMap
    99   /// \see DescriptorMap
   100   /// \see \ref GraphReader
   101   /// \see \ref graph-io-page
   102   /// \author Balazs Dezso
   103   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   104   class GraphWriter {
   105   public:
   106     
   107     typedef _Graph Graph;
   108     typedef typename Graph::Node Node;
   109     typedef typename Graph::Edge Edge;
   110 
   111     typedef _WriterTraits WriterTraits;
   112 
   113     /// \brief Construct a new GraphWriter.
   114     ///
   115     /// This function constructs a new GraphWriter to write the given graph
   116     /// to the given stream.
   117     GraphWriter(std::ostream& _os, const Graph& _graph) 
   118       : writer(new LemonWriter(_os)), own_writer(true), 
   119 	nodeset_writer(*writer, _graph, std::string()),
   120 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   121 	node_writer(*writer, nodeset_writer, std::string()),
   122 	edge_writer(*writer, edgeset_writer, std::string()),
   123 	attribute_writer(*writer, std::string()) {}
   124 
   125     /// \brief Construct a new GraphWriter.
   126     ///
   127     /// This function constructs a new GraphWriter to write the given graph
   128     /// to the given file.
   129     GraphWriter(const std::string& _filename, const Graph& _graph) 
   130       : writer(new LemonWriter(_filename)), own_writer(true), 
   131 	nodeset_writer(*writer, _graph, std::string()),
   132 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   133 	node_writer(*writer, nodeset_writer, std::string()),
   134 	edge_writer(*writer, edgeset_writer, std::string()),
   135 	attribute_writer(*writer, std::string()) {}
   136 
   137     /// \brief Construct a new GraphWriter.
   138     ///
   139     /// This function constructs a new GraphWriter to write the given graph
   140     /// to the given LemonReader.
   141     GraphWriter(LemonWriter& _writer, const Graph& _graph)
   142       : writer(_writer), own_writer(false), 
   143 	nodeset_writer(*writer, _graph, std::string()),
   144 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   145 	node_writer(*writer, nodeset_writer, std::string()),
   146 	edge_writer(*writer, edgeset_writer, std::string()),
   147 	attribute_writer(*writer, std::string()) {}
   148 
   149     /// \brief Destruct the graph writer.
   150     ///
   151     /// This function destructs the graph writer.
   152     ~GraphWriter() {
   153       if (own_writer) 
   154 	delete writer;
   155     }
   156 
   157     /// \brief Issue a new node map writing command for the writer.
   158     ///
   159    /// This function issues a new <i> node map writing command</i> to the writer.
   160     template <typename Map>
   161     GraphWriter& writeNodeMap(std::string label, const Map& map) {
   162       nodeset_writer.writeNodeMap(label, map);
   163       return *this;
   164     }
   165 
   166 
   167     /// \brief Issue a new node map writing command for the writer.
   168     ///
   169    /// This function issues a new <i> node map writing command</i> to the writer.
   170     template <typename ItemWriter, typename Map>
   171     GraphWriter& writeNodeMap(std::string label, const Map& map, 
   172 			      const ItemWriter& iw = ItemWriter()) {
   173       nodeset_writer.writeNodeMap(label, map, iw);
   174       return *this;
   175     }
   176 
   177 
   178     /// \brief Issue a new edge map writing command for the writer.
   179     ///
   180    /// This function issues a new <i> edge map writing command</i> to the writer.
   181     template <typename Map>
   182     GraphWriter& writeEdgeMap(std::string label, const Map& map) { 
   183       edgeset_writer.writeEdgeMap(label, map);
   184       return *this;
   185     }
   186 
   187 
   188     /// \brief Issue a new edge map writing command for the writer.
   189     ///
   190    /// This function issues a new <i> edge map writing command</i> to the writer.
   191     template <typename ItemWriter, typename Map>
   192     GraphWriter& writeEdgeMap(std::string label, const Map& map,
   193 			      const ItemWriter& iw = ItemWriter()) {
   194       edgeset_writer.writeEdgeMap(label, map, iw);
   195       return *this;
   196     }
   197 
   198     /// \brief Issue a new labeled node writing command to the writer.
   199     ///
   200     /// This function issues a new <i> labeled node writing command</i> 
   201     /// to the writer.
   202     GraphWriter& writeNode(std::string label, const Node& node) {
   203       node_writer.writeNode(label, node);
   204       return *this;
   205     }
   206 
   207     /// \brief Issue a new labeled edge writing command to the writer.
   208     ///
   209     /// This function issues a new <i> labeled edge writing command</i> 
   210     /// to the writer.
   211     GraphWriter& writeEdge(std::string label, const Edge& edge) {
   212       edge_writer.writeEdge(label, edge);
   213     }
   214 
   215     /// \brief Issue a new attribute writing command.
   216     ///
   217     /// This function issues a new <i> attribute writing command</i> 
   218     /// to the writer.
   219     template <typename Value>
   220     GraphWriter& writeAttribute(std::string label, const Value& value) {
   221       attribute_writer.writeAttribute(label, value);
   222       return *this;
   223     }
   224     
   225     /// \brief Issue a new attribute writing command.
   226     ///
   227     /// This function issues a new <i> attribute writing command</i> 
   228     /// to the writer.
   229     template <typename ItemWriter, typename Value>
   230     GraphWriter& writeAttribute(std::string label, const Value& value, 
   231 			       const ItemWriter& iw = ItemWriter()) {
   232       attribute_writer.writeAttribute(label, value, iw);
   233       return *this;
   234     }
   235 
   236     /// \brief Conversion operator to LemonWriter.
   237     ///
   238     /// Conversion operator to LemonWriter. It makes possible
   239     /// to access the encapsulated \e LemonWriter, this way
   240     /// you can attach to this writer new instances of 
   241     /// \e LemonWriter::SectionWriter. For more details see
   242     /// the \ref rwbackground "Background of Reading and Writing".
   243     operator LemonWriter&() {
   244       return *writer;
   245     }
   246 
   247     /// \brief Executes the writing commands.
   248     ///
   249     /// Executes the writing commands.
   250     void run() {
   251       writer->run();
   252     }
   253 
   254     /// \brief Returns true if the writer can give back the labels by the items.
   255     ///
   256     /// Returns true if the writer can give back the the labels by the items.
   257     bool isLabelWriter() const {
   258       return nodeset_writer.isLabelWriter() && 
   259         edgeset_writer.isLabelWriter();
   260     }
   261 
   262     /// \brief Write the label of the given node.
   263     ///
   264     /// It writes the label of the given node. If there was written a "label"
   265     /// named node map then it will write the map value belonging to the node.
   266     void writeLabel(std::ostream& os, const Node& item) const {
   267       nodeset_writer.writeLabel(os, item);
   268     } 
   269 
   270     /// \brief Write the label of the given edge.
   271     ///
   272     /// It writes the label of the given edge. If there was written a "label"
   273     /// named edge map then it will write the map value belonging to the edge.
   274     void writeLabel(std::ostream& os, const Edge& item) const {
   275       edgeset_writer.writeLabel(os, item);
   276     } 
   277 
   278     /// \brief Sorts the given node vector by label.
   279     ///
   280     /// Sorts the given node vector by label. If there was written an
   281     /// "label" named map then the vector will be sorted by the values
   282     /// of this map. Otherwise if the \c forceLabel parameter was true
   283     /// it will be sorted by its id in the graph.
   284     void sortByLabel(std::vector<Node>& nodes) const {
   285       nodeset_writer.sortByLabel(nodes);
   286     }
   287 
   288     /// \brief Sorts the given edge vector by label.
   289     ///
   290     /// Sorts the given edge vector by label. If there was written an
   291     /// "label" named map then the vector will be sorted by the values
   292     /// of this map. Otherwise if the \c forceLabel parameter was true
   293     /// it will be sorted by its id in the graph.
   294     void sortByLabel(std::vector<Edge>& edges) const {
   295       edgeset_writer.sortByLabel(edges);
   296     }
   297 
   298   private:
   299 
   300     LemonWriter* writer;
   301     bool own_writer;
   302 
   303     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   304     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   305 
   306     NodeWriter<Graph> node_writer;
   307     EdgeWriter<Graph> edge_writer;
   308     
   309     AttributeWriter<WriterTraits> attribute_writer;
   310   };
   311 
   312 
   313   /// \brief The undirected graph writer class.
   314   ///
   315   /// The \c UGraphWriter class provides the ugraph output. To write 
   316   /// a graph you should first give writing commands to the writer. You can 
   317   /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap 
   318   /// writing and labeled Node, Edge or UEdge writing.
   319   ///
   320   ///\code
   321   /// UGraphWriter<ListUGraph> writer(std::cout, graph);
   322   ///\endcode
   323   ///
   324   /// The \c writeNodeMap() function declares a \c NodeMap writing 
   325   /// command in the \c UGraphWriter. You should give as parameter 
   326   /// the name of the map and the map object. The NodeMap writing 
   327   /// command with name "label" should write a unique map because it 
   328   /// is regarded as label map.
   329   ///
   330   ///\code
   331   /// IdMap<ListUGraph, Node> nodeLabelMap;
   332   /// writer.writeNodeMap("label", nodeLabelMap);
   333   ///
   334   /// writer.writeNodeMap("coords", coords);
   335   /// writer.writeNodeMap("color", colorMap);
   336   ///\endcode
   337   ///
   338   /// With the \c writeUEdgeMap() member function you can give an 
   339   /// undirected edge map writing command similar to the NodeMaps.
   340   ///
   341   ///\code
   342   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
   343   ///   edgeDescMap(graph);
   344   /// writer.writeUEdgeMap("descriptor", edgeDescMap);
   345   ///
   346   /// writer.writeUEdgeMap("weight", weightMap);
   347   /// writer.writeUEdgeMap("label", labelMap);
   348   ///\endcode
   349   /// 
   350   /// The EdgeMap handling is just a syntactical sugar. It writes
   351   /// two undirected edge map with '+' and '-' prefix in the name.
   352   ///
   353   ///\code
   354   /// writer.writeEdgeMap("capacity", capacityMap);
   355   ///\endcode
   356   ///
   357   ///
   358   /// With \c writeNode() and \c writeUEdge() functions you can 
   359   /// designate nodes and undirected edges in the graph. For example, you can 
   360   /// write out the source and target of the graph.
   361   ///
   362   ///\code
   363   /// writer.writeNode("source", sourceNode);
   364   /// writer.writeNode("target", targetNode);
   365   ///
   366   /// writer.writeUEdge("observed", uEdge);
   367   ///\endcode
   368   ///
   369   /// After you give all write commands you must call the \c run() member
   370   /// function, which executes all the writing commands.
   371   ///
   372   ///\code
   373   /// writer.run();
   374   ///\endcode
   375   ///
   376   /// \see DefaultWriterTraits
   377   /// \see QuotedStringWriter
   378   /// \see IdMap
   379   /// \see DescriptorMap
   380   /// \see \ref GraphWriter
   381   /// \see \ref graph-io-page
   382   /// \author Balazs Dezso
   383   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   384   class UGraphWriter {
   385   public:
   386     
   387     typedef _Graph Graph;
   388     typedef typename Graph::Node Node;
   389     typedef typename Graph::Edge Edge;
   390     typedef typename Graph::UEdge UEdge;
   391 
   392     typedef _WriterTraits WriterTraits;
   393 
   394     /// \brief Construct a new UGraphWriter.
   395     ///
   396     /// Construct a new UGraphWriter. It writes the given graph
   397     /// to the given stream.
   398     UGraphWriter(std::ostream& _os, const Graph& _graph) 
   399       : writer(new LemonWriter(_os)), own_writer(true), 
   400 	nodeset_writer(*writer, _graph, std::string()),
   401 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   402 	node_writer(*writer, nodeset_writer, std::string()),
   403 	uedge_writer(*writer, uedgeset_writer, std::string()),
   404 	attribute_writer(*writer, std::string()) {}
   405 
   406     /// \brief Construct a new UGraphWriter.
   407     ///
   408     /// Construct a new UGraphWriter. It writes the given graph
   409     /// to the given file.
   410     UGraphWriter(const std::string& _filename, const Graph& _graph) 
   411       : writer(new LemonWriter(_filename)), own_writer(true), 
   412 	nodeset_writer(*writer, _graph, std::string()),
   413 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   414 	node_writer(*writer, nodeset_writer, std::string()),
   415 	uedge_writer(*writer, uedgeset_writer, std::string()),
   416 	attribute_writer(*writer, std::string()) {}
   417 
   418     /// \brief Construct a new UGraphWriter.
   419     ///
   420     /// Construct a new UGraphWriter. It writes the given graph
   421     /// to given LemonWriter.
   422     UGraphWriter(LemonWriter& _writer, const Graph& _graph)
   423       : writer(_writer), own_writer(false), 
   424 	nodeset_writer(*writer, _graph, std::string()),
   425 	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   426 	node_writer(*writer, nodeset_writer, std::string()),
   427 	uedge_writer(*writer, uedgeset_writer, std::string()),
   428 	attribute_writer(*writer, std::string()) {}
   429 
   430     /// \brief Destruct the graph writer.
   431     ///
   432     /// Destruct the graph writer.
   433     ~UGraphWriter() {
   434       if (own_writer) 
   435 	delete writer;
   436     }
   437 
   438     /// \brief Issue a new node map writing command to the writer.
   439     ///
   440     /// This function issues a new <i> node map writing command</i> to
   441     /// the writer.
   442     template <typename Map>
   443     UGraphWriter& writeNodeMap(std::string label, const Map& map) {
   444       nodeset_writer.writeNodeMap(label, map);
   445       return *this;
   446     }
   447 
   448     /// \brief Issue a new node map writing command to the writer.
   449     ///
   450     /// This function issues a new <i> node map writing command</i> to
   451     /// the writer.
   452     template <typename ItemWriter, typename Map>
   453     UGraphWriter& writeNodeMap(std::string label, const Map& map, 
   454 			      const ItemWriter& iw = ItemWriter()) {
   455       nodeset_writer.writeNodeMap(label, map, iw);
   456       return *this;
   457     }
   458 
   459     /// \brief Issue a new edge map writing command to the writer.
   460     ///
   461     /// This function issues a new <i> edge map writing command</i> to
   462     /// the writer.
   463     template <typename Map>
   464     UGraphWriter& writeEdgeMap(std::string label, const Map& map) { 
   465       uedgeset_writer.writeEdgeMap(label, map);
   466       return *this;
   467     }
   468 
   469     /// \brief Issue a new edge map writing command to the writer.
   470     ///
   471     /// This function issues a new <i> edge map writing command</i> to
   472     /// the writer.
   473     template <typename ItemWriter, typename Map>
   474     UGraphWriter& writeEdgeMap(std::string label, const Map& map,
   475 				   const ItemWriter& iw = ItemWriter()) {
   476       uedgeset_writer.writeEdgeMap(label, map, iw);
   477       return *this;
   478     }
   479 
   480     /// \brief Issue a new undirected edge map writing command to the writer.
   481     ///
   482     /// This function issues a new <i> undirected edge map writing
   483     /// command</i> to the writer.
   484     template <typename Map>
   485     UGraphWriter& writeUEdgeMap(std::string label, const Map& map) { 
   486       uedgeset_writer.writeUEdgeMap(label, map);
   487       return *this;
   488     }
   489 
   490     /// \brief Issue a new undirected edge map writing command to the writer.
   491     ///
   492     /// This function issues a new <i> undirected edge map writing
   493     /// command</i> to the writer.
   494    template <typename ItemWriter, typename Map>
   495     UGraphWriter& writeUEdgeMap(std::string label, const Map& map,
   496 					const ItemWriter& iw = ItemWriter()) {
   497       uedgeset_writer.writeUEdgeMap(label, map, iw);
   498       return *this;
   499     }
   500 
   501     /// \brief Issue a new labeled node writer to the writer.
   502     ///
   503     /// This function issues a new <i> labeled node writing
   504     /// command</i> to the writer.
   505     UGraphWriter& writeNode(std::string label, const Node& node) {
   506       node_writer.writeNode(label, node);
   507       return *this;
   508     }
   509 
   510     /// \brief Issue a new labeled edge writer to the writer.
   511     ///
   512     /// This function issues a new <i> labeled edge writing
   513     /// command</i> to the writer.
   514     UGraphWriter& writeEdge(std::string label, const Edge& edge) {
   515       uedge_writer.writeEdge(label, edge);
   516     }
   517 
   518     /// \brief Issue a new labeled undirected edge writing command to
   519     /// the writer.
   520     ///
   521     /// Issue a new <i>labeled undirected edge writing command</i> to
   522     /// the writer.
   523     UGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
   524       uedge_writer.writeUEdge(label, edge);
   525     }
   526 
   527     /// \brief Issue a new attribute writing command.
   528     ///
   529     /// This function issues a new <i> attribute writing
   530     /// command</i> to the writer.
   531     template <typename Value>
   532     UGraphWriter& writeAttribute(std::string label, const Value& value) {
   533       attribute_writer.writeAttribute(label, value);
   534       return *this;
   535     }
   536     
   537     /// \brief Issue a new attribute writing command.
   538     ///
   539     /// This function issues a new <i> attribute writing
   540     /// command</i> to the writer.
   541     template <typename ItemWriter, typename Value>
   542     UGraphWriter& writeAttribute(std::string label, const Value& value, 
   543 			       const ItemWriter& iw = ItemWriter()) {
   544       attribute_writer.writeAttribute(label, value, iw);
   545       return *this;
   546     }
   547 
   548     /// \brief Conversion operator to LemonWriter.
   549     ///
   550     /// Conversion operator to LemonWriter. It makes possible
   551     /// to access the encapsulated \e LemonWriter, this way
   552     /// you can attach to this writer new instances of 
   553     /// \e LemonWriter::SectionWriter.
   554     operator LemonWriter&() {
   555       return *writer;
   556     }
   557 
   558     /// \brief Executes the writing commands.
   559     ///
   560     /// Executes the writing commands.
   561     void run() {
   562       writer->run();
   563     }
   564 
   565     /// \brief Returns true if the writer can give back the labels by the items.
   566     ///
   567     /// Returns true if the writer can give back the the labels by the items.
   568     bool isLabelWriter() const {
   569       return nodeset_writer.isLabelWriter() && 
   570         uedgeset_writer.isLabelWriter();
   571     }
   572 
   573     /// \brief Write the label of the given node.
   574     ///
   575     /// It writes the label of the given node. If there was written a "label"
   576     /// named node map then it will write the map value belonging to the node.
   577     void writeLabel(std::ostream& os, const Node& item) const {
   578       nodeset_writer.writeLabel(os, item);
   579     } 
   580 
   581     /// \brief Write the label of the given edge.
   582     ///
   583     /// It writes the label of the given edge. If there was written a "label"
   584     /// named edge map then it will write the map value belonging to the edge.
   585     void writeLabel(std::ostream& os, const Edge& item) const {
   586       uedgeset_writer.writeLabel(os, item);
   587     } 
   588 
   589     /// \brief Write the label of the given undirected edge.
   590     ///
   591     /// It writes the label of the given undirected edge. If there was
   592     /// written a "label" named edge map then it will write the map
   593     /// value belonging to the edge.
   594     void writeLabel(std::ostream& os, const UEdge& item) const {
   595       uedgeset_writer.writeLabel(os, item);
   596     } 
   597 
   598     /// \brief Sorts the given node vector by label.
   599     ///
   600     /// Sorts the given node vector by label. If there was written an
   601     /// "label" named map then the vector will be sorted by the values
   602     /// of this map. Otherwise if the \c forceLabel parameter was true
   603     /// it will be sorted by its id in the graph.
   604     void sortByLabel(std::vector<Node>& nodes) const {
   605       nodeset_writer.sortByLabel(nodes);
   606     }
   607 
   608     /// \brief Sorts the given edge vector by label.
   609     ///
   610     /// Sorts the given edge vector by label. If there was written an
   611     /// "label" named map then the vector will be sorted by the values
   612     /// of this map. Otherwise if the \c forceLabel parameter was true
   613     /// it will be sorted by its id in the graph.
   614     void sortByLabel(std::vector<Edge>& edges) const {
   615       uedgeset_writer.sortByLabel(edges);
   616     }
   617 
   618     /// \brief Sorts the given undirected edge vector by label.
   619     ///
   620     /// Sorts the given undirected edge vector by label. If there was
   621     /// written an "label" named map then the vector will be sorted by
   622     /// the values of this map. Otherwise if the \c forceLabel
   623     /// parameter was true it will be sorted by its id in the graph.
   624     void sortByLabel(std::vector<UEdge>& uedges) const {
   625       uedgeset_writer.sortByLabel(uedges);
   626     }
   627 
   628   private:
   629 
   630     LemonWriter* writer;
   631     bool own_writer;
   632 
   633     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   634     UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
   635 
   636     NodeWriter<Graph> node_writer;
   637     UEdgeWriter<Graph> uedge_writer;
   638     
   639     AttributeWriter<WriterTraits> attribute_writer;
   640   };
   641 
   642   /// @}
   643 
   644 }
   645 
   646 #endif