lemon/lgf_writer.h
changeset 645 a3402913cffe
parent 606 c5fd2d996909
child 646 f63e87b9748e
equal deleted inserted replaced
29:be8e24d99bf3 31:78f30c7c15f0
   345       }
   345       }
   346     };
   346     };
   347 
   347 
   348   }
   348   }
   349 
   349 
   350   template <typename Digraph>
   350   template <typename DGR>
   351   class DigraphWriter;
   351   class DigraphWriter;
   352 
   352 
   353   template <typename Digraph>
   353   template <typename TDGR>
   354   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
   354   DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
   355                                        std::ostream& os = std::cout);
   355                                    std::ostream& os = std::cout);
   356   template <typename Digraph>
   356   template <typename TDGR>
   357   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
   357   DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
   358                                        const std::string& fn);
   358 
   359 
   359   template <typename TDGR>
   360   template <typename Digraph>
   360   DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn);
   361   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
       
   362                                        const char* fn);
       
   363 
   361 
   364 
   362 
   365   /// \ingroup lemon_io
   363   /// \ingroup lemon_io
   366   ///
   364   ///
   367   /// \brief \ref lgf-format "LGF" writer for directed graphs
   365   /// \brief \ref lgf-format "LGF" writer for directed graphs
   379   /// the output stream. If the functor is not set, then a default
   377   /// the output stream. If the functor is not set, then a default
   380   /// conversion will be used. The \c attribute(), \c node() and \c
   378   /// conversion will be used. The \c attribute(), \c node() and \c
   381   /// arc() functions are used to add attribute writing rules.
   379   /// arc() functions are used to add attribute writing rules.
   382   ///
   380   ///
   383   ///\code
   381   ///\code
   384   /// DigraphWriter<Digraph>(digraph, std::cout).
   382   /// DigraphWriter<DGR>(digraph, std::cout).
   385   ///   nodeMap("coordinates", coord_map).
   383   ///   nodeMap("coordinates", coord_map).
   386   ///   nodeMap("size", size).
   384   ///   nodeMap("size", size).
   387   ///   nodeMap("title", title).
   385   ///   nodeMap("title", title).
   388   ///   arcMap("capacity", cap_map).
   386   ///   arcMap("capacity", cap_map).
   389   ///   node("source", src).
   387   ///   node("source", src).
   404   /// writes the node section and the first arc section, then the
   402   /// writes the node section and the first arc section, then the
   405   /// second pass skips the node section and writes just the arc
   403   /// second pass skips the node section and writes just the arc
   406   /// section to the stream. The output stream can be retrieved with
   404   /// section to the stream. The output stream can be retrieved with
   407   /// the \c ostream() function, hence the second pass can append its
   405   /// the \c ostream() function, hence the second pass can append its
   408   /// output to the output of the first pass.
   406   /// output to the output of the first pass.
   409   template <typename GR>
   407   template <typename DGR>
   410   class DigraphWriter {
   408   class DigraphWriter {
   411   public:
   409   public:
   412 
   410 
   413     typedef GR Digraph;
   411     typedef DGR Digraph;
   414     TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   412     TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
   415 
   413 
   416   private:
   414   private:
   417 
   415 
   418 
   416 
   419     std::ostream* _os;
   417     std::ostream* _os;
   420     bool local_os;
   418     bool local_os;
   421 
   419 
   422     const Digraph& _digraph;
   420     const DGR& _digraph;
   423 
   421 
   424     std::string _nodes_caption;
   422     std::string _nodes_caption;
   425     std::string _arcs_caption;
   423     std::string _arcs_caption;
   426     std::string _attributes_caption;
   424     std::string _attributes_caption;
   427 
   425 
   449 
   447 
   450     /// \brief Constructor
   448     /// \brief Constructor
   451     ///
   449     ///
   452     /// Construct a directed graph writer, which writes to the given
   450     /// Construct a directed graph writer, which writes to the given
   453     /// output stream.
   451     /// output stream.
   454     DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
   452     DigraphWriter(const DGR& digraph, std::ostream& os = std::cout)
   455       : _os(&os), local_os(false), _digraph(digraph),
   453       : _os(&os), local_os(false), _digraph(digraph),
   456         _skip_nodes(false), _skip_arcs(false) {}
   454         _skip_nodes(false), _skip_arcs(false) {}
   457 
   455 
   458     /// \brief Constructor
   456     /// \brief Constructor
   459     ///
   457     ///
   460     /// Construct a directed graph writer, which writes to the given
   458     /// Construct a directed graph writer, which writes to the given
   461     /// output file.
   459     /// output file.
   462     DigraphWriter(const Digraph& digraph, const std::string& fn)
   460     DigraphWriter(const DGR& digraph, const std::string& fn)
   463       : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
   461       : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
   464         _skip_nodes(false), _skip_arcs(false) {
   462         _skip_nodes(false), _skip_arcs(false) {
   465       if (!(*_os)) {
   463       if (!(*_os)) {
   466         delete _os;
   464         delete _os;
   467         throw IoError("Cannot write file", fn);
   465         throw IoError("Cannot write file", fn);
   470 
   468 
   471     /// \brief Constructor
   469     /// \brief Constructor
   472     ///
   470     ///
   473     /// Construct a directed graph writer, which writes to the given
   471     /// Construct a directed graph writer, which writes to the given
   474     /// output file.
   472     /// output file.
   475     DigraphWriter(const Digraph& digraph, const char* fn)
   473     DigraphWriter(const DGR& digraph, const char* fn)
   476       : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
   474       : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
   477         _skip_nodes(false), _skip_arcs(false) {
   475         _skip_nodes(false), _skip_arcs(false) {
   478       if (!(*_os)) {
   476       if (!(*_os)) {
   479         delete _os;
   477         delete _os;
   480         throw IoError("Cannot write file", fn);
   478         throw IoError("Cannot write file", fn);
   503       }
   501       }
   504     }
   502     }
   505 
   503 
   506   private:
   504   private:
   507 
   505 
   508     template <typename DGR>
   506     template <typename TDGR>
   509     friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
   507     friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
   510                                             std::ostream& os);
   508                                              std::ostream& os);
   511     template <typename DGR>
   509     template <typename TDGR>
   512     friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
   510     friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
   513                                             const std::string& fn);
   511                                              const std::string& fn);
   514     template <typename DGR>
   512     template <typename TDGR>
   515     friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
   513     friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
   516                                             const char *fn);
   514                                              const char *fn);
   517 
   515 
   518     DigraphWriter(DigraphWriter& other)
   516     DigraphWriter(DigraphWriter& other)
   519       : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
   517       : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
   520         _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   518         _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   521 
   519 
   722       for (NodeIt n(_digraph); n != INVALID; ++n) {
   720       for (NodeIt n(_digraph); n != INVALID; ++n) {
   723         nodes.push_back(n);
   721         nodes.push_back(n);
   724       }
   722       }
   725 
   723 
   726       if (label == 0) {
   724       if (label == 0) {
   727         IdMap<Digraph, Node> id_map(_digraph);
   725         IdMap<DGR, Node> id_map(_digraph);
   728         _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
   726         _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
   729         std::sort(nodes.begin(), nodes.end(), id_less);
   727         std::sort(nodes.begin(), nodes.end(), id_less);
   730       } else {
   728       } else {
   731         label->sort(nodes);
   729         label->sort(nodes);
   732       }
   730       }
   733 
   731 
   807       for (ArcIt n(_digraph); n != INVALID; ++n) {
   805       for (ArcIt n(_digraph); n != INVALID; ++n) {
   808         arcs.push_back(n);
   806         arcs.push_back(n);
   809       }
   807       }
   810 
   808 
   811       if (label == 0) {
   809       if (label == 0) {
   812         IdMap<Digraph, Arc> id_map(_digraph);
   810         IdMap<DGR, Arc> id_map(_digraph);
   813         _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
   811         _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
   814         std::sort(arcs.begin(), arcs.end(), id_less);
   812         std::sort(arcs.begin(), arcs.end(), id_less);
   815       } else {
   813       } else {
   816         label->sort(arcs);
   814         label->sort(arcs);
   817       }
   815       }
   818 
   816 
   913     }
   911     }
   914 
   912 
   915     /// @}
   913     /// @}
   916   };
   914   };
   917 
   915 
       
   916   /// \ingroup lemon_io
       
   917   ///
       
   918   /// \brief Return a \ref DigraphWriter class
       
   919   ///
       
   920   /// This function just returns a \ref DigraphWriter class. 
       
   921   ///
       
   922   /// With this function a digraph can be write to a file or output
       
   923   /// stream in \ref lgf-format "LGF" format with several maps and
       
   924   /// attributes. For example, with the following code a network flow
       
   925   /// problem can be written to the standard output, i.e. a digraph
       
   926   /// with a \e capacity map on the arcs and \e source and \e target
       
   927   /// nodes:
       
   928   ///
       
   929   ///\code
       
   930   ///ListDigraph digraph;
       
   931   ///ListDigraph::ArcMap<int> cap(digraph);
       
   932   ///ListDigraph::Node src, trg;
       
   933   ///  // Setting the capacity map and source and target nodes
       
   934   ///digraphWriter(digraph, std::cout).
       
   935   ///  arcMap("capacity", cap).
       
   936   ///  node("source", src).
       
   937   ///  node("target", trg).
       
   938   ///  run();
       
   939   ///\endcode
       
   940   ///
       
   941   /// For a complete documentation, please see the \ref DigraphWriter
       
   942   /// class documentation.
       
   943   /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
       
   944   /// to the end of the parameter list.
       
   945   /// \relates DigraphWriter
       
   946   /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
       
   947   /// \sa digraphWriter(const TDGR& digraph, const char* fn)
       
   948   template <typename TDGR>
       
   949   DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, std::ostream& os) {
       
   950     DigraphWriter<TDGR> tmp(digraph, os);
       
   951     return tmp;
       
   952   }
       
   953 
   918   /// \brief Return a \ref DigraphWriter class
   954   /// \brief Return a \ref DigraphWriter class
   919   ///
   955   ///
   920   /// This function just returns a \ref DigraphWriter class.
   956   /// This function just returns a \ref DigraphWriter class.
   921   /// \relates DigraphWriter
   957   /// \relates DigraphWriter
   922   template <typename Digraph>
   958   /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
   923   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
   959   template <typename TDGR>
   924                                        std::ostream& os) {
   960   DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
   925     DigraphWriter<Digraph> tmp(digraph, os);
   961                                     const std::string& fn) {
       
   962     DigraphWriter<TDGR> tmp(digraph, fn);
   926     return tmp;
   963     return tmp;
   927   }
   964   }
   928 
   965 
   929   /// \brief Return a \ref DigraphWriter class
   966   /// \brief Return a \ref DigraphWriter class
   930   ///
   967   ///
   931   /// This function just returns a \ref DigraphWriter class.
   968   /// This function just returns a \ref DigraphWriter class.
   932   /// \relates DigraphWriter
   969   /// \relates DigraphWriter
   933   template <typename Digraph>
   970   /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
   934   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
   971   template <typename TDGR>
   935                                        const std::string& fn) {
   972   DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn) {
   936     DigraphWriter<Digraph> tmp(digraph, fn);
   973     DigraphWriter<TDGR> tmp(digraph, fn);
   937     return tmp;
   974     return tmp;
   938   }
   975   }
   939 
   976 
   940   /// \brief Return a \ref DigraphWriter class
   977   template <typename GR>
   941   ///
       
   942   /// This function just returns a \ref DigraphWriter class.
       
   943   /// \relates DigraphWriter
       
   944   template <typename Digraph>
       
   945   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
       
   946                                        const char* fn) {
       
   947     DigraphWriter<Digraph> tmp(digraph, fn);
       
   948     return tmp;
       
   949   }
       
   950 
       
   951   template <typename Graph>
       
   952   class GraphWriter;
   978   class GraphWriter;
   953 
   979 
   954   template <typename Graph>
   980   template <typename TGR>
   955   GraphWriter<Graph> graphWriter(const Graph& graph,
   981   GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os = std::cout);
   956                                  std::ostream& os = std::cout);
   982   template <typename TGR>
   957   template <typename Graph>
   983   GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn);
   958   GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
   984   template <typename TGR>
   959   template <typename Graph>
   985   GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn);
   960   GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
       
   961 
   986 
   962   /// \ingroup lemon_io
   987   /// \ingroup lemon_io
   963   ///
   988   ///
   964   /// \brief \ref lgf-format "LGF" writer for directed graphs
   989   /// \brief \ref lgf-format "LGF" writer for directed graphs
   965   ///
   990   ///
   977   template <typename GR>
  1002   template <typename GR>
   978   class GraphWriter {
  1003   class GraphWriter {
   979   public:
  1004   public:
   980 
  1005 
   981     typedef GR Graph;
  1006     typedef GR Graph;
   982     TEMPLATE_GRAPH_TYPEDEFS(Graph);
  1007     TEMPLATE_GRAPH_TYPEDEFS(GR);
   983 
  1008 
   984   private:
  1009   private:
   985 
  1010 
   986 
  1011 
   987     std::ostream* _os;
  1012     std::ostream* _os;
   988     bool local_os;
  1013     bool local_os;
   989 
  1014 
   990     const Graph& _graph;
  1015     const GR& _graph;
   991 
  1016 
   992     std::string _nodes_caption;
  1017     std::string _nodes_caption;
   993     std::string _edges_caption;
  1018     std::string _edges_caption;
   994     std::string _attributes_caption;
  1019     std::string _attributes_caption;
   995 
  1020 
  1017 
  1042 
  1018     /// \brief Constructor
  1043     /// \brief Constructor
  1019     ///
  1044     ///
  1020     /// Construct a directed graph writer, which writes to the given
  1045     /// Construct a directed graph writer, which writes to the given
  1021     /// output stream.
  1046     /// output stream.
  1022     GraphWriter(const Graph& graph, std::ostream& os = std::cout)
  1047     GraphWriter(const GR& graph, std::ostream& os = std::cout)
  1023       : _os(&os), local_os(false), _graph(graph),
  1048       : _os(&os), local_os(false), _graph(graph),
  1024         _skip_nodes(false), _skip_edges(false) {}
  1049         _skip_nodes(false), _skip_edges(false) {}
  1025 
  1050 
  1026     /// \brief Constructor
  1051     /// \brief Constructor
  1027     ///
  1052     ///
  1028     /// Construct a directed graph writer, which writes to the given
  1053     /// Construct a directed graph writer, which writes to the given
  1029     /// output file.
  1054     /// output file.
  1030     GraphWriter(const Graph& graph, const std::string& fn)
  1055     GraphWriter(const GR& graph, const std::string& fn)
  1031       : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
  1056       : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
  1032         _skip_nodes(false), _skip_edges(false) {
  1057         _skip_nodes(false), _skip_edges(false) {
  1033       if (!(*_os)) {
  1058       if (!(*_os)) {
  1034         delete _os;
  1059         delete _os;
  1035         throw IoError("Cannot write file", fn);
  1060         throw IoError("Cannot write file", fn);
  1038 
  1063 
  1039     /// \brief Constructor
  1064     /// \brief Constructor
  1040     ///
  1065     ///
  1041     /// Construct a directed graph writer, which writes to the given
  1066     /// Construct a directed graph writer, which writes to the given
  1042     /// output file.
  1067     /// output file.
  1043     GraphWriter(const Graph& graph, const char* fn)
  1068     GraphWriter(const GR& graph, const char* fn)
  1044       : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
  1069       : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
  1045         _skip_nodes(false), _skip_edges(false) {
  1070         _skip_nodes(false), _skip_edges(false) {
  1046       if (!(*_os)) {
  1071       if (!(*_os)) {
  1047         delete _os;
  1072         delete _os;
  1048         throw IoError("Cannot write file", fn);
  1073         throw IoError("Cannot write file", fn);
  1071       }
  1096       }
  1072     }
  1097     }
  1073 
  1098 
  1074   private:
  1099   private:
  1075 
  1100 
  1076     template <typename Graph>
  1101     template <typename TGR>
  1077     friend GraphWriter<Graph> graphWriter(const Graph& graph,
  1102     friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
  1078                                           std::ostream& os);
  1103     template <typename TGR>
  1079     template <typename Graph>
  1104     friend GraphWriter<TGR> graphWriter(const TGR& graph, 
  1080     friend GraphWriter<Graph> graphWriter(const Graph& graph,
  1105                                         const std::string& fn);
  1081                                           const std::string& fn);
  1106     template <typename TGR>
  1082     template <typename Graph>
  1107     friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
  1083     friend GraphWriter<Graph> graphWriter(const Graph& graph,
       
  1084                                           const char *fn);
       
  1085     
  1108     
  1086     GraphWriter(GraphWriter& other)
  1109     GraphWriter(GraphWriter& other)
  1087       : _os(other._os), local_os(other.local_os), _graph(other._graph),
  1110       : _os(other._os), local_os(other.local_os), _graph(other._graph),
  1088         _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
  1111         _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
  1089 
  1112 
  1166     /// Add an arc map writing rule to the writer.
  1189     /// Add an arc map writing rule to the writer.
  1167     template <typename Map>
  1190     template <typename Map>
  1168     GraphWriter& arcMap(const std::string& caption, const Map& map) {
  1191     GraphWriter& arcMap(const std::string& caption, const Map& map) {
  1169       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
  1192       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
  1170       _writer_bits::MapStorageBase<Edge>* forward_storage =
  1193       _writer_bits::MapStorageBase<Edge>* forward_storage =
  1171         new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
  1194         new _writer_bits::GraphArcMapStorage<GR, true, Map>(_graph, map);
  1172       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1195       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1173       _writer_bits::MapStorageBase<Edge>* backward_storage =
  1196       _writer_bits::MapStorageBase<Edge>* backward_storage =
  1174         new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
  1197         new _writer_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
  1175       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1198       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1176       return *this;
  1199       return *this;
  1177     }
  1200     }
  1178 
  1201 
  1179     /// \brief Arc map writing rule
  1202     /// \brief Arc map writing rule
  1183     template <typename Map, typename Converter>
  1206     template <typename Map, typename Converter>
  1184     GraphWriter& arcMap(const std::string& caption, const Map& map,
  1207     GraphWriter& arcMap(const std::string& caption, const Map& map,
  1185                           const Converter& converter = Converter()) {
  1208                           const Converter& converter = Converter()) {
  1186       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
  1209       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
  1187       _writer_bits::MapStorageBase<Edge>* forward_storage =
  1210       _writer_bits::MapStorageBase<Edge>* forward_storage =
  1188         new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
  1211         new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter>
  1189         (_graph, map, converter);
  1212         (_graph, map, converter);
  1190       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1213       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1191       _writer_bits::MapStorageBase<Edge>* backward_storage =
  1214       _writer_bits::MapStorageBase<Edge>* backward_storage =
  1192         new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
  1215         new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter>
  1193         (_graph, map, converter);
  1216         (_graph, map, converter);
  1194       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1217       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1195       return *this;
  1218       return *this;
  1196     }
  1219     }
  1197 
  1220 
  1245 
  1268 
  1246     /// \brief Arc writing rule
  1269     /// \brief Arc writing rule
  1247     ///
  1270     ///
  1248     /// Add an arc writing rule to writer.
  1271     /// Add an arc writing rule to writer.
  1249     GraphWriter& arc(const std::string& caption, const Arc& arc) {
  1272     GraphWriter& arc(const std::string& caption, const Arc& arc) {
  1250       typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
  1273       typedef _writer_bits::GraphArcLookUpConverter<GR> Converter;
  1251       Converter converter(_graph, _edge_index);
  1274       Converter converter(_graph, _edge_index);
  1252       _writer_bits::ValueStorageBase* storage =
  1275       _writer_bits::ValueStorageBase* storage =
  1253         new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
  1276         new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
  1254       _attributes.push_back(std::make_pair(caption, storage));
  1277       _attributes.push_back(std::make_pair(caption, storage));
  1255       return *this;
  1278       return *this;
  1336       for (NodeIt n(_graph); n != INVALID; ++n) {
  1359       for (NodeIt n(_graph); n != INVALID; ++n) {
  1337         nodes.push_back(n);
  1360         nodes.push_back(n);
  1338       }
  1361       }
  1339 
  1362 
  1340       if (label == 0) {
  1363       if (label == 0) {
  1341         IdMap<Graph, Node> id_map(_graph);
  1364         IdMap<GR, Node> id_map(_graph);
  1342         _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
  1365         _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
  1343         std::sort(nodes.begin(), nodes.end(), id_less);
  1366         std::sort(nodes.begin(), nodes.end(), id_less);
  1344       } else {
  1367       } else {
  1345         label->sort(nodes);
  1368         label->sort(nodes);
  1346       }
  1369       }
  1347 
  1370 
  1421       for (EdgeIt n(_graph); n != INVALID; ++n) {
  1444       for (EdgeIt n(_graph); n != INVALID; ++n) {
  1422         edges.push_back(n);
  1445         edges.push_back(n);
  1423       }
  1446       }
  1424 
  1447 
  1425       if (label == 0) {
  1448       if (label == 0) {
  1426         IdMap<Graph, Edge> id_map(_graph);
  1449         IdMap<GR, Edge> id_map(_graph);
  1427         _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
  1450         _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
  1428         std::sort(edges.begin(), edges.end(), id_less);
  1451         std::sort(edges.begin(), edges.end(), id_less);
  1429       } else {
  1452       } else {
  1430         label->sort(edges);
  1453         label->sort(edges);
  1431       }
  1454       }
  1432 
  1455 
  1527     }
  1550     }
  1528 
  1551 
  1529     /// @}
  1552     /// @}
  1530   };
  1553   };
  1531 
  1554 
       
  1555   /// \ingroup lemon_io
       
  1556   ///
       
  1557   /// \brief Return a \ref GraphWriter class
       
  1558   ///
       
  1559   /// This function just returns a \ref GraphWriter class. 
       
  1560   ///
       
  1561   /// With this function a graph can be write to a file or output
       
  1562   /// stream in \ref lgf-format "LGF" format with several maps and
       
  1563   /// attributes. For example, with the following code a weighted
       
  1564   /// matching problem can be written to the standard output, i.e. a
       
  1565   /// graph with a \e weight map on the edges:
       
  1566   ///
       
  1567   ///\code
       
  1568   ///ListGraph graph;
       
  1569   ///ListGraph::EdgeMap<int> weight(graph);
       
  1570   ///  // Setting the weight map
       
  1571   ///graphWriter(graph, std::cout).
       
  1572   ///  edgeMap("weight", weight).
       
  1573   ///  run();
       
  1574   ///\endcode
       
  1575   ///
       
  1576   /// For a complete documentation, please see the \ref GraphWriter
       
  1577   /// class documentation.
       
  1578   /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
       
  1579   /// to the end of the parameter list.
       
  1580   /// \relates GraphWriter
       
  1581   /// \sa graphWriter(const TGR& graph, const std::string& fn)
       
  1582   /// \sa graphWriter(const TGR& graph, const char* fn)
       
  1583   template <typename TGR>
       
  1584   GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os) {
       
  1585     GraphWriter<TGR> tmp(graph, os);
       
  1586     return tmp;
       
  1587   }
       
  1588 
  1532   /// \brief Return a \ref GraphWriter class
  1589   /// \brief Return a \ref GraphWriter class
  1533   ///
  1590   ///
  1534   /// This function just returns a \ref GraphWriter class.
  1591   /// This function just returns a \ref GraphWriter class.
  1535   /// \relates GraphWriter
  1592   /// \relates GraphWriter
  1536   template <typename Graph>
  1593   /// \sa graphWriter(const TGR& graph, std::ostream& os)
  1537   GraphWriter<Graph> graphWriter(const Graph& graph,
  1594   template <typename TGR>
  1538                                  std::ostream& os) {
  1595   GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn) {
  1539     GraphWriter<Graph> tmp(graph, os);
  1596     GraphWriter<TGR> tmp(graph, fn);
  1540     return tmp;
  1597     return tmp;
  1541   }
  1598   }
  1542 
  1599 
  1543   /// \brief Return a \ref GraphWriter class
  1600   /// \brief Return a \ref GraphWriter class
  1544   ///
  1601   ///
  1545   /// This function just returns a \ref GraphWriter class.
  1602   /// This function just returns a \ref GraphWriter class.
  1546   /// \relates GraphWriter
  1603   /// \relates GraphWriter
  1547   template <typename Graph>
  1604   /// \sa graphWriter(const TGR& graph, std::ostream& os)
  1548   GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
  1605   template <typename TGR>
  1549     GraphWriter<Graph> tmp(graph, fn);
  1606   GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
  1550     return tmp;
  1607     GraphWriter<TGR> tmp(graph, fn);
  1551   }
       
  1552 
       
  1553   /// \brief Return a \ref GraphWriter class
       
  1554   ///
       
  1555   /// This function just returns a \ref GraphWriter class.
       
  1556   /// \relates GraphWriter
       
  1557   template <typename Graph>
       
  1558   GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
       
  1559     GraphWriter<Graph> tmp(graph, fn);
       
  1560     return tmp;
  1608     return tmp;
  1561   }
  1609   }
  1562 
  1610 
  1563   class SectionWriter;
  1611   class SectionWriter;
  1564 
  1612 
  1744 
  1792 
  1745     /// @}
  1793     /// @}
  1746 
  1794 
  1747   };
  1795   };
  1748 
  1796 
       
  1797   /// \ingroup lemon_io
       
  1798   ///
  1749   /// \brief Return a \ref SectionWriter class
  1799   /// \brief Return a \ref SectionWriter class
  1750   ///
  1800   ///
  1751   /// This function just returns a \ref SectionWriter class.
  1801   /// This function just returns a \ref SectionWriter class.
       
  1802   ///
       
  1803   /// Please see SectionWriter documentation about the custom section
       
  1804   /// output.
       
  1805   ///
  1752   /// \relates SectionWriter
  1806   /// \relates SectionWriter
       
  1807   /// \sa sectionWriter(const std::string& fn)
       
  1808   /// \sa sectionWriter(const char *fn)
  1753   inline SectionWriter sectionWriter(std::ostream& os) {
  1809   inline SectionWriter sectionWriter(std::ostream& os) {
  1754     SectionWriter tmp(os);
  1810     SectionWriter tmp(os);
  1755     return tmp;
  1811     return tmp;
  1756   }
  1812   }
  1757 
  1813 
  1758   /// \brief Return a \ref SectionWriter class
  1814   /// \brief Return a \ref SectionWriter class
  1759   ///
  1815   ///
  1760   /// This function just returns a \ref SectionWriter class.
  1816   /// This function just returns a \ref SectionWriter class.
  1761   /// \relates SectionWriter
  1817   /// \relates SectionWriter
       
  1818   /// \sa sectionWriter(std::ostream& os)
  1762   inline SectionWriter sectionWriter(const std::string& fn) {
  1819   inline SectionWriter sectionWriter(const std::string& fn) {
  1763     SectionWriter tmp(fn);
  1820     SectionWriter tmp(fn);
  1764     return tmp;
  1821     return tmp;
  1765   }
  1822   }
  1766 
  1823 
  1767   /// \brief Return a \ref SectionWriter class
  1824   /// \brief Return a \ref SectionWriter class
  1768   ///
  1825   ///
  1769   /// This function just returns a \ref SectionWriter class.
  1826   /// This function just returns a \ref SectionWriter class.
  1770   /// \relates SectionWriter
  1827   /// \relates SectionWriter
       
  1828   /// \sa sectionWriter(std::ostream& os)
  1771   inline SectionWriter sectionWriter(const char* fn) {
  1829   inline SectionWriter sectionWriter(const char* fn) {
  1772     SectionWriter tmp(fn);
  1830     SectionWriter tmp(fn);
  1773     return tmp;
  1831     return tmp;
  1774   }
  1832   }
  1775 }
  1833 }