lemon/lemon_writer.h
changeset 2470 46818ce27a60
parent 2414 9e80927b7921
child 2502 9c23c3762bc5
equal deleted inserted replaced
21:7116138bd85c 22:dbed5069139f
    69       }
    69       }
    70       const Map& map;
    70       const Map& map;
    71       Less<typename Map::Value> less;
    71       Less<typename Map::Value> less;
    72     };
    72     };
    73 
    73 
       
    74     template <typename UGraph, typename Map>
       
    75     struct UEdgeComposeLess {
       
    76       UEdgeComposeLess(const UGraph& _ugraph, const Map& _map) 
       
    77 	: ugraph(_ugraph), map(_map), less() {}
       
    78 
       
    79       bool operator()(const typename UGraph::Edge& p, 
       
    80                       const typename UGraph::Edge& q) const {
       
    81 	return p != q ? less(map[p], map[q]) : 
       
    82 	  (!ugraph.direction(p) && ugraph.direction(q));
       
    83       }
       
    84 
       
    85       const UGraph& ugraph;
       
    86       const Map& map;
       
    87       Less<typename Map::Value> less;
       
    88     };
       
    89 
    74     template <typename Item>
    90     template <typename Item>
    75     class ItemLabelWriter {
    91     class ItemLabelWriter {
    76     public:
    92     public:
    77 
    93 
    78       bool isLabelWriter() { return true; }
    94       bool isLabelWriter() { return true; }
   121       typedef typename Map::Value Value;
   137       typedef typename Map::Value Value;
   122 
   138 
   123       ForwardComposeMap(const Graph& _graph, const Map& _map) 
   139       ForwardComposeMap(const Graph& _graph, const Map& _map) 
   124 	: graph(_graph), map(_map) {}
   140 	: graph(_graph), map(_map) {}
   125       
   141       
   126       Value operator[](const Key& key) {
   142       Value operator[](const Key& key) const {
   127 	return map[graph.direct(key, false)];
   143 	return map[graph.direct(key, true)];
   128       }
   144       }
   129 
   145 
   130     private:
   146     private:
   131       typename Ref<Map>::Type map;
   147       typename Ref<Map>::Type map;
   132       const Graph& graph;
   148       const Graph& graph;
   145       typedef typename Map::Value Value;
   161       typedef typename Map::Value Value;
   146 
   162 
   147       BackwardComposeMap(const Graph& _graph, const Map& _map) 
   163       BackwardComposeMap(const Graph& _graph, const Map& _map) 
   148 	: graph(_graph), map(_map) {}
   164 	: graph(_graph), map(_map) {}
   149       
   165       
   150       Value operator[](const Key& key) {
   166       Value operator[](const Key& key) const {
   151 	return map[graph.direct(key, false)];
   167 	return map[graph.direct(key, false)];
   152       }
   168       }
   153 
   169 
   154     private:
   170     private:
   155       typename Ref<Map>::Type map;
   171       typename Ref<Map>::Type map;
   197       typedef _Item Item;
   213       typedef _Item Item;
   198 
   214 
   199       virtual ~MapWriterBase() {}
   215       virtual ~MapWriterBase() {}
   200 
   216 
   201       virtual void write(std::ostream& os, const Item& item) const = 0;
   217       virtual void write(std::ostream& os, const Item& item) const = 0;
   202       virtual void sortByMap(std::vector<Item>&) const = 0;
   218       virtual void sort(std::vector<Item>&) const = 0;
   203     };
   219     };
   204 
   220 
   205 
   221 
   206     template <typename _Item, typename _Map, typename _Writer>
   222     template <typename _Item, typename _Map, typename _Writer>
   207     class MapWriter : public MapWriterBase<_Item> {
   223     class MapWriter : public MapWriterBase<_Item> {
   222       virtual void write(std::ostream& os, const Item& item) const {
   238       virtual void write(std::ostream& os, const Item& item) const {
   223 	Value value = map[item];
   239 	Value value = map[item];
   224 	writer.write(os, value);
   240 	writer.write(os, value);
   225       }
   241       }
   226 
   242 
   227       virtual void sortByMap(std::vector<Item>& items) const {
   243       virtual void sort(std::vector<Item>& items) const {
       
   244         ComposeLess<Map> less(map);
       
   245         std::sort(items.begin(), items.end(), less);
       
   246       }
       
   247 
       
   248     };
       
   249 
       
   250     template <typename _UGraph>    
       
   251     class UEdgeMapWriterBase {
       
   252     public:
       
   253       typedef typename _UGraph::Edge Edge;
       
   254       typedef typename _UGraph::UEdge UEdge;
       
   255 
       
   256       typedef UEdge Item;
       
   257 
       
   258       virtual ~UEdgeMapWriterBase() {}
       
   259 
       
   260       virtual void write(std::ostream& os, const Item& item) const = 0;
       
   261       virtual void sort(const _UGraph&, std::vector<Edge>&) const = 0;
       
   262       virtual void sort(std::vector<UEdge>&) const = 0;
       
   263     };
       
   264 
       
   265 
       
   266     template <typename _UGraph, typename _Map, typename _Writer>
       
   267     class UEdgeMapWriter : public UEdgeMapWriterBase<_UGraph> {
       
   268     public:
       
   269       typedef _Map Map;
       
   270       typedef _Writer Writer;
       
   271       typedef typename Writer::Value Value;
       
   272 
       
   273       typedef typename _UGraph::Edge Edge;
       
   274       typedef typename _UGraph::UEdge UEdge;
       
   275       typedef UEdge Item;
       
   276       
       
   277       typename _writer_bits::Ref<Map>::Type map;
       
   278       Writer writer;
       
   279 
       
   280       UEdgeMapWriter(const Map& _map, const Writer& _writer) 
       
   281 	: map(_map), writer(_writer) {}
       
   282 
       
   283       virtual ~UEdgeMapWriter() {}
       
   284 
       
   285       virtual void write(std::ostream& os, const Item& item) const {
       
   286 	Value value = map[item];
       
   287 	writer.write(os, value);
       
   288       }
       
   289 
       
   290       virtual void sort(const _UGraph& ugraph, std::vector<Edge>& items) const {
       
   291         UEdgeComposeLess<_UGraph, Map> less(ugraph, map);
       
   292         std::sort(items.begin(), items.end(), less);
       
   293       }
       
   294 
       
   295       virtual void sort(std::vector<UEdge>& items) const {
   228         ComposeLess<Map> less(map);
   296         ComposeLess<Map> less(map);
   229         std::sort(items.begin(), items.end(), less);
   297         std::sort(items.begin(), items.end(), less);
   230       }
   298       }
   231 
   299 
   232     };
   300     };
   260     class LabelWriterBase {
   328     class LabelWriterBase {
   261     public:
   329     public:
   262       typedef _Item Item;
   330       typedef _Item Item;
   263       virtual ~LabelWriterBase() {}
   331       virtual ~LabelWriterBase() {}
   264       virtual void write(std::ostream&, const Item&) const = 0;
   332       virtual void write(std::ostream&, const Item&) const = 0;
       
   333       virtual void sort(std::vector<Item>&) const = 0;
   265       virtual bool isLabelWriter() const = 0;
   334       virtual bool isLabelWriter() const = 0;
       
   335       virtual LabelWriterBase* clone() const = 0;
   266     };
   336     };
   267 
   337 
   268     template <typename _Item, typename _BoxedLabelWriter>
   338     template <typename _Item, typename _BoxedLabelWriter>
   269     class LabelWriter : public LabelWriterBase<_Item> {
   339     class LabelWriter : public LabelWriterBase<_Item> {
   270     public:
   340     public:
   277 	: labelWriter(_labelWriter) {}
   347 	: labelWriter(_labelWriter) {}
   278 
   348 
   279       virtual void write(std::ostream& os, const Item& item) const {
   349       virtual void write(std::ostream& os, const Item& item) const {
   280 	labelWriter.writeLabel(os, item);
   350 	labelWriter.writeLabel(os, item);
   281       }
   351       }
       
   352       virtual void sort(std::vector<Item>& items) const {
       
   353 	labelWriter.sortByLabel(items);
       
   354       }
   282 
   355 
   283       virtual bool isLabelWriter() const {
   356       virtual bool isLabelWriter() const {
   284 	return labelWriter.isLabelWriter();
   357 	return labelWriter.isLabelWriter();
       
   358       }
       
   359 
       
   360       virtual LabelWriter* clone() const {
       
   361 	return new LabelWriter(labelWriter);
   285       }
   362       }
   286     };
   363     };
   287 
   364 
   288   }
   365   }
   289 
   366 
   423   /// If the nodeset contains an \c "label" named map then it will be regarded
   500   /// If the nodeset contains an \c "label" named map then it will be regarded
   424   /// as label map. This map should contain only unique values and when the 
   501   /// as label map. This map should contain only unique values and when the 
   425   /// \c writeLabel() member will be called with a node it will write it's 
   502   /// \c writeLabel() member will be called with a node it will write it's 
   426   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   503   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   427   /// then the label map will be the id in the graph. In addition if the
   504   /// then the label map will be the id in the graph. In addition if the
   428   /// the \c _sortByLabel is true then the writer will write the edges
   505   /// the \c _forceSort is true then the writer will write the edges
   429   /// sorted by the labels.
   506   /// sorted by the labels.
   430   ///
   507   ///
   431   /// \relates LemonWriter
   508   /// \relates LemonWriter
   432   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   509   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   433   class NodeSetWriter : public LemonWriter::SectionWriter {
   510   class NodeSetWriter : public LemonWriter::SectionWriter {
   442     ///
   519     ///
   443     /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
   520     /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
   444     /// attach it into the given LemonWriter. If the \c _forceLabelMap
   521     /// attach it into the given LemonWriter. If the \c _forceLabelMap
   445     /// parameter is true then the writer will write own label map when
   522     /// parameter is true then the writer will write own label map when
   446     /// the user does not give "label" named map. In addition if the
   523     /// the user does not give "label" named map. In addition if the
   447     /// the \c _sortByLabel is true then the writer will write the edges
   524     /// the \c _forceSort is true then the writer will write the edges
   448     /// sorted by the labels.
   525     /// sorted by the labels.
   449     NodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   526     NodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   450 		  const std::string& _name = std::string(), 
   527 		  const std::string& _name = std::string(), 
   451 		  bool _forceLabelMap = true, bool _sortByLabel = true) 
   528 		  bool _forceLabelMap = true, bool _forceSort = true) 
   452       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), 
   529       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), 
   453 	sortByLabel(_sortByLabel), graph(_graph), name(_name) {}
   530 	forceSort(_forceSort), graph(_graph), name(_name) {}
   454 
   531 
   455     /// \brief Destructor.
   532     /// \brief Destructor.
   456     ///
   533     ///
   457     /// Destructor for NodeSetWriter.
   534     /// Destructor for NodeSetWriter.
   458     virtual ~NodeSetWriter() {
   535     virtual ~NodeSetWriter() {
   513       }
   590       }
   514       std::vector<Node> items;
   591       std::vector<Node> items;
   515       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
   592       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
   516         items.push_back(it);
   593         items.push_back(it);
   517       }
   594       }
   518       if (sortByLabel) {
   595       if (forceSort) {
   519         if (labelMap) {
   596         if (labelMap) {
   520           labelMap->sortByMap(items);
   597           labelMap->sort(items);
   521         } else {
   598         } else {
   522           typedef IdMap<Graph, Node> Map;
   599           typedef IdMap<Graph, Node> Map;
   523           Map map(graph);
   600           Map map(graph);
   524           _writer_bits::ComposeLess<Map> less(map);
   601           _writer_bits::ComposeLess<Map> less(map);
   525           std::sort(items.begin(), items.end(), less);
   602           std::sort(items.begin(), items.end(), less);
   548   public:
   625   public:
   549 
   626 
   550     /// \brief Returns true if the nodeset can write the labels of the nodes.
   627     /// \brief Returns true if the nodeset can write the labels of the nodes.
   551     ///
   628     ///
   552     /// Returns true if the nodeset can write the labels of the nodes.
   629     /// Returns true if the nodeset can write the labels of the nodes.
   553     /// It is possible only if an "label" named map was written or the 
   630     /// It is possible only if a "label" named map was written or the 
   554     /// \c _forceLabelMap constructor parameter was true.
   631     /// \c _forceLabelMap constructor parameter was true.
   555     bool isLabelWriter() const {
   632     bool isLabelWriter() const {
   556       return labelMap != 0 || forceLabelMap;
   633       return labelMap != 0 || forceLabelMap;
   557     }
   634     }
   558 
   635 
   559     /// \brief Write the label of the given node.
   636     /// \brief Write the label of the given node.
   560     ///
   637     ///
   561     /// It writes the label of the given node. If there was written an "label"
   638     /// It writes the label of the given node. If there was written a "label"
   562     /// named map then it will write the map value belongs to the node.
   639     /// named map then it will write the map value belongs to the node.
   563     /// Otherwise if the \c forceLabel parameter was true it will write
   640     /// Otherwise if the \c forceLabel parameter was true it will write
   564     /// its label in the graph. 
   641     /// its label in the graph. 
   565     void writeLabel(std::ostream& os, const Node& item) const {
   642     void writeLabel(std::ostream& os, const Node& item) const {
   566       if (forceLabelMap) {
   643       if (forceLabelMap) {
   568       } else {
   645       } else {
   569 	labelMap->write(os, item);
   646 	labelMap->write(os, item);
   570       }
   647       }
   571     }
   648     }
   572 
   649 
       
   650     /// \brief Sorts the given node vector by label.
       
   651     ///
       
   652     /// Sorts the given node vector by label. If there was written an
       
   653     /// "label" named map then the vector will be sorted by the values
       
   654     /// of this map. Otherwise if the \c forceLabel parameter was true
       
   655     /// it will be sorted by its id in the graph.
       
   656     void sortByLabel(std::vector<Node>& nodes) const {
       
   657       if (labelMap) {
       
   658 	labelMap->sort(nodes);
       
   659       } else {
       
   660 	typedef IdMap<Graph, Node> Map;
       
   661 	Map map(graph);
       
   662 	_writer_bits::ComposeLess<Map> less(map);
       
   663 	std::sort(nodes.begin(), nodes.end(), less);
       
   664       }
       
   665     }
       
   666 
   573   private:
   667   private:
   574 
   668 
   575     typedef std::vector<std::pair<std::string, _writer_bits::
   669     typedef std::vector<std::pair<std::string, _writer_bits::
   576 				  MapWriterBase<Node>*> > MapWriters;
   670 				  MapWriterBase<Node>*> > MapWriters;
   577     MapWriters writers;
   671     MapWriters writers;
   578 
   672 
   579     _writer_bits::MapWriterBase<Node>* labelMap;
   673     _writer_bits::MapWriterBase<Node>* labelMap;
   580     bool forceLabelMap;
   674     bool forceLabelMap;
   581     bool sortByLabel;
   675     bool forceSort;
   582    
   676    
   583     const Graph& graph;   
   677     const Graph& graph;   
   584     std::string name;
   678     std::string name;
   585 
   679 
   586   };
   680   };
   600   /// If the edgeset contains an \c "label" named map then it will be regarded
   694   /// If the edgeset contains an \c "label" named map then it will be regarded
   601   /// as label map. This map should contain only unique values and when the 
   695   /// as label map. This map should contain only unique values and when the 
   602   /// \c writeLabel() member will be called with an edge it will write it's 
   696   /// \c writeLabel() member will be called with an edge it will write it's 
   603   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   697   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   604   /// then the label map will be the id in the graph. In addition if the
   698   /// then the label map will be the id in the graph. In addition if the
   605   /// the \c _sortByLabel is true then the writer will write the edges
   699   /// the \c _forceSort is true then the writer will write the edges
   606   /// sorted by the labels.
   700   /// sorted by the labels.
   607   ///
   701   ///
   608   /// The edgeset writer needs a node label writer to identify which nodes
   702   /// The edgeset writer needs a node label writer to identify which nodes
   609   /// have to be connected. If a NodeSetWriter can write the nodes' label,
   703   /// have to be connected. If a NodeSetWriter can write the nodes' label,
   610   /// it will be able to use with this class.
   704   /// it will be able to use with this class.
   625     /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter
   719     /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter
   626     /// and attach it into the given LemonWriter. It will write node
   720     /// and attach it into the given LemonWriter. It will write node
   627     /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
   721     /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
   628     /// parameter is true then the writer will write own label map if
   722     /// parameter is true then the writer will write own label map if
   629     /// the user does not give "label" named map. In addition if the
   723     /// the user does not give "label" named map. In addition if the
   630     /// the \c _sortByLabel is true then the writer will write the
   724     /// the \c _forceSort is true then the writer will write the
   631     /// edges sorted by the labels.
   725     /// edges sorted by the labels.
   632     template <typename NodeLabelWriter>
   726     template <typename NodeLabelWriter>
   633     EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   727     EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   634 		  const NodeLabelWriter& _nodeLabelWriter, 
   728 		  const NodeLabelWriter& _nodeLabelWriter, 
   635 		  const std::string& _name = std::string(),
   729 		  const std::string& _name = std::string(),
   636 		  bool _forceLabelMap = true, bool _sortByLabel = true)
   730 		  bool _forceLabelMap = true, bool _forceSort = true)
   637       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
   731       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
   638 	sortByLabel(_sortByLabel), graph(_graph), name(_name) {
   732 	forceSort(_forceSort), graph(_graph), name(_name) {
   639       checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
   733       checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
   640       nodeLabelWriter.reset(new _writer_bits::
   734       nodeLabelWriter.reset(new _writer_bits::
   641 			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   735 			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   642     } 
   736     } 
   643 
   737 
   705       }
   799       }
   706       std::vector<Edge> items;
   800       std::vector<Edge> items;
   707       for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
   801       for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
   708         items.push_back(it);
   802         items.push_back(it);
   709       }
   803       }
   710       if (sortByLabel) {
   804       if (forceSort) {
   711         if (labelMap) {
   805         if (labelMap) {
   712           labelMap->sortByMap(items);
   806           labelMap->sort(items);
   713         } else {
   807         } else {
   714           typedef IdMap<Graph, Edge> Map;
   808           typedef IdMap<Graph, Edge> Map;
   715           Map map(graph);
   809           Map map(graph);
   716           _writer_bits::ComposeLess<Map> less(map);
   810           _writer_bits::ComposeLess<Map> less(map);
   717           std::sort(items.begin(), items.end(), less);
   811           std::sort(items.begin(), items.end(), less);
   745   public:
   839   public:
   746 
   840 
   747     /// \brief Returns true if the edgeset can write the labels of the edges.
   841     /// \brief Returns true if the edgeset can write the labels of the edges.
   748     ///
   842     ///
   749     /// Returns true if the edgeset can write the labels of the edges.
   843     /// Returns true if the edgeset can write the labels of the edges.
   750     /// It is possible only if an "label" named map was written or the 
   844     /// It is possible only if a "label" named map was written or the 
   751     /// \c _forceLabelMap constructor parameter was true.
   845     /// \c _forceLabelMap constructor parameter was true.
   752     bool isLabelWriter() const {
   846     bool isLabelWriter() const {
   753       return forceLabelMap || labelMap != 0;
   847       return forceLabelMap || labelMap != 0;
   754     }
   848     }
   755 
   849 
   756     /// \brief Write the label of the given edge.
   850     /// \brief Write the label of the given edge.
   757     ///
   851     ///
   758     /// It writes the label of the given edge. If there was written an "label"
   852     /// It writes the label of the given edge. If there was written a "label"
   759     /// named map then it will write the map value belongs to the edge.
   853     /// named map then it will write the map value belongs to the edge.
   760     /// Otherwise if the \c forceLabel parameter was true it will write
   854     /// Otherwise if the \c forceLabel parameter was true it will write
   761     /// its label in the graph. 
   855     /// its label in the graph. 
   762     void writeLabel(std::ostream& os, const Edge& item) const {
   856     void writeLabel(std::ostream& os, const Edge& item) const {
   763       if (forceLabelMap) {
   857       if (forceLabelMap) {
   765       } else {
   859       } else {
   766 	labelMap->write(os, item);
   860 	labelMap->write(os, item);
   767       }
   861       }
   768     } 
   862     } 
   769 
   863 
       
   864     /// \brief Sorts the given edge vector by label.
       
   865     ///
       
   866     /// Sorts the given edge vector by label. If there was written an
       
   867     /// "label" named map then the vector will be sorted by the values
       
   868     /// of this map. Otherwise if the \c forceLabel parameter was true
       
   869     /// it will be sorted by its id in the graph.
       
   870     void sortByLabel(std::vector<Edge>& edges) const {
       
   871       if (labelMap) {
       
   872 	labelMap->sort(edges);
       
   873       } else {
       
   874 	typedef IdMap<Graph, Edge> Map;
       
   875 	Map map(graph);
       
   876 	_writer_bits::ComposeLess<Map> less(map);
       
   877 	std::sort(edges.begin(), edges.end(), less);
       
   878       }
       
   879     }
       
   880 
   770   private:
   881   private:
   771 
   882 
   772     typedef std::vector<std::pair<std::string, _writer_bits::
   883     typedef std::vector<std::pair<std::string, _writer_bits::
   773 				  MapWriterBase<Edge>*> > MapWriters;
   884 				  MapWriterBase<Edge>*> > MapWriters;
   774     MapWriters writers;
   885     MapWriters writers;
   775 
   886 
   776     _writer_bits::MapWriterBase<Edge>* labelMap;
   887     _writer_bits::MapWriterBase<Edge>* labelMap;
   777     bool forceLabelMap;
   888     bool forceLabelMap;
   778     bool sortByLabel;
   889     bool forceSort;
   779    
   890    
   780     const Graph& graph;   
   891     const Graph& graph;   
   781     std::string name;
   892     std::string name;
   782 
   893 
   783     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
   894     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
   805   /// regarded as label map. This map should contain only unique
   916   /// regarded as label map. This map should contain only unique
   806   /// values and when the \c writeLabel() member will be called with
   917   /// values and when the \c writeLabel() member will be called with
   807   /// an undirected edge it will write it's label. Otherwise if the \c
   918   /// an undirected edge it will write it's label. Otherwise if the \c
   808   /// _forceLabelMap constructor parameter is true then the label map
   919   /// _forceLabelMap constructor parameter is true then the label map
   809   /// will be the id in the graph.  In addition if the the \c
   920   /// will be the id in the graph.  In addition if the the \c
   810   /// _sortByLabel is true then the writer will write the edges sorted
   921   /// _forceSort is true then the writer will write the edges sorted
   811   /// by the labels.
   922   /// by the labels.
   812   ///
   923   ///
   813   /// The undirected edgeset writer needs a node label writer to identify 
   924   /// The undirected edgeset writer needs a node label writer to identify 
   814   /// which nodes have to be connected. If a NodeSetWriter can write the 
   925   /// which nodes have to be connected. If a NodeSetWriter can write the 
   815   /// nodes' label, it will be able to use with this class.
   926   /// nodes' label, it will be able to use with this class.
   831     /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
   942     /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
   832     /// and attach it into the given LemonWriter. It will write node
   943     /// and attach it into the given LemonWriter. It will write node
   833     /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
   944     /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
   834     /// parameter is true then the writer will write own label map if
   945     /// parameter is true then the writer will write own label map if
   835     /// the user does not give "label" named map. In addition if the
   946     /// the user does not give "label" named map. In addition if the
   836     /// the \c _sortByLabel is true then the writer will write the
   947     /// the \c _forceSort is true then the writer will write the
   837     /// edges sorted by the labels.
   948     /// edges sorted by the labels.
   838     template <typename NodeLabelWriter>
   949     template <typename NodeLabelWriter>
   839     UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   950     UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   840 		       const NodeLabelWriter& _nodeLabelWriter, 
   951 		       const NodeLabelWriter& _nodeLabelWriter, 
   841 		       const std::string& _name = std::string(),
   952 		       const std::string& _name = std::string(),
   842 		       bool _forceLabelMap = true, bool _sortByLabel = true)
   953 		       bool _forceLabelMap = true, bool _forceSort = true)
   843       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
   954       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
   844 	sortByLabel(_sortByLabel), graph(_graph), name(_name) {
   955 	forceSort(_forceSort), graph(_graph), name(_name) {
   845       checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
   956       checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
   846       nodeLabelWriter.reset(new _writer_bits::
   957       nodeLabelWriter.reset(new _writer_bits::
   847 			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   958 	LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   848     } 
   959     } 
   849 
   960 
   850     /// \brief Destructor.
   961     /// \brief Destructor.
   851     ///
   962     ///
   852     /// Destructor for UEdgeSetWriter.
   963     /// Destructor for UEdgeSetWriter.
   880                                   const ItemWriter& iw = ItemWriter()) {
   991                                   const ItemWriter& iw = ItemWriter()) {
   881       checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
   992       checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
   882       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
   993       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
   883       writers.push_back(
   994       writers.push_back(
   884 	make_pair(label, new _writer_bits::
   995 	make_pair(label, new _writer_bits::
   885 		  MapWriter<UEdge, Map, ItemWriter>(map, iw)));
   996 		  UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
   886       return *this;
   997       return *this;
   887     }
   998     }
   888 
   999 
   889     /// \brief Add a new directed edge map writer command for the writer.
  1000     /// \brief Add a new directed edge map writer command for the writer.
   890     ///
  1001     ///
   901     template <typename ItemWriter, typename Map>
  1012     template <typename ItemWriter, typename Map>
   902     UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map, 
  1013     UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map, 
   903                                  const ItemWriter& iw = ItemWriter()) {
  1014                                  const ItemWriter& iw = ItemWriter()) {
   904       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1015       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
   905       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
  1016       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
   906       writeUEdgeMap("+" + name, 
  1017       writeUEdgeMap("+" + label, 
   907                     _writer_bits::forwardComposeMap(graph, map), iw);
  1018                     _writer_bits::forwardComposeMap(graph, map), iw);
   908       writeUEdgeMap("-" + name, 
  1019       writeUEdgeMap("-" + label, 
   909                     _writer_bits::backwardComposeMap(graph, map), iw);
  1020                     _writer_bits::backwardComposeMap(graph, map), iw);
   910       return *this;
  1021       return *this;
   911     }
  1022     }
   912 
  1023 
   913   protected:
  1024   protected:
   935       }
  1046       }
   936       std::vector<UEdge> items;
  1047       std::vector<UEdge> items;
   937       for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
  1048       for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
   938         items.push_back(it);
  1049         items.push_back(it);
   939       }
  1050       }
   940       if (sortByLabel) {
  1051       if (forceSort) {
   941         if (labelMap) {
  1052         if (labelMap) {
   942           labelMap->sortByMap(items);
  1053           labelMap->sort(items);
   943         } else {
  1054         } else {
   944           typedef IdMap<Graph, UEdge> Map;
  1055           typedef IdMap<Graph, UEdge> Map;
   945           Map map(graph);
  1056           Map map(graph);
   946           _writer_bits::ComposeLess<Map> less(map);
  1057           _writer_bits::ComposeLess<Map> less(map);
   947           std::sort(items.begin(), items.end(), less);
  1058           std::sort(items.begin(), items.end(), less);
   976 
  1087 
   977     /// \brief Returns true if the undirected edgeset can write the labels of 
  1088     /// \brief Returns true if the undirected edgeset can write the labels of 
   978     /// the edges.
  1089     /// the edges.
   979     ///
  1090     ///
   980     /// Returns true if the undirected edgeset can write the labels of the 
  1091     /// Returns true if the undirected edgeset can write the labels of the 
   981     /// undirected edges. It is possible only if an "label" named map was 
  1092     /// undirected edges. It is possible only if a "label" named map was 
   982     /// written or the \c _forceLabelMap constructor parameter was true.
  1093     /// written or the \c _forceLabelMap constructor parameter was true.
   983     bool isLabelWriter() const {
  1094     bool isLabelWriter() const {
   984       return forceLabelMap || labelMap != 0;
  1095       return forceLabelMap || labelMap != 0;
   985     }
  1096     }
   986 
  1097 
   987     /// \brief Write the label of the given undirected edge.
  1098     /// \brief Write the label of the given undirected edge.
   988     ///
  1099     ///
   989     /// It writes the label of the given undirected edge. If there was written 
  1100     /// It writes the label of the given undirected edge. If there was written 
   990     /// an "label" named map then it will write the map value belongs to the 
  1101     /// a "label" named map then it will write the map value belongs to the 
   991     /// undirected edge. Otherwise if the \c forceLabel parameter was true it 
  1102     /// undirected edge. Otherwise if the \c forceLabel parameter was true it 
   992     /// will write its id in the graph. 
  1103     /// will write its id in the graph. 
   993     void writeLabel(std::ostream& os, const UEdge& item) const {
  1104     void writeLabel(std::ostream& os, const UEdge& item) const {
   994       if (forceLabelMap) {
  1105       if (forceLabelMap) {
   995 	os << graph.id(item);
  1106 	os << graph.id(item);
   999     } 
  1110     } 
  1000 
  1111 
  1001     /// \brief Write the label of the given edge.
  1112     /// \brief Write the label of the given edge.
  1002     ///
  1113     ///
  1003     /// It writes the label of the given edge. If there was written 
  1114     /// It writes the label of the given edge. If there was written 
  1004     /// an "label" named map then it will write the map value belongs to the 
  1115     /// a "label" named map then it will write the map value belongs to the 
  1005     /// edge. Otherwise if the \c forceLabel parameter was true it 
  1116     /// edge. Otherwise if the \c forceLabel parameter was true it 
  1006     /// will write its id in the graph. If the edge is forward map
  1117     /// will write its id in the graph. If the edge is forward map
  1007     /// then its prefix character is \c '+' elsewhere \c '-'.
  1118     /// then its prefix character is \c '+' elsewhere \c '-'.
  1008     void writeLabel(std::ostream& os, const Edge& item) const {
  1119     void writeLabel(std::ostream& os, const Edge& item) const {
  1009       if (graph.direction(item)) {
  1120       if (graph.direction(item)) {
  1010 	os << "+ ";
  1121 	os << "+";
  1011       } else {
  1122       } else {
  1012 	os << "- ";
  1123 	os << "-";
  1013       }
  1124       }
  1014       if (forceLabelMap) {
  1125       if (forceLabelMap) {
  1015 	os << graph.id(item);
  1126 	os << graph.id(static_cast<const UEdge&>(item));
  1016       } else {
  1127       } else {
  1017 	labelMap->write(os, item);
  1128 	labelMap->write(os, item);
  1018       }
  1129       }
  1019     } 
  1130     } 
  1020 
  1131 
       
  1132     /// \brief Sorts the given undirected edge vector by label.
       
  1133     ///
       
  1134     /// Sorts the given undirected edge vector by label. If there was
       
  1135     /// written a "label" named map then the vector will be sorted by
       
  1136     /// the values of this map. Otherwise if the \c forceLabel
       
  1137     /// parameter was true it will be sorted by its id in the graph.
       
  1138     void sortByLabel(std::vector<UEdge>& uedges) const {
       
  1139       if (labelMap) {
       
  1140 	labelMap->sort(uedges);
       
  1141       } else {
       
  1142 	typedef IdMap<Graph, UEdge> Map;
       
  1143 	Map map(graph);
       
  1144 	_writer_bits::ComposeLess<Map> less(map);
       
  1145 	std::sort(uedges.begin(), uedges.end(), less);
       
  1146       }
       
  1147     }
       
  1148 
       
  1149     /// \brief Sorts the given edge vector by label.
       
  1150     ///
       
  1151     /// Sorts the given edge vector by label. If there was written a
       
  1152     /// "label" named map then the vector will be sorted by the values
       
  1153     /// of this map. Otherwise if the \c forceLabel parameter was true
       
  1154     /// it will be sorted by its id in the graph.
       
  1155     void sortByLabel(std::vector<Edge>& edges) const {
       
  1156       if (labelMap) {
       
  1157 	labelMap->sort(graph, edges);
       
  1158       } else {
       
  1159 	typedef IdMap<Graph, Edge> Map;
       
  1160 	Map map(graph);
       
  1161 	_writer_bits::ComposeLess<Map> less(map);
       
  1162 	std::sort(edges.begin(), edges.end(), less);
       
  1163       }
       
  1164     }
       
  1165 
  1021   private:
  1166   private:
  1022 
  1167 
  1023     typedef std::vector<std::pair<std::string, _writer_bits::
  1168     typedef std::vector<std::pair<std::string, _writer_bits::
  1024 				  MapWriterBase<UEdge>*> > MapWriters;
  1169 				  UEdgeMapWriterBase<Graph>*> > MapWriters;
  1025     MapWriters writers;
  1170     MapWriters writers;
  1026 
  1171 
  1027     _writer_bits::MapWriterBase<UEdge>* labelMap;
  1172     _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
  1028     bool forceLabelMap;
  1173     bool forceLabelMap;
  1029     bool sortByLabel;
  1174     bool forceSort;
  1030    
  1175    
  1031     const Graph& graph;   
  1176     const Graph& graph;   
  1032     std::string name;
  1177     std::string name;
  1033 
  1178 
  1034     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
  1179     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
  1203     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
  1348     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
  1204     EdgeWriters writers;
  1349     EdgeWriters writers;
  1205 
  1350 
  1206     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
  1351     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
  1207   };
  1352   };
       
  1353 
  1208 
  1354 
  1209   /// \ingroup section_io
  1355   /// \ingroup section_io
  1210   /// \brief SectionWriter for writing named undirected edges.
  1356   /// \brief SectionWriter for writing named undirected edges.
  1211   ///
  1357   ///
  1212   /// The undirected edges section's header line is \c \@uedges 
  1358   /// The undirected edges section's header line is \c \@uedges 
  1319     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
  1465     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
  1320 
  1466 
  1321   };
  1467   };
  1322 
  1468 
  1323   /// \ingroup section_io
  1469   /// \ingroup section_io
       
  1470   /// \brief SectionWriter for writing extra node maps.
       
  1471   ///
       
  1472   /// The lemon format can store maps in the nodeset. This class let
       
  1473   /// you make distinict section to store maps. The main purpose of
       
  1474   /// this class is a logical separation of some maps. The other
       
  1475   /// useful application could be to store paths in node maps.
       
  1476   ///
       
  1477   /// The first line of the section contains the names of the maps
       
  1478   /// separated with white spaces. Each next line describes an item
       
  1479   /// in the itemset, and contains in the first column the label of
       
  1480   /// the item and then the mapped values for each map.
       
  1481   ///
       
  1482   /// \relates LemonWriter
       
  1483   template <typename _Graph, typename _Traits = DefaultWriterTraits>
       
  1484   class NodeMapWriter : public LemonWriter::SectionWriter {
       
  1485     typedef LemonWriter::SectionWriter Parent;
       
  1486   public:
       
  1487 
       
  1488     typedef _Graph Graph;
       
  1489     typedef _Traits Traits;
       
  1490     typedef typename Graph::Node Node;
       
  1491 
       
  1492     /// \brief Constructor.
       
  1493     ///
       
  1494     /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
       
  1495     /// attach it into the given LemonWriter. If the the
       
  1496     /// \c _forceSort is true then the writer will write the edges
       
  1497     /// sorted by the labels.
       
  1498     template <typename _LabelWriter>
       
  1499     NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
       
  1500 		 const _LabelWriter& _labelWriter,
       
  1501 		 const std::string& _name = std::string(),
       
  1502 		 bool _forceSort = true) 
       
  1503       : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
       
  1504       checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
       
  1505       labelWriter.reset(new _writer_bits::LabelWriter<Node, 
       
  1506 			_LabelWriter>(_labelWriter));
       
  1507     }
       
  1508 
       
  1509     /// \brief Destructor.
       
  1510     ///
       
  1511     /// Destructor for NodeMapWriter.
       
  1512     virtual ~NodeMapWriter() {
       
  1513       typename MapWriters::iterator it;
       
  1514       for (it = writers.begin(); it != writers.end(); ++it) {
       
  1515 	delete it->second;
       
  1516       }
       
  1517     }
       
  1518 
       
  1519   private:
       
  1520     NodeMapWriter(const NodeMapWriter&);
       
  1521     void operator=(const NodeMapWriter&);
       
  1522   
       
  1523   public:
       
  1524 
       
  1525     /// \brief Add a new node map writer command for the writer.
       
  1526     ///
       
  1527     /// Add a new node map writer command for the writer.
       
  1528     template <typename Map>
       
  1529     NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
       
  1530       return writeNodeMap<typename Traits::
       
  1531 	template Writer<typename Map::Value>, Map>(label, map);
       
  1532     }
       
  1533 
       
  1534     /// \brief Add a new node map writer command for the writer.
       
  1535     ///
       
  1536     /// Add a new node map writer command for the writer.
       
  1537     template <typename ItemWriter, typename Map>
       
  1538     NodeMapWriter& writeNodeMap(std::string label, const Map& map, 
       
  1539 			   const ItemWriter& iw = ItemWriter()) {
       
  1540       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
       
  1541       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
       
  1542       writers.push_back(
       
  1543 	make_pair(label, new _writer_bits::
       
  1544 		  MapWriter<Node, Map, ItemWriter>(map, iw)));
       
  1545       return *this;
       
  1546     }
       
  1547 
       
  1548   protected:
       
  1549 
       
  1550     /// \brief The header of the section.
       
  1551     ///
       
  1552     /// It gives back the header of the section.
       
  1553     virtual std::string header() {
       
  1554       return "@nodemaps " + name;
       
  1555     }
       
  1556 
       
  1557     /// \brief  Writer function of the section.
       
  1558     ///
       
  1559     /// Write the content of the section.
       
  1560     virtual void write(std::ostream& os) {
       
  1561       std::vector<Node> nodes;
       
  1562       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
       
  1563         nodes.push_back(it);
       
  1564       }
       
  1565       if (forceSort) {
       
  1566 	labelWriter->sort(nodes);
       
  1567       }
       
  1568       os << '\t';
       
  1569       for (int i = 0; i < int(writers.size()); ++i) {
       
  1570 	os << writers[i].first << '\t';
       
  1571       }
       
  1572       os << std::endl;
       
  1573       for (typename std::vector<Node>::iterator it = nodes.begin();
       
  1574            it != nodes.end(); ++it) {
       
  1575 
       
  1576 	labelWriter->write(os, *it); os << '\t';
       
  1577 	for (int i = 0; i < int(writers.size()); ++i) {
       
  1578 	  writers[i].second->write(os, *it);
       
  1579 	  os << '\t';
       
  1580 	}
       
  1581 	os << std::endl;
       
  1582       }
       
  1583     }
       
  1584 
       
  1585 
       
  1586   private:
       
  1587 
       
  1588     typedef std::vector<std::pair<std::string, _writer_bits::
       
  1589 				  MapWriterBase<Node>*> > MapWriters;
       
  1590     MapWriters writers;
       
  1591 
       
  1592     _writer_bits::MapWriterBase<Node>* labelMap;
       
  1593 
       
  1594     const Graph& graph;   
       
  1595     std::string name;
       
  1596     bool forceSort;
       
  1597 
       
  1598     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
       
  1599   };
       
  1600 
       
  1601   /// \ingroup section_io
       
  1602   /// \brief SectionWriter for writing extra edge maps.
       
  1603   ///
       
  1604   /// The lemon format can store maps in the edgeset. This class let
       
  1605   /// you make distinict section to store maps. The main purpose of
       
  1606   /// this class is a logical separation of some maps. The other
       
  1607   /// useful application could be to store paths in edge maps.
       
  1608   ///
       
  1609   /// The first line of the section contains the names of the maps
       
  1610   /// separated with white spaces. Each next line describes an item
       
  1611   /// in the itemset, and contains in the first column the label of
       
  1612   /// the item and then the mapped values for each map.
       
  1613   ///
       
  1614   /// \relates LemonWriter
       
  1615   template <typename _Graph, typename _Traits = DefaultWriterTraits>
       
  1616   class EdgeMapWriter : public LemonWriter::SectionWriter {
       
  1617     typedef LemonWriter::SectionWriter Parent;
       
  1618   public:
       
  1619 
       
  1620     typedef _Graph Graph;
       
  1621     typedef _Traits Traits;
       
  1622     typedef typename Graph::Edge Edge;
       
  1623 
       
  1624     /// \brief Constructor.
       
  1625     ///
       
  1626     /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
       
  1627     /// attach it into the given LemonWriter. If the the
       
  1628     /// \c _forceSort is true then the writer will write the edges
       
  1629     /// sorted by the labels.
       
  1630     template <typename _LabelWriter>
       
  1631     EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
       
  1632 		 const _LabelWriter& _labelWriter,
       
  1633 		 const std::string& _name = std::string(),
       
  1634 		 bool _forceSort = true) 
       
  1635       : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
       
  1636       checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
       
  1637       labelWriter.reset(new _writer_bits::LabelWriter<Edge, 
       
  1638 			_LabelWriter>(_labelWriter));
       
  1639     }
       
  1640 
       
  1641     /// \brief Destructor.
       
  1642     ///
       
  1643     /// Destructor for EdgeMapWriter.
       
  1644     virtual ~EdgeMapWriter() {
       
  1645       typename MapWriters::iterator it;
       
  1646       for (it = writers.begin(); it != writers.end(); ++it) {
       
  1647 	delete it->second;
       
  1648       }
       
  1649     }
       
  1650 
       
  1651   private:
       
  1652     EdgeMapWriter(const EdgeMapWriter&);
       
  1653     void operator=(const EdgeMapWriter&);
       
  1654   
       
  1655   public:
       
  1656 
       
  1657     /// \brief Add a new edge map writer command for the writer.
       
  1658     ///
       
  1659     /// Add a new edge map writer command for the writer.
       
  1660     template <typename Map>
       
  1661     EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
       
  1662       return writeEdgeMap<typename Traits::
       
  1663 	template Writer<typename Map::Value>, Map>(label, map);
       
  1664     }
       
  1665 
       
  1666     /// \brief Add a new edge map writer command for the writer.
       
  1667     ///
       
  1668     /// Add a new edge map writer command for the writer.
       
  1669     template <typename ItemWriter, typename Map>
       
  1670     EdgeMapWriter& writeEdgeMap(std::string label, const Map& map, 
       
  1671 				const ItemWriter& iw = ItemWriter()) {
       
  1672       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
       
  1673       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
       
  1674       writers.push_back(
       
  1675 	make_pair(label, new _writer_bits::
       
  1676 		  MapWriter<Edge, Map, ItemWriter>(map, iw)));
       
  1677       return *this;
       
  1678     }
       
  1679 
       
  1680   protected:
       
  1681 
       
  1682     /// \brief The header of the section.
       
  1683     ///
       
  1684     /// It gives back the header of the section.
       
  1685     virtual std::string header() {
       
  1686       return "@edgemaps " + name;
       
  1687     }
       
  1688 
       
  1689     /// \brief  Writer function of the section.
       
  1690     ///
       
  1691     /// Write the content of the section.
       
  1692     virtual void write(std::ostream& os) {
       
  1693       std::vector<Edge> edges;
       
  1694       for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
       
  1695         edges.push_back(it);
       
  1696       }
       
  1697       if (forceSort) {
       
  1698 	labelWriter->sort(edges);
       
  1699       }
       
  1700       os << '\t';
       
  1701       for (int i = 0; i < int(writers.size()); ++i) {
       
  1702 	os << writers[i].first << '\t';
       
  1703       }
       
  1704       os << std::endl;
       
  1705       for (typename std::vector<Edge>::iterator it = edges.begin();
       
  1706            it != edges.end(); ++it) {
       
  1707 
       
  1708 	labelWriter->write(os, *it); os << '\t';
       
  1709 	for (int i = 0; i < int(writers.size()); ++i) {
       
  1710 	  writers[i].second->write(os, *it);
       
  1711 	  os << '\t';
       
  1712 	}
       
  1713 	os << std::endl;
       
  1714       }
       
  1715     }
       
  1716 
       
  1717 
       
  1718   private:
       
  1719 
       
  1720     typedef std::vector<std::pair<std::string, _writer_bits::
       
  1721 				  MapWriterBase<Edge>*> > MapWriters;
       
  1722     MapWriters writers;
       
  1723 
       
  1724     _writer_bits::MapWriterBase<Edge>* labelMap;
       
  1725 
       
  1726     const Graph& graph;   
       
  1727     std::string name;
       
  1728     bool forceSort;
       
  1729 
       
  1730     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
       
  1731   };
       
  1732 
       
  1733   /// \ingroup section_io
       
  1734   /// \brief SectionWriter for writing extra undirected edge maps.
       
  1735   ///
       
  1736   /// The lemon format can store maps in the uedgeset. This class let
       
  1737   /// you make distinict section to store maps. The main purpose of
       
  1738   /// this class is a logical separation of some maps. The other
       
  1739   /// useful application could be to store paths in undirected edge
       
  1740   /// maps.
       
  1741   ///
       
  1742   /// The first line of the section contains the names of the maps
       
  1743   /// separated with white spaces. Each next line describes an item
       
  1744   /// in the itemset, and contains in the first column the label of
       
  1745   /// the item and then the mapped values for each map.
       
  1746   ///
       
  1747   /// \relates LemonWriter
       
  1748   template <typename _Graph, typename _Traits = DefaultWriterTraits>
       
  1749   class UEdgeMapWriter : public LemonWriter::SectionWriter {
       
  1750     typedef LemonWriter::SectionWriter Parent;
       
  1751   public:
       
  1752 
       
  1753     typedef _Graph Graph;
       
  1754     typedef _Traits Traits;
       
  1755     typedef typename Graph::UEdge UEdge;
       
  1756     typedef typename Graph::Edge Edge;
       
  1757 
       
  1758     /// \brief Constructor.
       
  1759     ///
       
  1760     /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
       
  1761     /// attach it into the given LemonWriter. If the the
       
  1762     /// \c _forceSort is true then the writer will write the uedges
       
  1763     /// sorted by the labels.
       
  1764     template <typename _LabelWriter>
       
  1765     UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
       
  1766 		 const _LabelWriter& _labelWriter,
       
  1767 		 const std::string& _name = std::string(),
       
  1768 		 bool _forceSort = true) 
       
  1769       : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
       
  1770       checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
       
  1771       labelWriter.reset(new _writer_bits::LabelWriter<UEdge, 
       
  1772 			    _LabelWriter>(_labelWriter));
       
  1773     }
       
  1774 
       
  1775     /// \brief Destructor.
       
  1776     ///
       
  1777     /// Destructor for UEdgeMapWriter.
       
  1778     virtual ~UEdgeMapWriter() {
       
  1779       typename MapWriters::iterator it;
       
  1780       for (it = writers.begin(); it != writers.end(); ++it) {
       
  1781 	delete it->second;
       
  1782       }
       
  1783     }
       
  1784 
       
  1785   private:
       
  1786     UEdgeMapWriter(const UEdgeMapWriter&);
       
  1787     void operator=(const UEdgeMapWriter&);
       
  1788   
       
  1789   public:
       
  1790 
       
  1791     /// \brief Add a new undirected edge map writer command for the writer.
       
  1792     ///
       
  1793     /// Add a new undirected edge map writer command for the writer.
       
  1794     template <typename Map>
       
  1795     UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
       
  1796       return writeUEdgeMap<typename Traits::
       
  1797 	template Writer<typename Map::Value>, Map>(label, map);
       
  1798     }
       
  1799 
       
  1800     /// \brief Add a new undirected edge map writer command for the writer.
       
  1801     ///
       
  1802     /// Add a new undirected edge map writer command for the writer.
       
  1803     template <typename ItemWriter, typename Map>
       
  1804     UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map, 
       
  1805 			   const ItemWriter& iw = ItemWriter()) {
       
  1806       checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
       
  1807       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
       
  1808       writers.push_back(
       
  1809 	make_pair(label, new _writer_bits::
       
  1810 		  MapWriter<UEdge, Map, ItemWriter>(map, iw)));
       
  1811       return *this;
       
  1812     }
       
  1813 
       
  1814     /// \brief Add a new directed edge map writer command for the writer.
       
  1815     ///
       
  1816     /// Add a new directed map writer command for the writer.
       
  1817     template <typename Map>
       
  1818     UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
       
  1819       return writeEdgeMap<typename Traits::
       
  1820 	template Writer<typename Map::Value>, Map>(label, map);
       
  1821     }
       
  1822 
       
  1823     /// \brief Add a new directed map writer command for the writer.
       
  1824     ///
       
  1825     /// Add a new directed map writer command for the writer.
       
  1826     template <typename ItemWriter, typename Map>
       
  1827     UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map, 
       
  1828                                  const ItemWriter& iw = ItemWriter()) {
       
  1829       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
       
  1830       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
       
  1831       writeUEdgeMap("+" + label, 
       
  1832                     _writer_bits::forwardComposeMap(graph, map), iw);
       
  1833       writeUEdgeMap("-" + label, 
       
  1834                     _writer_bits::backwardComposeMap(graph, map), iw);
       
  1835       return *this;
       
  1836     }
       
  1837 
       
  1838   protected:
       
  1839 
       
  1840     /// \brief The header of the section.
       
  1841     ///
       
  1842     /// It gives back the header of the section.
       
  1843     virtual std::string header() {
       
  1844       return "@uedgemaps " + name;
       
  1845     }
       
  1846 
       
  1847     /// \brief  Writer function of the section.
       
  1848     ///
       
  1849     /// Write the content of the section.
       
  1850     virtual void write(std::ostream& os) {
       
  1851       std::vector<UEdge> uedges;
       
  1852       for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
       
  1853         uedges.push_back(it);
       
  1854       }
       
  1855       if (forceSort) {
       
  1856 	labelWriter->sort(uedges);
       
  1857       }
       
  1858       os << '\t';
       
  1859       for (int i = 0; i < int(writers.size()); ++i) {
       
  1860 	os << writers[i].first << '\t';
       
  1861       }
       
  1862       os << std::endl;
       
  1863       for (typename std::vector<UEdge>::iterator it = uedges.begin();
       
  1864            it != uedges.end(); ++it) {
       
  1865 
       
  1866 	labelWriter->write(os, *it); os << '\t';
       
  1867 	for (int i = 0; i < int(writers.size()); ++i) {
       
  1868 	  writers[i].second->write(os, *it);
       
  1869 	  os << '\t';
       
  1870 	}
       
  1871 	os << std::endl;
       
  1872       }
       
  1873     }
       
  1874 
       
  1875 
       
  1876   private:
       
  1877 
       
  1878     typedef std::vector<std::pair<std::string, _writer_bits::
       
  1879 				  MapWriterBase<UEdge>*> > MapWriters;
       
  1880     MapWriters writers;
       
  1881 
       
  1882     _writer_bits::MapWriterBase<UEdge>* labelMap;
       
  1883 
       
  1884     const Graph& graph;   
       
  1885     std::string name;
       
  1886     bool forceSort;
       
  1887 
       
  1888     std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
       
  1889   };
       
  1890 
       
  1891 
       
  1892   /// \ingroup section_io
  1324   /// \brief SectionWriter for attributes.
  1893   /// \brief SectionWriter for attributes.
  1325   ///
  1894   ///
  1326   /// The lemon format can store multiple attribute set. Each set has
  1895   /// The lemon format can store multiple attribute set. Each set has
  1327   /// the header line \c \@attributes \c attributes_name, but the 
  1896   /// the header line \c \@attributes \c attributes_name, but the 
  1328   /// attributeset_name may be empty.
  1897   /// attributeset_name may be empty.