lemon/lemon_writer.h
author deba
Thu, 20 Mar 2008 16:25:47 +0000
changeset 2596 9c00e972cdfd
parent 2502 9c23c3762bc5
permissions -rw-r--r--
Back porting commit 81563e019fa4
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2008
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 ///\ingroup lemon_io
    20 ///\file
    21 ///\brief Lemon Format writer.
    22 
    23 #ifndef LEMON_LEMON_WRITER_H
    24 #define LEMON_LEMON_WRITER_H
    25 
    26 #include <iostream>
    27 #include <fstream>
    28 #include <string>
    29 #include <vector>
    30 #include <algorithm>
    31 #include <map>
    32 #include <memory>
    33 
    34 #include <lemon/error.h>
    35 #include <lemon/bits/invalid.h>
    36 #include <lemon/graph_utils.h>
    37 #include <lemon/bits/item_writer.h>
    38 #include <lemon/bits/utility.h>
    39 #include <lemon/maps.h>
    40 #include <lemon/dim2.h>
    41 
    42 #include <lemon/concept_check.h>
    43 #include <lemon/concepts/maps.h>
    44 
    45 
    46 namespace lemon {
    47 
    48   namespace _writer_bits {
    49     
    50     template <typename T>
    51     bool operator<(T, T) {
    52       throw DataFormatError("Label is not comparable");
    53     }
    54 
    55     template <typename T>
    56     struct Less {
    57       bool operator()(const T& p, const T& q) const {
    58 	return p < q;
    59       }
    60     };
    61 
    62     template <typename Map>
    63     struct ComposeLess {
    64       ComposeLess(const Map& _map) : map(_map), less() {}
    65 
    66       bool operator()(const typename Map::Key& p, 
    67                       const typename Map::Key& q) const {
    68 	return less(map[p], map[q]);
    69       }
    70       const Map& map;
    71       Less<typename Map::Value> less;
    72     };
    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 
    90     template <typename Item>
    91     class ItemLabelWriter {
    92     public:
    93 
    94       bool isLabelWriter() { return true; }
    95 
    96       void writeLabel(std::ostream&, const Item&) {}
    97       
    98       template <class _ItemLabelWriter>
    99       struct Constraints {
   100 	void constraints() {
   101 	  bool b = writer.isLabelWriter();
   102 	  ignore_unused_variable_warning(b);
   103 	  writer.writeLabel(os, item);
   104 	}
   105 	_ItemLabelWriter& writer;
   106 	std::ostream& os;
   107 	const Item& item;
   108       };
   109 
   110     };
   111 
   112     template <typename Item>
   113     class ItemWriter {
   114     public:
   115 
   116       void write(std::ostream&, const Item&) {}
   117       
   118       template <class _ItemWriter>
   119       struct Constraints {
   120 	void constraints() {
   121 	  writer.write(os, item);
   122 	}
   123 	_ItemWriter& writer;
   124 	std::ostream& os;
   125 	const Item& item;
   126       };
   127 
   128     };
   129 
   130     template <typename Map>
   131     struct Ref { typedef const Map& Type; };
   132 
   133     template <typename Graph, typename Map>
   134     class ForwardComposeMap {
   135     public:
   136       typedef typename Graph::UEdge Key;
   137       typedef typename Map::Value Value;
   138 
   139       ForwardComposeMap(const Graph& _graph, const Map& _map) 
   140 	: graph(_graph), map(_map) {}
   141       
   142       Value operator[](const Key& key) const {
   143 	return map[graph.direct(key, true)];
   144       }
   145 
   146     private:
   147       const Graph& graph;
   148       typename Ref<Map>::Type map;
   149     };
   150 
   151     template <typename Graph, typename Map>
   152     ForwardComposeMap<Graph, Map>
   153     forwardComposeMap(const Graph& graph, const Map& map) {
   154       return ForwardComposeMap<Graph, Map>(graph, map);
   155     }
   156 
   157     template <typename Graph, typename Map>
   158     class BackwardComposeMap {
   159     public:
   160       typedef typename Graph::UEdge Key;
   161       typedef typename Map::Value Value;
   162 
   163       BackwardComposeMap(const Graph& _graph, const Map& _map) 
   164 	: graph(_graph), map(_map) {}
   165       
   166       Value operator[](const Key& key) const {
   167 	return map[graph.direct(key, false)];
   168       }
   169 
   170     private:
   171       const Graph& graph;
   172       typename Ref<Map>::Type map;
   173     };
   174 
   175     template <typename Graph, typename Map>
   176     BackwardComposeMap<Graph, Map>
   177     backwardComposeMap(const Graph& graph, const Map& map) {
   178       return BackwardComposeMap<Graph, Map>(graph, map);
   179     }
   180 
   181     template <typename Graph, typename Map>
   182     struct Ref<ForwardComposeMap<Graph, Map> > { 
   183       typedef ForwardComposeMap<Graph, Map> Type;
   184     };
   185 
   186     template <typename Graph, typename Map>
   187     struct Ref<BackwardComposeMap<Graph, Map> > { 
   188       typedef BackwardComposeMap<Graph, Map> Type; 
   189     };
   190 
   191     template <typename Map>
   192     struct Ref<dim2::XMap<Map> > { 
   193       typedef dim2::XMap<Map> Type;
   194     };
   195     template <typename Map>
   196     struct Ref<dim2::ConstXMap<Map> > { 
   197       typedef dim2::ConstXMap<Map> Type;
   198     };
   199 
   200     template <typename Map>
   201     struct Ref<dim2::YMap<Map> > { 
   202       typedef dim2::YMap<Map> Type;
   203     };
   204     template <typename Map>
   205     struct Ref<dim2::ConstYMap<Map> > { 
   206       typedef dim2::ConstYMap<Map> Type;
   207     };
   208 
   209 
   210     template <typename _Item>    
   211     class MapWriterBase {
   212     public:
   213       typedef _Item Item;
   214 
   215       virtual ~MapWriterBase() {}
   216 
   217       virtual void write(std::ostream& os, const Item& item) const = 0;
   218       virtual void sort(std::vector<Item>&) const = 0;
   219     };
   220 
   221 
   222     template <typename _Item, typename _Map, typename _Writer>
   223     class MapWriter : public MapWriterBase<_Item> {
   224     public:
   225       typedef _Map Map;
   226       typedef _Writer Writer;
   227       typedef typename Writer::Value Value;
   228       typedef _Item Item;
   229       
   230       typename _writer_bits::Ref<Map>::Type map;
   231       Writer writer;
   232 
   233       MapWriter(const Map& _map, const Writer& _writer) 
   234 	: map(_map), writer(_writer) {}
   235 
   236       virtual ~MapWriter() {}
   237 
   238       virtual void write(std::ostream& os, const Item& item) const {
   239 	Value value = map[item];
   240 	writer.write(os, value);
   241       }
   242 
   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 {
   296         ComposeLess<Map> less(map);
   297         std::sort(items.begin(), items.end(), less);
   298       }
   299 
   300     };
   301 
   302 
   303     class ValueWriterBase {
   304     public:
   305       virtual ~ValueWriterBase() {}
   306       virtual void write(std::ostream&) = 0;
   307     };
   308 
   309     template <typename _Value, typename _Writer>
   310     class ValueWriter : public ValueWriterBase {
   311     public:
   312       typedef _Value Value;
   313       typedef _Writer Writer;
   314 
   315       ValueWriter(const Value& _value, const Writer& _writer)
   316  	: value(_value), writer(_writer) {}
   317 
   318       virtual void write(std::ostream& os) {
   319 	writer.write(os, value);
   320       }
   321     private:
   322       const Value& value;
   323       Writer writer;
   324     };
   325     
   326 
   327     template <typename _Item>
   328     class LabelWriterBase {
   329     public:
   330       typedef _Item Item;
   331       virtual ~LabelWriterBase() {}
   332       virtual void write(std::ostream&, const Item&) const = 0;
   333       virtual void sort(std::vector<Item>&) const = 0;
   334       virtual bool isLabelWriter() const = 0;
   335       virtual LabelWriterBase* clone() const = 0;
   336     };
   337 
   338     template <typename _Item, typename _BoxedLabelWriter>
   339     class LabelWriter : public LabelWriterBase<_Item> {
   340     public:
   341       typedef _Item Item;
   342       typedef _BoxedLabelWriter BoxedLabelWriter;
   343 
   344       const BoxedLabelWriter& labelWriter;
   345 
   346       LabelWriter(const BoxedLabelWriter& _labelWriter) 
   347 	: labelWriter(_labelWriter) {}
   348 
   349       virtual void write(std::ostream& os, const Item& item) const {
   350 	labelWriter.writeLabel(os, item);
   351       }
   352       virtual void sort(std::vector<Item>& items) const {
   353 	labelWriter.sortByLabel(items);
   354       }
   355 
   356       virtual bool isLabelWriter() const {
   357 	return labelWriter.isLabelWriter();
   358       }
   359 
   360       virtual LabelWriter* clone() const {
   361 	return new LabelWriter(labelWriter);
   362       }
   363     };
   364 
   365   }
   366 
   367   /// \ingroup lemon_io
   368   /// \brief Lemon Format writer class.
   369   /// 
   370   /// The Lemon Format contains several sections. We do not want to
   371   /// determine what sections are in a lemon file we give only a framework
   372   /// to write a section oriented format.
   373   ///
   374   /// In the Lemon Format each section starts with a line contains a \c \@
   375   /// character on the first not white space position. This line is the
   376   /// header line of the section. Each next lines belong to this section
   377   /// while it does not starts with \c \@ character. This line can start a 
   378   /// new section or if it can close the file with the \c \@end line.
   379   /// The file format ignore the empty lines and it may contain comments
   380   /// started with a \c # character to the end of the line. 
   381   ///
   382   /// The framework provides an abstract LemonWriter::SectionWriter class
   383   /// what defines the interface of a SectionWriter. The SectionWriter
   384   /// has the \c header() member function what gives back the header of the
   385   /// section. After that it will be called the \c write() member which
   386   /// should write the content of the section.
   387   ///
   388   /// \relates GraphWriter
   389   /// \relates NodeSetWriter
   390   /// \relates EdgeSetWriter
   391   /// \relates NodesWriter
   392   /// \relates EdgesWriter
   393   /// \relates AttributeWriter
   394   class LemonWriter {
   395   public:
   396 
   397     /// \brief Abstract base class for writing a section.
   398     ///
   399     /// This class has an \c header() member function what gives back
   400     /// the header line of the section. The \c write() member should
   401     /// write the content of the section to the stream.
   402     class SectionWriter {
   403       friend class LemonWriter;
   404     protected:
   405       /// \brief Constructor for SectionWriter.
   406       ///
   407       /// Constructor for SectionWriter. It attach this writer to
   408       /// the given LemonWriter.
   409       SectionWriter(LemonWriter& writer) {
   410 	writer.attach(*this);
   411       }
   412       
   413       virtual ~SectionWriter() {}
   414 
   415       /// \brief The header of section.
   416       ///
   417       /// It gives back the header of the section.
   418       virtual std::string header() = 0;
   419 
   420       /// \brief Writer function of the section.
   421       ///
   422       /// Write the content of the section.
   423       virtual void write(std::ostream& os) = 0;
   424       
   425       /// \brief Gives back true when the section should be written.
   426       ///
   427       /// Gives back true when the section should be written.
   428       virtual bool valid() { return true; }
   429     };
   430 
   431     /// \brief Constructor for LemonWriter.
   432     ///
   433     /// Constructor for LemonWriter which writes to the given stream.
   434     LemonWriter(std::ostream& _os) 
   435       : os(&_os), own_os(false) {}
   436 
   437     /// \brief Constructor for LemonWriter.
   438     ///
   439     /// Constructor for LemonWriter which writes to the given file.
   440     LemonWriter(const std::string& filename) 
   441       : os(0), own_os(true) {
   442       os = new std::ofstream(filename.c_str());
   443     }
   444 
   445     /// \brief Desctructor for LemonWriter.
   446     ///
   447     /// Desctructor for LemonWriter.
   448     ~LemonWriter() {
   449       if (own_os) {
   450 	delete os;
   451       }
   452     }
   453 
   454   private:
   455     LemonWriter(const LemonWriter&);
   456     void operator=(const LemonWriter&);
   457 
   458     void attach(SectionWriter& writer) {
   459       writers.push_back(&writer);
   460     }
   461 
   462   public:
   463 
   464     /// \brief Executes the LemonWriter.
   465     /// 
   466     /// It executes the LemonWriter.
   467     void run() {
   468       SectionWriters::iterator it;
   469       for (it = writers.begin(); it != writers.end(); ++it) {
   470         if ((*it)->valid()) {
   471           *os << (*it)->header() << std::endl;
   472           (*it)->write(*os);
   473         }
   474       }
   475       *os << "@end" << std::endl;
   476     }
   477 
   478 
   479   private:
   480 
   481     std::ostream* os;
   482     bool own_os;
   483 
   484     typedef std::vector<SectionWriter*> SectionWriters;
   485     SectionWriters writers;
   486 
   487   };
   488 
   489   /// \ingroup section_io
   490   /// \brief SectionWriter for writing a graph's nodeset.
   491   ///
   492   /// The lemon format can store multiple graph nodesets with several maps.
   493   /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but 
   494   /// the \c nodeset_name may be empty.
   495   ///
   496   /// The first line of the section contains the names of the maps separated
   497   /// with white spaces. Each next lines describes a node in the nodeset, and
   498   /// contains the mapped values for each map.
   499   ///
   500   /// If the nodeset contains an \c "label" named map then it will be regarded
   501   /// as label map. This map should contain only unique values and when the 
   502   /// \c writeLabel() member will be called with a node it will write it's 
   503   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   504   /// then the label map will be the id in the graph. In addition if the
   505   /// the \c _forceSort is true then the writer will write the nodes
   506   /// sorted by the labels.
   507   ///
   508   /// \relates LemonWriter
   509   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   510   class NodeSetWriter : public LemonWriter::SectionWriter {
   511     typedef LemonWriter::SectionWriter Parent;
   512   public:
   513 
   514     typedef _Graph Graph;
   515     typedef _Traits Traits;
   516     typedef typename Graph::Node Node;
   517 
   518     /// \brief Constructor.
   519     ///
   520     /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
   521     /// attach it into the given LemonWriter. If the \c _forceLabelMap
   522     /// parameter is true then the writer will write own label map when
   523     /// the user does not give "label" named map. In addition if the
   524     /// the \c _forceSort is true then the writer will write the edges
   525     /// sorted by the labels.
   526     NodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   527 		  const std::string& _name = std::string(), 
   528 		  bool _forceLabelMap = true, bool _forceSort = true) 
   529       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), 
   530 	forceSort(_forceSort), graph(_graph), name(_name) {}
   531 
   532     /// \brief Destructor.
   533     ///
   534     /// Destructor for NodeSetWriter.
   535     virtual ~NodeSetWriter() {
   536       typename MapWriters::iterator it;
   537       for (it = writers.begin(); it != writers.end(); ++it) {
   538 	delete it->second;
   539       }
   540     }
   541 
   542   private:
   543     NodeSetWriter(const NodeSetWriter&);
   544     void operator=(const NodeSetWriter&);
   545   
   546   public:
   547 
   548     /// \brief Add a new node map writer command for the writer.
   549     ///
   550     /// Add a new node map writer command for the writer.
   551     template <typename Map>
   552     NodeSetWriter& writeNodeMap(std::string label, const Map& map) {
   553       return writeNodeMap<typename Traits::
   554 	template Writer<typename Map::Value>, Map>(label, map);
   555     }
   556 
   557     /// \brief Add a new node map writer command for the writer.
   558     ///
   559     /// Add a new node map writer command for the writer.
   560     template <typename ItemWriter, typename Map>
   561     NodeSetWriter& writeNodeMap(std::string label, const Map& map, 
   562 			    const ItemWriter& iw = ItemWriter()) {
   563       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   564       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
   565       writers.push_back(
   566 	make_pair(label, new _writer_bits::
   567 		  MapWriter<Node, Map, ItemWriter>(map, iw)));
   568       return *this;
   569     }
   570 
   571   protected:
   572 
   573     /// \brief The header of the section.
   574     ///
   575     /// It gives back the header of the section.
   576     virtual std::string header() {
   577       return "@nodeset " + name;
   578     }
   579 
   580     /// \brief  Writer function of the section.
   581     ///
   582     /// Write the content of the section.
   583     virtual void write(std::ostream& os) {
   584       for (int i = 0; i < int(writers.size()); ++i) {
   585 	if (writers[i].first == "label") {
   586 	  labelMap = writers[i].second;
   587 	  forceLabelMap = false;
   588 	  break;
   589 	}
   590       }
   591       std::vector<Node> items;
   592       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
   593         items.push_back(it);
   594       }
   595       if (forceSort) {
   596         if (labelMap) {
   597           labelMap->sort(items);
   598         } else {
   599           typedef IdMap<Graph, Node> Map;
   600           Map map(graph);
   601           _writer_bits::ComposeLess<Map> less(map);
   602           std::sort(items.begin(), items.end(), less);
   603         }
   604       }
   605       if (forceLabelMap) {
   606 	os << "label\t";
   607       }
   608       for (int i = 0; i < int(writers.size()); ++i) {
   609 	os << writers[i].first << '\t';
   610       }
   611       os << std::endl;
   612       for (typename std::vector<Node>::iterator it = items.begin();
   613            it != items.end(); ++it) {
   614 	if (forceLabelMap) {
   615 	  os << graph.id(*it) << '\t';
   616 	}
   617 	for (int i = 0; i < int(writers.size()); ++i) {
   618 	  writers[i].second->write(os, *it);
   619 	  os << '\t';
   620 	}
   621 	os << std::endl;
   622       }
   623     }
   624 
   625   public:
   626 
   627     /// \brief Returns true if the nodeset can write the labels of the nodes.
   628     ///
   629     /// Returns true if the nodeset can write the labels of the nodes.
   630     /// It is possible only if a "label" named map was written or the 
   631     /// \c _forceLabelMap constructor parameter was true.
   632     bool isLabelWriter() const {
   633       return labelMap != 0 || forceLabelMap;
   634     }
   635 
   636     /// \brief Write the label of the given node.
   637     ///
   638     /// It writes the label of the given node. If there was written a "label"
   639     /// named map then it will write the map value belongs to the node.
   640     /// Otherwise if the \c forceLabel parameter was true it will write
   641     /// its label in the graph. 
   642     void writeLabel(std::ostream& os, const Node& item) const {
   643       if (forceLabelMap) {
   644 	os << graph.id(item);
   645       } else {
   646 	labelMap->write(os, item);
   647       }
   648     }
   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 
   667   private:
   668 
   669     typedef std::vector<std::pair<std::string, _writer_bits::
   670 				  MapWriterBase<Node>*> > MapWriters;
   671     MapWriters writers;
   672 
   673     _writer_bits::MapWriterBase<Node>* labelMap;
   674     bool forceLabelMap;
   675     bool forceSort;
   676    
   677     const Graph& graph;   
   678     std::string name;
   679 
   680   };
   681 
   682   /// \ingroup section_io
   683   /// \brief SectionWriter for writing a bipartite graph's nodeset.
   684   ///
   685   /// The lemon format can store multiple bipartite graph nodesets
   686   /// with several maps.  The nodeset section's header line is \c
   687   /// \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_name may be empty.
   688   ///
   689   /// The first line of the section contains the names of the maps separated
   690   /// with white spaces. Each next lines describes a node in the nodeset, and
   691   /// contains the mapped values for each map.
   692   ///
   693   /// If the nodeset contains an \c "label" named map then it will be regarded
   694   /// as label map. This map should contain only unique values and when the 
   695   /// \c writeLabel() member will be called with a node it will write it's 
   696   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   697   /// then the label map will be the id in the graph. In addition if the
   698   /// the \c _forceSort is true then the writer will write the edges
   699   /// sorted by the labels.
   700   ///
   701   /// \relates LemonWriter
   702   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   703   class BpNodeSetWriter : public LemonWriter::SectionWriter {
   704     typedef LemonWriter::SectionWriter Parent;
   705   public:
   706 
   707     typedef _Graph Graph;
   708     typedef _Traits Traits;
   709     typedef typename Graph::Node Node;
   710 
   711     /// \brief Constructor.
   712     ///
   713     /// Constructor for BpNodeSetWriter. It creates the BpNodeSetWriter and
   714     /// attach it into the given LemonWriter. If the \c _forceLabelMap
   715     /// parameter is true then the writer will write own label map when
   716     /// the user does not give "label" named map. In addition if the
   717     /// the \c _forceSort is true then the writer will write the nodes
   718     /// sorted by the labels.
   719     BpNodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   720 		  const std::string& _name = std::string(), 
   721 		  bool _forceLabelMap = true, bool _forceSort = true) 
   722       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), 
   723 	forceSort(_forceSort), graph(_graph), name(_name) {}
   724 
   725     /// \brief Destructor.
   726     ///
   727     /// Destructor for BpNodeSetWriter.
   728     virtual ~BpNodeSetWriter() {
   729       typename MapWriters::iterator it;
   730       for (it = writers.begin(); it != writers.end(); ++it) {
   731 	delete it->second;
   732       }
   733     }
   734 
   735   private:
   736     BpNodeSetWriter(const BpNodeSetWriter&);
   737     void operator=(const BpNodeSetWriter&);
   738   
   739   public:
   740 
   741     /// \brief Add a new A-node map writer command for the writer.
   742     ///
   743     /// Add a new A-node map writer command for the writer.
   744     template <typename Map>
   745     BpNodeSetWriter& writeANodeMap(std::string label, const Map& map) {
   746       return writeANodeMap<typename Traits::
   747 	template Writer<typename Map::Value>, Map>(label, map);
   748     }
   749 
   750     /// \brief Add a new A-node map writer command for the writer.
   751     ///
   752     /// Add a new A-node map writer command for the writer.
   753     template <typename ItemWriter, typename Map>
   754     BpNodeSetWriter& writeANodeMap(std::string label, const Map& map, 
   755 				   const ItemWriter& iw = ItemWriter()) {
   756       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   757       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
   758       if (label == "label") {
   759 	throw IoParameterError("Label cannot be A-node map");
   760       }
   761       awriters.push_back(make_pair(label, new _writer_bits::
   762 				   MapWriter<Node, Map, ItemWriter>(map, iw)));
   763       return *this;
   764     }
   765 
   766     /// \brief Add a new B-node map writer command for the writer.
   767     ///
   768     /// Add a new B-node map writer command for the writer.
   769     template <typename Map>
   770     BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map) {
   771       return writeBNodeMap<typename Traits::
   772 	template Writer<typename Map::Value>, Map>(label, map);
   773     }
   774 
   775     /// \brief Add a new B-node map writer command for the writer.
   776     ///
   777     /// Add a new B-node map writer command for the writer.
   778     template <typename ItemWriter, typename Map>
   779     BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map, 
   780 				   const ItemWriter& iw = ItemWriter()) {
   781       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   782       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
   783       if (label == "label") {
   784 	throw IoParameterError("Label cannot be B-node map");
   785       }
   786       bwriters.push_back(make_pair(label, new _writer_bits::
   787 				   MapWriter<Node, Map, ItemWriter>(map, iw)));
   788       return *this;
   789     }
   790 
   791     /// \brief Add a new node map writer command for the writer.
   792     ///
   793     /// Add a new node map writer command for the writer.
   794     template <typename Map>
   795     BpNodeSetWriter& writeNodeMap(std::string label, const Map& map) {
   796       return writeNodeMap<typename Traits::
   797 	template Writer<typename Map::Value>, Map>(label, map);
   798     }
   799 
   800     /// \brief Add a new node map writer command for the writer.
   801     ///
   802     /// Add a new node map writer command for the writer.
   803     template <typename ItemWriter, typename Map>
   804     BpNodeSetWriter& writeNodeMap(std::string label, const Map& map, 
   805 				  const ItemWriter& iw = ItemWriter()) {
   806       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   807       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
   808       writers.push_back(make_pair(label, new _writer_bits::
   809 				  MapWriter<Node, Map, ItemWriter>(map, iw)));
   810       return *this;
   811     }
   812 
   813   protected:
   814 
   815     /// \brief The header of the section.
   816     ///
   817     /// It gives back the header of the section.
   818     virtual std::string header() {
   819       return "@bpnodeset " + name;
   820     }
   821 
   822     /// \brief Writer function of the section.
   823     ///
   824     /// Write the content of the section.
   825     virtual void write(std::ostream& os) {
   826       for (int i = 0; i < int(writers.size()); ++i) {
   827 	if (writers[i].first == "label") {
   828 	  labelMap = writers[i].second;
   829 	  forceLabelMap = false;
   830 	  break;
   831 	}
   832       }
   833       {
   834 	os << "&anodeset ";
   835 	std::vector<Node> items;
   836 	for (typename Graph::ANodeIt it(graph); it != INVALID; ++it) {
   837 	  items.push_back(it);
   838 	}
   839 	if (forceSort) {
   840 	  if (labelMap) {
   841 	    labelMap->sort(items);
   842 	  } else {
   843 	    typedef IdMap<Graph, Node> Map;
   844 	    Map map(graph);
   845 	    _writer_bits::ComposeLess<Map> less(map);
   846 	    std::sort(items.begin(), items.end(), less);
   847 	  }
   848 	}
   849 	if (forceLabelMap) {
   850 	  os << "label\t";
   851 	}
   852 	for (int i = 0; i < int(writers.size()); ++i) {
   853 	  os << writers[i].first << '\t';
   854 	}
   855 	for (int i = 0; i < int(awriters.size()); ++i) {
   856 	  os << awriters[i].first << '\t';
   857 	}
   858 	os << std::endl;
   859 	for (typename std::vector<Node>::iterator it = items.begin();
   860 	     it != items.end(); ++it) {
   861 	  if (forceLabelMap) {
   862 	    os << graph.id(*it) << '\t';
   863 	  }
   864 	  for (int i = 0; i < int(writers.size()); ++i) {
   865 	    writers[i].second->write(os, *it);
   866 	    os << '\t';
   867 	  }
   868 	  for (int i = 0; i < int(awriters.size()); ++i) {
   869 	    awriters[i].second->write(os, *it);
   870 	    os << '\t';
   871 	  }
   872 	  os << std::endl;
   873 	}
   874       }
   875       {
   876 	os << "&bnodeset ";
   877 	std::vector<Node> items;
   878 	for (typename Graph::BNodeIt it(graph); it != INVALID; ++it) {
   879 	  items.push_back(it);
   880 	}
   881 	if (forceSort) {
   882 	  if (labelMap) {
   883 	    labelMap->sort(items);
   884 	  } else {
   885 	    typedef IdMap<Graph, Node> Map;
   886 	    Map map(graph);
   887 	    _writer_bits::ComposeLess<Map> less(map);
   888 	    std::sort(items.begin(), items.end(), less);
   889 	  }
   890 	}
   891 	if (forceLabelMap) {
   892 	  os << "label\t";
   893 	}
   894 	for (int i = 0; i < int(writers.size()); ++i) {
   895 	  os << writers[i].first << '\t';
   896 	}
   897 	for (int i = 0; i < int(bwriters.size()); ++i) {
   898 	  os << bwriters[i].first << '\t';
   899 	}
   900 	os << std::endl;
   901 	for (typename std::vector<Node>::iterator it = items.begin();
   902 	     it != items.end(); ++it) {
   903 	  if (forceLabelMap) {
   904 	    os << graph.id(*it) << '\t';
   905 	  }
   906 	  for (int i = 0; i < int(writers.size()); ++i) {
   907 	    writers[i].second->write(os, *it);
   908 	    os << '\t';
   909 	  }
   910 	  for (int i = 0; i < int(bwriters.size()); ++i) {
   911 	    bwriters[i].second->write(os, *it);
   912 	    os << '\t';
   913 	  }
   914 	  os << std::endl;
   915 	}
   916       }
   917     }
   918 
   919   public:
   920 
   921     /// \brief Returns true if the nodeset can write the labels of the nodes.
   922     ///
   923     /// Returns true if the nodeset can write the labels of the nodes.
   924     /// It is possible only if a "label" named map was written or the 
   925     /// \c _forceLabelMap constructor parameter was true.
   926     bool isLabelWriter() const {
   927       return labelMap != 0 || forceLabelMap;
   928     }
   929 
   930     /// \brief Write the label of the given node.
   931     ///
   932     /// It writes the label of the given node. If there was written a "label"
   933     /// named map then it will write the map value belongs to the node.
   934     /// Otherwise if the \c forceLabel parameter was true it will write
   935     /// its label in the graph. 
   936     void writeLabel(std::ostream& os, const Node& item) const {
   937       if (forceLabelMap) {
   938 	os << graph.id(item);
   939       } else {
   940 	labelMap->write(os, item);
   941       }
   942     }
   943 
   944     /// \brief Sorts the given node vector by label.
   945     ///
   946     /// Sorts the given node vector by label. If there was written an
   947     /// "label" named map then the vector will be sorted by the values
   948     /// of this map. Otherwise if the \c forceLabel parameter was true
   949     /// it will be sorted by its id in the graph.
   950     void sortByLabel(std::vector<Node>& nodes) const {
   951       if (labelMap) {
   952 	labelMap->sort(nodes);
   953       } else {
   954 	typedef IdMap<Graph, Node> Map;
   955 	Map map(graph);
   956 	_writer_bits::ComposeLess<Map> less(map);
   957 	std::sort(nodes.begin(), nodes.end(), less);
   958       }
   959     }
   960 
   961   private:
   962 
   963     typedef std::vector<std::pair<std::string, _writer_bits::
   964 				  MapWriterBase<Node>*> > MapWriters;
   965     MapWriters awriters, bwriters, writers;
   966     
   967     _writer_bits::MapWriterBase<Node>* labelMap;
   968     bool forceLabelMap;
   969     bool forceSort;
   970    
   971     const Graph& graph;   
   972     std::string name;
   973 
   974   };
   975 
   976   /// \ingroup section_io
   977   /// \brief SectionWriter for writing a graph's edgesets.
   978   ///
   979   /// The lemon format can store multiple graph edgesets with several maps. 
   980   /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but 
   981   /// the \c edgeset_name may be empty.
   982   ///
   983   /// The first line of the section contains the names of the maps separated
   984   /// with white spaces. Each next lines describes a edge in the edgeset. The
   985   /// line contains the source and the target nodes' label and the mapped 
   986   /// values for each map.
   987   ///
   988   /// If the edgeset contains an \c "label" named map then it will be regarded
   989   /// as label map. This map should contain only unique values and when the 
   990   /// \c writeLabel() member will be called with an edge it will write it's 
   991   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   992   /// then the label map will be the id in the graph. In addition if the
   993   /// the \c _forceSort is true then the writer will write the edges
   994   /// sorted by the labels.
   995   ///
   996   /// The edgeset writer needs a node label writer to identify which nodes
   997   /// have to be connected. If a NodeSetWriter can write the nodes' label,
   998   /// it will be able to use with this class.
   999   ///
  1000   /// \relates LemonWriter
  1001   template <typename _Graph, typename _Traits = DefaultWriterTraits>
  1002   class EdgeSetWriter : public LemonWriter::SectionWriter {
  1003     typedef LemonWriter::SectionWriter Parent;
  1004   public:
  1005 
  1006     typedef _Graph Graph;
  1007     typedef _Traits Traits;
  1008     typedef typename Graph::Node Node;
  1009     typedef typename Graph::Edge Edge;
  1010 
  1011     /// \brief Constructor.
  1012     ///
  1013     /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter
  1014     /// and attach it into the given LemonWriter. It will write node
  1015     /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
  1016     /// parameter is true then the writer will write own label map if
  1017     /// the user does not give "label" named map. In addition if the
  1018     /// the \c _forceSort is true then the writer will write the
  1019     /// edges sorted by the labels.
  1020     template <typename NodeLabelWriter>
  1021     EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
  1022 		  const NodeLabelWriter& _nodeLabelWriter, 
  1023 		  const std::string& _name = std::string(),
  1024 		  bool _forceLabelMap = true, bool _forceSort = true)
  1025       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
  1026 	forceSort(_forceSort), graph(_graph), name(_name) {
  1027       checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
  1028       nodeLabelWriter.reset(new _writer_bits::
  1029 			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
  1030     } 
  1031 
  1032     /// \brief Destructor.
  1033     ///
  1034     /// Destructor for EdgeSetWriter.
  1035     virtual ~EdgeSetWriter() {
  1036       typename MapWriters::iterator it;
  1037       for (it = writers.begin(); it != writers.end(); ++it) {
  1038 	delete it->second;
  1039       }
  1040     }
  1041 
  1042   private:
  1043     EdgeSetWriter(const EdgeSetWriter&);
  1044     void operator=(const EdgeSetWriter&);
  1045 
  1046   public:
  1047 
  1048     /// \brief Add a new edge map writer command for the writer.
  1049     ///
  1050     /// Add a new edge map writer command for the writer.
  1051     template <typename Map>
  1052     EdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
  1053       return writeEdgeMap<typename Traits::
  1054 	template Writer<typename Map::Value>, Map>(label, map);
  1055     }
  1056 
  1057     /// \brief Add a new edge map writer command for the writer.
  1058     ///
  1059     /// Add a new edge map writer command for the writer.
  1060     template <typename ItemWriter, typename Map>
  1061     EdgeSetWriter& writeEdgeMap(std::string label, const Map& map, 
  1062 			    const ItemWriter& iw = ItemWriter()) {
  1063       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1064       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
  1065       writers.push_back(
  1066 	make_pair(label, new _writer_bits::
  1067 		  MapWriter<Edge, Map, ItemWriter>(map, iw)));
  1068       return *this;
  1069     }
  1070 
  1071   protected:
  1072 
  1073     /// \brief The header of the section.
  1074     ///
  1075     /// It gives back the header of the section.
  1076     virtual std::string header() {
  1077       return "@edgeset " + name;
  1078     }
  1079 
  1080     /// \brief  Writer function of the section.
  1081     ///
  1082     /// Write the content of the section.
  1083     virtual void write(std::ostream& os) {
  1084       if (!nodeLabelWriter->isLabelWriter()) {
  1085 	throw DataFormatError("Cannot find nodeset or label map");
  1086       }
  1087       for (int i = 0; i < int(writers.size()); ++i) {
  1088 	if (writers[i].first == "label") {
  1089 	  labelMap = writers[i].second;
  1090 	  forceLabelMap = false;
  1091 	  break;
  1092 	}
  1093       }
  1094       std::vector<Edge> items;
  1095       for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
  1096         items.push_back(it);
  1097       }
  1098       if (forceSort) {
  1099         if (labelMap) {
  1100           labelMap->sort(items);
  1101         } else {
  1102           typedef IdMap<Graph, Edge> Map;
  1103           Map map(graph);
  1104           _writer_bits::ComposeLess<Map> less(map);
  1105           std::sort(items.begin(), items.end(), less);
  1106         }
  1107       }
  1108       os << "\t\t";
  1109       if (forceLabelMap) {
  1110 	os << "label\t";
  1111       }
  1112       for (int i = 0; i < int(writers.size()); ++i) {
  1113 	os << writers[i].first << '\t';
  1114       }
  1115       os << std::endl;
  1116       for (typename std::vector<Edge>::iterator it = items.begin();
  1117            it != items.end(); ++it) {
  1118 	nodeLabelWriter->write(os, graph.source(*it));
  1119 	os << '\t';
  1120 	nodeLabelWriter->write(os, graph.target(*it));
  1121 	os << '\t';
  1122 	if (forceLabelMap) {
  1123 	  os << graph.id(*it) << '\t';
  1124 	}
  1125 	for (int i = 0; i < int(writers.size()); ++i) {
  1126 	  writers[i].second->write(os, *it);
  1127 	  os << '\t';
  1128 	}
  1129 	os << std::endl;
  1130       }
  1131     }
  1132 
  1133   public:
  1134 
  1135     /// \brief Returns true if the edgeset can write the labels of the edges.
  1136     ///
  1137     /// Returns true if the edgeset can write the labels of the edges.
  1138     /// It is possible only if a "label" named map was written or the 
  1139     /// \c _forceLabelMap constructor parameter was true.
  1140     bool isLabelWriter() const {
  1141       return forceLabelMap || labelMap != 0;
  1142     }
  1143 
  1144     /// \brief Write the label of the given edge.
  1145     ///
  1146     /// It writes the label of the given edge. If there was written a "label"
  1147     /// named map then it will write the map value belongs to the edge.
  1148     /// Otherwise if the \c forceLabel parameter was true it will write
  1149     /// its label in the graph. 
  1150     void writeLabel(std::ostream& os, const Edge& item) const {
  1151       if (forceLabelMap) {
  1152 	os << graph.id(item);
  1153       } else {
  1154 	labelMap->write(os, item);
  1155       }
  1156     } 
  1157 
  1158     /// \brief Sorts the given edge vector by label.
  1159     ///
  1160     /// Sorts the given edge vector by label. If there was written an
  1161     /// "label" named map then the vector will be sorted by the values
  1162     /// of this map. Otherwise if the \c forceLabel parameter was true
  1163     /// it will be sorted by its id in the graph.
  1164     void sortByLabel(std::vector<Edge>& edges) const {
  1165       if (labelMap) {
  1166 	labelMap->sort(edges);
  1167       } else {
  1168 	typedef IdMap<Graph, Edge> Map;
  1169 	Map map(graph);
  1170 	_writer_bits::ComposeLess<Map> less(map);
  1171 	std::sort(edges.begin(), edges.end(), less);
  1172       }
  1173     }
  1174 
  1175   private:
  1176 
  1177     typedef std::vector<std::pair<std::string, _writer_bits::
  1178 				  MapWriterBase<Edge>*> > MapWriters;
  1179     MapWriters writers;
  1180 
  1181     _writer_bits::MapWriterBase<Edge>* labelMap;
  1182     bool forceLabelMap;
  1183     bool forceSort;
  1184    
  1185     const Graph& graph;   
  1186     std::string name;
  1187 
  1188     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
  1189   };
  1190 
  1191   /// \ingroup section_io
  1192   /// \brief SectionWriter for writing a undirected edgeset.
  1193   ///
  1194   /// The lemon format can store multiple undirected edgesets with several 
  1195   /// maps. The undirected edgeset section's header line is \c \@uedgeset 
  1196   /// \c uedgeset_name, but the \c uedgeset_name may be empty.
  1197   ///
  1198   /// The first line of the section contains the names of the maps separated
  1199   /// with white spaces. Each next lines describes an undirected edge in the 
  1200   /// edgeset. The line contains the two connected nodes' label and the mapped 
  1201   /// values for each undirected map.
  1202   ///
  1203   /// The section can handle the directed as a syntactical sugar. Two
  1204   /// undirected edge map describes one directed edge map. This two maps
  1205   /// are the forward map and the backward map and the names of this map
  1206   /// is near the same just with a prefix \c '+' or \c '-' character 
  1207   /// difference.
  1208   ///
  1209   /// If the edgeset contains an \c "label" named map then it will be
  1210   /// regarded as label map. This map should contain only unique
  1211   /// values and when the \c writeLabel() member will be called with
  1212   /// an undirected edge it will write it's label. Otherwise if the \c
  1213   /// _forceLabelMap constructor parameter is true then the label map
  1214   /// will be the id in the graph.  In addition if the the \c
  1215   /// _forceSort is true then the writer will write the edges sorted
  1216   /// by the labels.
  1217   ///
  1218   /// The undirected edgeset writer needs a node label writer to identify 
  1219   /// which nodes have to be connected. If a NodeSetWriter can write the 
  1220   /// nodes' label, it will be able to use with this class.
  1221   ///
  1222   /// \relates LemonWriter
  1223   template <typename _Graph, typename _Traits = DefaultWriterTraits>
  1224   class UEdgeSetWriter : public LemonWriter::SectionWriter {
  1225     typedef LemonWriter::SectionWriter Parent;
  1226   public:
  1227 
  1228     typedef _Graph Graph;
  1229     typedef _Traits Traits;
  1230     typedef typename Graph::Node Node;
  1231     typedef typename Graph::Edge Edge;
  1232     typedef typename Graph::UEdge UEdge;
  1233 
  1234     /// \brief Constructor.
  1235     ///
  1236     /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
  1237     /// and attach it into the given LemonWriter. It will write node
  1238     /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
  1239     /// parameter is true then the writer will write own label map if
  1240     /// the user does not give "label" named map. In addition if the
  1241     /// the \c _forceSort is true then the writer will write the
  1242     /// edges sorted by the labels.
  1243     template <typename NodeLabelWriter>
  1244     UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
  1245 		       const NodeLabelWriter& _nodeLabelWriter, 
  1246 		       const std::string& _name = std::string(),
  1247 		       bool _forceLabelMap = true, bool _forceSort = true)
  1248       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
  1249 	forceSort(_forceSort), graph(_graph), name(_name) {
  1250       checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
  1251       nodeLabelWriter.reset(new _writer_bits::
  1252 	LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
  1253     } 
  1254 
  1255     /// \brief Destructor.
  1256     ///
  1257     /// Destructor for UEdgeSetWriter.
  1258     virtual ~UEdgeSetWriter() {
  1259       typename MapWriters::iterator it;
  1260       for (it = writers.begin(); it != writers.end(); ++it) {
  1261 	delete it->second;
  1262       }
  1263     }
  1264 
  1265   private:
  1266     UEdgeSetWriter(const UEdgeSetWriter&);
  1267     void operator=(const UEdgeSetWriter&);
  1268 
  1269   public:
  1270 
  1271     /// \brief Add a new undirected edge map writer command for the writer.
  1272     ///
  1273     /// Add a new undirected map writer command for the writer.
  1274     template <typename Map>
  1275     UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map) {
  1276       return writeUEdgeMap<typename Traits::
  1277 	template Writer<typename Map::Value>, Map>(label, map);
  1278     }
  1279 
  1280     /// \brief Add a new undirected map writer command for the writer.
  1281     ///
  1282     /// Add a new undirected map writer command for the writer.
  1283     template <typename ItemWriter, typename Map>
  1284     UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map, 
  1285                                   const ItemWriter& iw = ItemWriter()) {
  1286       checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
  1287       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
  1288       writers.push_back(
  1289 	make_pair(label, new _writer_bits::
  1290 		  UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
  1291       return *this;
  1292     }
  1293 
  1294     /// \brief Add a new directed edge map writer command for the writer.
  1295     ///
  1296     /// Add a new directed map writer command for the writer.
  1297     template <typename Map>
  1298     UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
  1299       return writeEdgeMap<typename Traits::
  1300 	template Writer<typename Map::Value>, Map>(label, map);
  1301     }
  1302 
  1303     /// \brief Add a new directed map writer command for the writer.
  1304     ///
  1305     /// Add a new directed map writer command for the writer.
  1306     template <typename ItemWriter, typename Map>
  1307     UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map, 
  1308                                  const ItemWriter& iw = ItemWriter()) {
  1309       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1310       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
  1311       writeUEdgeMap("+" + label, 
  1312                     _writer_bits::forwardComposeMap(graph, map), iw);
  1313       writeUEdgeMap("-" + label, 
  1314                     _writer_bits::backwardComposeMap(graph, map), iw);
  1315       return *this;
  1316     }
  1317 
  1318   protected:
  1319 
  1320     /// \brief The header of the section.
  1321     ///
  1322     /// It gives back the header of the section.
  1323     virtual std::string header() {
  1324       return "@uedgeset " + name;
  1325     }
  1326 
  1327     /// \brief  Writer function of the section.
  1328     ///
  1329     /// Write the content of the section.
  1330     virtual void write(std::ostream& os) {
  1331       if (!nodeLabelWriter->isLabelWriter()) {
  1332 	throw DataFormatError("Cannot find nodeset or label map");
  1333       }
  1334       for (int i = 0; i < int(writers.size()); ++i) {
  1335 	if (writers[i].first == "label") {
  1336 	  labelMap = writers[i].second;
  1337 	  forceLabelMap = false;
  1338 	  break;
  1339 	}
  1340       }
  1341       std::vector<UEdge> items;
  1342       for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
  1343         items.push_back(it);
  1344       }
  1345       if (forceSort) {
  1346         if (labelMap) {
  1347           labelMap->sort(items);
  1348         } else {
  1349           typedef IdMap<Graph, UEdge> Map;
  1350           Map map(graph);
  1351           _writer_bits::ComposeLess<Map> less(map);
  1352           std::sort(items.begin(), items.end(), less);
  1353         }
  1354       }
  1355       os << "\t\t";
  1356       if (forceLabelMap) {
  1357 	os << "label\t";
  1358       }
  1359       for (int i = 0; i < int(writers.size()); ++i) {
  1360 	os << writers[i].first << '\t';
  1361       }
  1362       os << std::endl;
  1363       for (typename std::vector<UEdge>::iterator it = items.begin();
  1364            it != items.end(); ++it) {
  1365 	nodeLabelWriter->write(os, graph.source(*it));
  1366 	os << '\t';
  1367 	nodeLabelWriter->write(os, graph.target(*it));
  1368 	os << '\t';
  1369 	if (forceLabelMap) {
  1370 	  os << graph.id(*it) << '\t';
  1371 	}
  1372 	for (int i = 0; i < int(writers.size()); ++i) {
  1373 	  writers[i].second->write(os, *it);
  1374 	  os << '\t';
  1375 	}
  1376 	os << std::endl;
  1377       }
  1378     }
  1379 
  1380   public:
  1381 
  1382     /// \brief Returns true if the undirected edgeset can write the labels of 
  1383     /// the edges.
  1384     ///
  1385     /// Returns true if the undirected edgeset can write the labels of the 
  1386     /// undirected edges. It is possible only if a "label" named map was 
  1387     /// written or the \c _forceLabelMap constructor parameter was true.
  1388     bool isLabelWriter() const {
  1389       return forceLabelMap || labelMap != 0;
  1390     }
  1391 
  1392     /// \brief Write the label of the given undirected edge.
  1393     ///
  1394     /// It writes the label of the given undirected edge. If there was written 
  1395     /// a "label" named map then it will write the map value belongs to the 
  1396     /// undirected edge. Otherwise if the \c forceLabel parameter was true it 
  1397     /// will write its id in the graph. 
  1398     void writeLabel(std::ostream& os, const UEdge& item) const {
  1399       if (forceLabelMap) {
  1400 	os << graph.id(item);
  1401       } else {
  1402 	labelMap->write(os, item);
  1403       }
  1404     } 
  1405 
  1406     /// \brief Write the label of the given edge.
  1407     ///
  1408     /// It writes the label of the given edge. If there was written 
  1409     /// a "label" named map then it will write the map value belongs to the 
  1410     /// edge. Otherwise if the \c forceLabel parameter was true it 
  1411     /// will write its id in the graph. If the edge is forward map
  1412     /// then its prefix character is \c '+' elsewhere \c '-'.
  1413     void writeLabel(std::ostream& os, const Edge& item) const {
  1414       if (graph.direction(item)) {
  1415 	os << "+";
  1416       } else {
  1417 	os << "-";
  1418       }
  1419       if (forceLabelMap) {
  1420 	os << graph.id(static_cast<const UEdge&>(item));
  1421       } else {
  1422 	labelMap->write(os, item);
  1423       }
  1424     } 
  1425 
  1426     /// \brief Sorts the given undirected edge vector by label.
  1427     ///
  1428     /// Sorts the given undirected edge vector by label. If there was
  1429     /// written a "label" named map then the vector will be sorted by
  1430     /// the values of this map. Otherwise if the \c forceLabel
  1431     /// parameter was true it will be sorted by its id in the graph.
  1432     void sortByLabel(std::vector<UEdge>& uedges) const {
  1433       if (labelMap) {
  1434 	labelMap->sort(uedges);
  1435       } else {
  1436 	typedef IdMap<Graph, UEdge> Map;
  1437 	Map map(graph);
  1438 	_writer_bits::ComposeLess<Map> less(map);
  1439 	std::sort(uedges.begin(), uedges.end(), less);
  1440       }
  1441     }
  1442 
  1443     /// \brief Sorts the given edge vector by label.
  1444     ///
  1445     /// Sorts the given edge vector by label. If there was written a
  1446     /// "label" named map then the vector will be sorted by the values
  1447     /// of this map. Otherwise if the \c forceLabel parameter was true
  1448     /// it will be sorted by its id in the graph.
  1449     void sortByLabel(std::vector<Edge>& edges) const {
  1450       if (labelMap) {
  1451 	labelMap->sort(graph, edges);
  1452       } else {
  1453 	typedef IdMap<Graph, Edge> Map;
  1454 	Map map(graph);
  1455 	_writer_bits::ComposeLess<Map> less(map);
  1456 	std::sort(edges.begin(), edges.end(), less);
  1457       }
  1458     }
  1459 
  1460   private:
  1461 
  1462     typedef std::vector<std::pair<std::string, _writer_bits::
  1463 				  UEdgeMapWriterBase<Graph>*> > MapWriters;
  1464     MapWriters writers;
  1465 
  1466     _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
  1467     bool forceLabelMap;
  1468     bool forceSort;
  1469    
  1470     const Graph& graph;   
  1471     std::string name;
  1472 
  1473     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
  1474   };
  1475 
  1476   /// \ingroup section_io
  1477   /// \brief SectionWriter for writing named nodes.
  1478   ///
  1479   /// The nodes section's header line is \c \@nodes \c nodes_name, but the
  1480   /// \c nodes_name may be empty.
  1481   ///
  1482   /// Each line in the section contains the name of the node and 
  1483   /// then the node label. 
  1484   ///
  1485   /// \relates LemonWriter
  1486   template <typename _Graph>
  1487   class NodeWriter : public LemonWriter::SectionWriter {
  1488     typedef LemonWriter::SectionWriter Parent;
  1489     typedef _Graph Graph;
  1490     typedef typename Graph::Node Node;
  1491   public:
  1492     
  1493     /// \brief Constructor.
  1494     ///
  1495     /// Constructor for NodeWriter. It creates the NodeWriter and
  1496     /// attach it into the given LemonWriter. The given \c _LabelWriter
  1497     /// will write the nodes' label what can be a nodeset writer.
  1498     template <typename _LabelWriter>
  1499     NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
  1500 	       const std::string& _name = std::string()) 
  1501       : Parent(_writer), name(_name) {
  1502       checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
  1503       labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
  1504                         (_labelWriter));
  1505     }
  1506 
  1507 
  1508     /// \brief Destructor.
  1509     ///
  1510     /// Destructor for NodeWriter.
  1511     virtual ~NodeWriter() {}
  1512 
  1513   private:
  1514     NodeWriter(const NodeWriter&);
  1515     void operator=(const NodeWriter&);
  1516 
  1517   public:
  1518 
  1519     /// \brief Add a node writer command for the NodeWriter.
  1520     ///
  1521     /// Add a node writer command for the NodeWriter.
  1522     void writeNode(std::string label, const Node& item) {
  1523       writers.push_back(make_pair(label, &item));
  1524     }
  1525 
  1526   protected:
  1527 
  1528     /// \brief The header of the section.
  1529     ///
  1530     /// It gives back the header of the section.
  1531     virtual std::string header() {
  1532       return "@nodes " + name;
  1533     }
  1534 
  1535     /// \brief  Writer function of the section.
  1536     ///
  1537     /// Write the content of the section.
  1538     virtual void write(std::ostream& os) {
  1539       if (!labelWriter->isLabelWriter()) {
  1540 	throw DataFormatError("Cannot find nodeset or label map");
  1541       }
  1542       for (int i = 0; i < int(writers.size()); ++i) {
  1543 	os << writers[i].first << ' ';
  1544 	labelWriter->write(os, *(writers[i].second));
  1545 	os << std::endl;
  1546       }
  1547     }
  1548 
  1549     /// \brief Gives back true when the section should be written.
  1550     ///
  1551     /// Gives back true when the section should be written.
  1552     virtual bool valid() { return !writers.empty(); }
  1553     
  1554   private:
  1555 
  1556     std::string name;
  1557 
  1558     typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
  1559     NodeWriters writers;
  1560     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
  1561   };
  1562 
  1563   /// \ingroup section_io
  1564   /// \brief SectionWriter for writing named edges.
  1565   ///
  1566   /// The edges section's header line is \c \@edges \c edges_name, but the
  1567   /// \c edges_name may be empty.
  1568   ///
  1569   /// Each line in the section contains the name of the edge and 
  1570   /// then the edge label. 
  1571   ///
  1572   /// \relates LemonWriter
  1573   template <typename _Graph>
  1574   class EdgeWriter : public LemonWriter::SectionWriter {
  1575     typedef LemonWriter::SectionWriter Parent;
  1576     typedef _Graph Graph;
  1577     typedef typename Graph::Edge Edge;
  1578   public:
  1579     
  1580     /// \brief Constructor.
  1581     ///
  1582     /// Constructor for EdgeWriter. It creates the EdgeWriter and
  1583     /// attach it into the given LemonWriter. The given \c _LabelWriter
  1584     /// will write the edges' label what can be a edgeset writer.
  1585     template <typename _LabelWriter>
  1586     EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
  1587 	       const std::string& _name = std::string()) 
  1588       : Parent(_writer), name(_name) {
  1589       checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
  1590       labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
  1591     }
  1592 
  1593     /// \brief Destructor.
  1594     ///
  1595     /// Destructor for EdgeWriter.
  1596     virtual ~EdgeWriter() {}
  1597   private:
  1598     EdgeWriter(const EdgeWriter&);
  1599     void operator=(const EdgeWriter&);
  1600 
  1601   public:
  1602 
  1603     /// \brief Add an edge writer command for the EdgeWriter.
  1604     ///
  1605     /// Add an edge writer command for the EdgeWriter.
  1606     void writeEdge(std::string label, const Edge& item) {
  1607       writers.push_back(make_pair(label, &item));
  1608     }
  1609 
  1610   protected:
  1611 
  1612     /// \brief The header of the section.
  1613     ///
  1614     /// It gives back the header of the section.
  1615     virtual std::string header() {
  1616       return "@edges " + name;
  1617     }
  1618 
  1619     /// \brief  Writer function of the section.
  1620     ///
  1621     /// Write the content of the section.
  1622     virtual void write(std::ostream& os) {
  1623       if (!labelWriter->isLabelWriter()) {
  1624 	throw DataFormatError("Cannot find edgeset or label map");
  1625       }
  1626       for (int i = 0; i < int(writers.size()); ++i) {
  1627 	os << writers[i].first << ' ';
  1628 	labelWriter->write(os, *(writers[i].second));
  1629 	os << std::endl;
  1630       }
  1631     }
  1632 
  1633     /// \brief Gives back true when the section should be written.
  1634     ///
  1635     /// Gives back true when the section should be written.
  1636     virtual bool valid() { return !writers.empty(); }
  1637     
  1638   private:
  1639 
  1640     std::string name;
  1641 
  1642     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
  1643     EdgeWriters writers;
  1644 
  1645     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
  1646   };
  1647 
  1648 
  1649   /// \ingroup section_io
  1650   /// \brief SectionWriter for writing named undirected edges.
  1651   ///
  1652   /// The undirected edges section's header line is \c \@uedges 
  1653   /// \c uedges_name, but the \c uedges_name may be empty.
  1654   ///
  1655   /// Each line in the section contains the name of the undirected edge and 
  1656   /// then the undirected edge label. 
  1657   ///
  1658   /// \relates LemonWriter
  1659   template <typename _Graph>
  1660   class UEdgeWriter : public LemonWriter::SectionWriter {
  1661     typedef LemonWriter::SectionWriter Parent;
  1662     typedef _Graph Graph;
  1663     typedef typename Graph::Node Node;
  1664     typedef typename Graph::Edge Edge;
  1665     typedef typename Graph::UEdge UEdge;
  1666   public:
  1667     
  1668     /// \brief Constructor.
  1669     ///
  1670     /// Constructor for UEdgeWriter. It creates the UEdgeWriter and
  1671     /// attach it into the given LemonWriter. The given \c _LabelWriter
  1672     /// will write the undirected edges' label what can be an undirected 
  1673     /// edgeset writer.
  1674     template <typename _LabelWriter>
  1675     UEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
  1676 	       const std::string& _name = std::string()) 
  1677       : Parent(_writer), name(_name) {
  1678       checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
  1679       checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
  1680       uEdgeLabelWriter.reset(new _writer_bits::
  1681 			      LabelWriter<UEdge, _LabelWriter>(_labelWriter));
  1682       edgeLabelWriter.reset(new _writer_bits::
  1683 			 LabelWriter<Edge, _LabelWriter>(_labelWriter));
  1684     }
  1685 
  1686     /// \brief Destructor.
  1687     ///
  1688     /// Destructor for UEdgeWriter.
  1689     virtual ~UEdgeWriter() {}
  1690   private:
  1691     UEdgeWriter(const UEdgeWriter&);
  1692     void operator=(const UEdgeWriter&);
  1693 
  1694   public:
  1695 
  1696     /// \brief Add an edge writer command for the UEdgeWriter.
  1697     ///
  1698     /// Add an edge writer command for the UEdgeWriter.
  1699     void writeEdge(std::string label, const Edge& item) {
  1700       edgeWriters.push_back(make_pair(label, &item));
  1701     }
  1702 
  1703     /// \brief Add an undirected edge writer command for the UEdgeWriter.
  1704     ///
  1705     /// Add an undirected edge writer command for the UEdgeWriter.
  1706     void writeUEdge(std::string label, const UEdge& item) {
  1707       uEdgeWriters.push_back(make_pair(label, &item));
  1708     }
  1709 
  1710   protected:
  1711 
  1712     /// \brief The header of the section.
  1713     ///
  1714     /// It gives back the header of the section.
  1715     virtual std::string header() {
  1716       return "@uedges " + name;
  1717     }
  1718 
  1719     /// \brief  Writer function of the section.
  1720     ///
  1721     /// Write the content of the section.
  1722     virtual void write(std::ostream& os) {
  1723       if (!edgeLabelWriter->isLabelWriter()) {
  1724 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1725       }
  1726       if (!uEdgeLabelWriter->isLabelWriter()) {
  1727 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1728       }
  1729       for (int i = 0; i < int(uEdgeWriters.size()); ++i) {
  1730 	os << uEdgeWriters[i].first << ' ';
  1731 	uEdgeLabelWriter->write(os, *(uEdgeWriters[i].second));
  1732 	os << std::endl;
  1733       }
  1734       for (int i = 0; i < int(edgeWriters.size()); ++i) {
  1735 	os << edgeWriters[i].first << ' ';
  1736 	edgeLabelWriter->write(os, *(edgeWriters[i].second));
  1737 	os << std::endl;
  1738       }
  1739     }
  1740 
  1741     /// \brief Gives back true when the section should be written.
  1742     ///
  1743     /// Gives back true when the section should be written.
  1744     virtual bool valid() { 
  1745       return !uEdgeWriters.empty() || !edgeWriters.empty(); 
  1746     }
  1747     
  1748   private:
  1749 
  1750     std::string name;
  1751 
  1752     typedef std::vector<std::pair<std::string, 
  1753 				  const UEdge*> > UEdgeWriters;
  1754     UEdgeWriters uEdgeWriters;
  1755     std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > uEdgeLabelWriter;
  1756 
  1757     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
  1758     EdgeWriters edgeWriters;
  1759     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
  1760 
  1761   };
  1762 
  1763   /// \ingroup section_io
  1764   /// \brief SectionWriter for writing extra node maps.
  1765   ///
  1766   /// The lemon format can store maps in the nodeset. This class let
  1767   /// you make distinict section to store maps. The main purpose of
  1768   /// this class is a logical separation of some maps. The other
  1769   /// useful application could be to store paths in node maps.
  1770   ///
  1771   /// The first line of the section contains the names of the maps
  1772   /// separated with white spaces. Each next line describes an item
  1773   /// in the itemset, and contains in the first column the label of
  1774   /// the item and then the mapped values for each map.
  1775   ///
  1776   /// \relates LemonWriter
  1777   template <typename _Graph, typename _Traits = DefaultWriterTraits>
  1778   class NodeMapWriter : public LemonWriter::SectionWriter {
  1779     typedef LemonWriter::SectionWriter Parent;
  1780   public:
  1781 
  1782     typedef _Graph Graph;
  1783     typedef _Traits Traits;
  1784     typedef typename Graph::Node Node;
  1785 
  1786     /// \brief Constructor.
  1787     ///
  1788     /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
  1789     /// attach it into the given LemonWriter. If the the
  1790     /// \c _forceSort is true then the writer will write the edges
  1791     /// sorted by the labels.
  1792     template <typename _LabelWriter>
  1793     NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
  1794 		 const _LabelWriter& _labelWriter,
  1795 		 const std::string& _name = std::string(),
  1796 		 bool _forceSort = true) 
  1797       : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
  1798       checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
  1799       labelWriter.reset(new _writer_bits::LabelWriter<Node, 
  1800 			_LabelWriter>(_labelWriter));
  1801     }
  1802 
  1803     /// \brief Destructor.
  1804     ///
  1805     /// Destructor for NodeMapWriter.
  1806     virtual ~NodeMapWriter() {
  1807       typename MapWriters::iterator it;
  1808       for (it = writers.begin(); it != writers.end(); ++it) {
  1809 	delete it->second;
  1810       }
  1811     }
  1812 
  1813   private:
  1814     NodeMapWriter(const NodeMapWriter&);
  1815     void operator=(const NodeMapWriter&);
  1816   
  1817   public:
  1818 
  1819     /// \brief Add a new node map writer command for the writer.
  1820     ///
  1821     /// Add a new node map writer command for the writer.
  1822     template <typename Map>
  1823     NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
  1824       return writeNodeMap<typename Traits::
  1825 	template Writer<typename Map::Value>, Map>(label, map);
  1826     }
  1827 
  1828     /// \brief Add a new node map writer command for the writer.
  1829     ///
  1830     /// Add a new node map writer command for the writer.
  1831     template <typename ItemWriter, typename Map>
  1832     NodeMapWriter& writeNodeMap(std::string label, const Map& map, 
  1833 			   const ItemWriter& iw = ItemWriter()) {
  1834       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
  1835       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
  1836       writers.push_back(
  1837 	make_pair(label, new _writer_bits::
  1838 		  MapWriter<Node, Map, ItemWriter>(map, iw)));
  1839       return *this;
  1840     }
  1841 
  1842   protected:
  1843 
  1844     /// \brief The header of the section.
  1845     ///
  1846     /// It gives back the header of the section.
  1847     virtual std::string header() {
  1848       return "@nodemaps " + name;
  1849     }
  1850 
  1851     /// \brief  Writer function of the section.
  1852     ///
  1853     /// Write the content of the section.
  1854     virtual void write(std::ostream& os) {
  1855       std::vector<Node> nodes;
  1856       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
  1857         nodes.push_back(it);
  1858       }
  1859       if (forceSort) {
  1860 	labelWriter->sort(nodes);
  1861       }
  1862       os << '\t';
  1863       for (int i = 0; i < int(writers.size()); ++i) {
  1864 	os << writers[i].first << '\t';
  1865       }
  1866       os << std::endl;
  1867       for (typename std::vector<Node>::iterator it = nodes.begin();
  1868            it != nodes.end(); ++it) {
  1869 
  1870 	labelWriter->write(os, *it); os << '\t';
  1871 	for (int i = 0; i < int(writers.size()); ++i) {
  1872 	  writers[i].second->write(os, *it);
  1873 	  os << '\t';
  1874 	}
  1875 	os << std::endl;
  1876       }
  1877     }
  1878 
  1879 
  1880   private:
  1881 
  1882     typedef std::vector<std::pair<std::string, _writer_bits::
  1883 				  MapWriterBase<Node>*> > MapWriters;
  1884     MapWriters writers;
  1885 
  1886     _writer_bits::MapWriterBase<Node>* labelMap;
  1887 
  1888     const Graph& graph;   
  1889     std::string name;
  1890     bool forceSort;
  1891 
  1892     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
  1893   };
  1894 
  1895   /// \ingroup section_io
  1896   /// \brief SectionWriter for writing extra edge maps.
  1897   ///
  1898   /// The lemon format can store maps in the edgeset. This class let
  1899   /// you make distinict section to store maps. The main purpose of
  1900   /// this class is a logical separation of some maps. The other
  1901   /// useful application could be to store paths in edge maps.
  1902   ///
  1903   /// The first line of the section contains the names of the maps
  1904   /// separated with white spaces. Each next line describes an item
  1905   /// in the itemset, and contains in the first column the label of
  1906   /// the item and then the mapped values for each map.
  1907   ///
  1908   /// \relates LemonWriter
  1909   template <typename _Graph, typename _Traits = DefaultWriterTraits>
  1910   class EdgeMapWriter : public LemonWriter::SectionWriter {
  1911     typedef LemonWriter::SectionWriter Parent;
  1912   public:
  1913 
  1914     typedef _Graph Graph;
  1915     typedef _Traits Traits;
  1916     typedef typename Graph::Edge Edge;
  1917 
  1918     /// \brief Constructor.
  1919     ///
  1920     /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
  1921     /// attach it into the given LemonWriter. If the the
  1922     /// \c _forceSort is true then the writer will write the edges
  1923     /// sorted by the labels.
  1924     template <typename _LabelWriter>
  1925     EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
  1926 		 const _LabelWriter& _labelWriter,
  1927 		 const std::string& _name = std::string(),
  1928 		 bool _forceSort = true) 
  1929       : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
  1930       checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
  1931       labelWriter.reset(new _writer_bits::LabelWriter<Edge, 
  1932 			_LabelWriter>(_labelWriter));
  1933     }
  1934 
  1935     /// \brief Destructor.
  1936     ///
  1937     /// Destructor for EdgeMapWriter.
  1938     virtual ~EdgeMapWriter() {
  1939       typename MapWriters::iterator it;
  1940       for (it = writers.begin(); it != writers.end(); ++it) {
  1941 	delete it->second;
  1942       }
  1943     }
  1944 
  1945   private:
  1946     EdgeMapWriter(const EdgeMapWriter&);
  1947     void operator=(const EdgeMapWriter&);
  1948   
  1949   public:
  1950 
  1951     /// \brief Add a new edge map writer command for the writer.
  1952     ///
  1953     /// Add a new edge map writer command for the writer.
  1954     template <typename Map>
  1955     EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
  1956       return writeEdgeMap<typename Traits::
  1957 	template Writer<typename Map::Value>, Map>(label, map);
  1958     }
  1959 
  1960     /// \brief Add a new edge map writer command for the writer.
  1961     ///
  1962     /// Add a new edge map writer command for the writer.
  1963     template <typename ItemWriter, typename Map>
  1964     EdgeMapWriter& writeEdgeMap(std::string label, const Map& map, 
  1965 				const ItemWriter& iw = ItemWriter()) {
  1966       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1967       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
  1968       writers.push_back(
  1969 	make_pair(label, new _writer_bits::
  1970 		  MapWriter<Edge, Map, ItemWriter>(map, iw)));
  1971       return *this;
  1972     }
  1973 
  1974   protected:
  1975 
  1976     /// \brief The header of the section.
  1977     ///
  1978     /// It gives back the header of the section.
  1979     virtual std::string header() {
  1980       return "@edgemaps " + name;
  1981     }
  1982 
  1983     /// \brief  Writer function of the section.
  1984     ///
  1985     /// Write the content of the section.
  1986     virtual void write(std::ostream& os) {
  1987       std::vector<Edge> edges;
  1988       for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
  1989         edges.push_back(it);
  1990       }
  1991       if (forceSort) {
  1992 	labelWriter->sort(edges);
  1993       }
  1994       os << '\t';
  1995       for (int i = 0; i < int(writers.size()); ++i) {
  1996 	os << writers[i].first << '\t';
  1997       }
  1998       os << std::endl;
  1999       for (typename std::vector<Edge>::iterator it = edges.begin();
  2000            it != edges.end(); ++it) {
  2001 
  2002 	labelWriter->write(os, *it); os << '\t';
  2003 	for (int i = 0; i < int(writers.size()); ++i) {
  2004 	  writers[i].second->write(os, *it);
  2005 	  os << '\t';
  2006 	}
  2007 	os << std::endl;
  2008       }
  2009     }
  2010 
  2011 
  2012   private:
  2013 
  2014     typedef std::vector<std::pair<std::string, _writer_bits::
  2015 				  MapWriterBase<Edge>*> > MapWriters;
  2016     MapWriters writers;
  2017 
  2018     _writer_bits::MapWriterBase<Edge>* labelMap;
  2019 
  2020     const Graph& graph;   
  2021     std::string name;
  2022     bool forceSort;
  2023 
  2024     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
  2025   };
  2026 
  2027   /// \ingroup section_io
  2028   /// \brief SectionWriter for writing extra undirected edge maps.
  2029   ///
  2030   /// The lemon format can store maps in the uedgeset. This class let
  2031   /// you make distinict section to store maps. The main purpose of
  2032   /// this class is a logical separation of some maps. The other
  2033   /// useful application could be to store paths in undirected edge
  2034   /// maps.
  2035   ///
  2036   /// The first line of the section contains the names of the maps
  2037   /// separated with white spaces. Each next line describes an item
  2038   /// in the itemset, and contains in the first column the label of
  2039   /// the item and then the mapped values for each map.
  2040   ///
  2041   /// \relates LemonWriter
  2042   template <typename _Graph, typename _Traits = DefaultWriterTraits>
  2043   class UEdgeMapWriter : public LemonWriter::SectionWriter {
  2044     typedef LemonWriter::SectionWriter Parent;
  2045   public:
  2046 
  2047     typedef _Graph Graph;
  2048     typedef _Traits Traits;
  2049     typedef typename Graph::UEdge UEdge;
  2050     typedef typename Graph::Edge Edge;
  2051 
  2052     /// \brief Constructor.
  2053     ///
  2054     /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
  2055     /// attach it into the given LemonWriter. If the the
  2056     /// \c _forceSort is true then the writer will write the uedges
  2057     /// sorted by the labels.
  2058     template <typename _LabelWriter>
  2059     UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
  2060 		 const _LabelWriter& _labelWriter,
  2061 		 const std::string& _name = std::string(),
  2062 		 bool _forceSort = true) 
  2063       : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
  2064       checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
  2065       labelWriter.reset(new _writer_bits::LabelWriter<UEdge, 
  2066 			    _LabelWriter>(_labelWriter));
  2067     }
  2068 
  2069     /// \brief Destructor.
  2070     ///
  2071     /// Destructor for UEdgeMapWriter.
  2072     virtual ~UEdgeMapWriter() {
  2073       typename MapWriters::iterator it;
  2074       for (it = writers.begin(); it != writers.end(); ++it) {
  2075 	delete it->second;
  2076       }
  2077     }
  2078 
  2079   private:
  2080     UEdgeMapWriter(const UEdgeMapWriter&);
  2081     void operator=(const UEdgeMapWriter&);
  2082   
  2083   public:
  2084 
  2085     /// \brief Add a new undirected edge map writer command for the writer.
  2086     ///
  2087     /// Add a new undirected edge map writer command for the writer.
  2088     template <typename Map>
  2089     UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
  2090       return writeUEdgeMap<typename Traits::
  2091 	template Writer<typename Map::Value>, Map>(label, map);
  2092     }
  2093 
  2094     /// \brief Add a new undirected edge map writer command for the writer.
  2095     ///
  2096     /// Add a new undirected edge map writer command for the writer.
  2097     template <typename ItemWriter, typename Map>
  2098     UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map, 
  2099 			   const ItemWriter& iw = ItemWriter()) {
  2100       checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
  2101       checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
  2102       writers.push_back(
  2103 	make_pair(label, new _writer_bits::
  2104 		  MapWriter<UEdge, Map, ItemWriter>(map, iw)));
  2105       return *this;
  2106     }
  2107 
  2108     /// \brief Add a new directed edge map writer command for the writer.
  2109     ///
  2110     /// Add a new directed map writer command for the writer.
  2111     template <typename Map>
  2112     UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
  2113       return writeEdgeMap<typename Traits::
  2114 	template Writer<typename Map::Value>, Map>(label, map);
  2115     }
  2116 
  2117     /// \brief Add a new directed map writer command for the writer.
  2118     ///
  2119     /// Add a new directed map writer command for the writer.
  2120     template <typename ItemWriter, typename Map>
  2121     UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map, 
  2122                                  const ItemWriter& iw = ItemWriter()) {
  2123       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  2124       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
  2125       writeUEdgeMap("+" + label, 
  2126                     _writer_bits::forwardComposeMap(graph, map), iw);
  2127       writeUEdgeMap("-" + label, 
  2128                     _writer_bits::backwardComposeMap(graph, map), iw);
  2129       return *this;
  2130     }
  2131 
  2132   protected:
  2133 
  2134     /// \brief The header of the section.
  2135     ///
  2136     /// It gives back the header of the section.
  2137     virtual std::string header() {
  2138       return "@uedgemaps " + name;
  2139     }
  2140 
  2141     /// \brief  Writer function of the section.
  2142     ///
  2143     /// Write the content of the section.
  2144     virtual void write(std::ostream& os) {
  2145       std::vector<UEdge> uedges;
  2146       for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
  2147         uedges.push_back(it);
  2148       }
  2149       if (forceSort) {
  2150 	labelWriter->sort(uedges);
  2151       }
  2152       os << '\t';
  2153       for (int i = 0; i < int(writers.size()); ++i) {
  2154 	os << writers[i].first << '\t';
  2155       }
  2156       os << std::endl;
  2157       for (typename std::vector<UEdge>::iterator it = uedges.begin();
  2158            it != uedges.end(); ++it) {
  2159 
  2160 	labelWriter->write(os, *it); os << '\t';
  2161 	for (int i = 0; i < int(writers.size()); ++i) {
  2162 	  writers[i].second->write(os, *it);
  2163 	  os << '\t';
  2164 	}
  2165 	os << std::endl;
  2166       }
  2167     }
  2168 
  2169 
  2170   private:
  2171 
  2172     typedef std::vector<std::pair<std::string, _writer_bits::
  2173 				  MapWriterBase<UEdge>*> > MapWriters;
  2174     MapWriters writers;
  2175 
  2176     _writer_bits::MapWriterBase<UEdge>* labelMap;
  2177 
  2178     const Graph& graph;   
  2179     std::string name;
  2180     bool forceSort;
  2181 
  2182     std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
  2183   };
  2184 
  2185 
  2186   /// \ingroup section_io
  2187   /// \brief SectionWriter for attributes.
  2188   ///
  2189   /// The lemon format can store multiple attribute set. Each set has
  2190   /// the header line \c \@attributes \c attributes_name, but the 
  2191   /// attributeset_name may be empty.
  2192   ///
  2193   /// The attributeset section contains several lines. Each of them starts
  2194   /// with the name of attribute and then the value.
  2195   ///
  2196   /// \relates LemonWriter
  2197   template <typename _Traits = DefaultWriterTraits>
  2198   class AttributeWriter : public LemonWriter::SectionWriter {
  2199     typedef LemonWriter::SectionWriter Parent;
  2200     typedef _Traits Traits; 
  2201   public:
  2202     /// \brief Constructor.
  2203     ///
  2204     /// Constructor for AttributeWriter. It creates the AttributeWriter and
  2205     /// attach it into the given LemonWriter.
  2206     AttributeWriter(LemonWriter& _writer, 
  2207 		    const std::string& _name = std::string()) 
  2208       : Parent(_writer), name(_name) {}
  2209 
  2210     /// \brief Destructor.
  2211     ///
  2212     /// Destructor for AttributeWriter.
  2213     virtual ~AttributeWriter() {
  2214       typename Writers::iterator it;
  2215       for (it = writers.begin(); it != writers.end(); ++it) {
  2216 	delete it->second;
  2217       }
  2218     }
  2219 
  2220   private:
  2221     AttributeWriter(const AttributeWriter&);
  2222     void operator=(AttributeWriter&);
  2223 
  2224   public:
  2225     /// \brief Add an attribute writer command for the writer.
  2226     ///
  2227     /// Add an attribute writer command for the writer.
  2228     template <typename Value>
  2229     AttributeWriter& writeAttribute(std::string label, 
  2230 				    const Value& value) {
  2231       return 
  2232 	writeAttribute<typename Traits::template Writer<Value> >(label, value);
  2233     }
  2234 
  2235     /// \brief Add an attribute writer command for the writer.
  2236     ///
  2237     /// Add an attribute writer command for the writer.
  2238     template <typename ItemWriter, typename Value>
  2239     AttributeWriter& writeAttribute(std::string label, const Value& value,
  2240 				    const ItemWriter& iw = ItemWriter()) {
  2241       checkConcept<_writer_bits::ItemWriter<Value>, ItemWriter>();
  2242       writers.push_back(make_pair(label, new _writer_bits::
  2243 				  ValueWriter<Value, ItemWriter>(value, iw)));
  2244       return *this;
  2245     }
  2246 
  2247   protected:
  2248 
  2249     /// \brief The header of section.
  2250     ///
  2251     /// It gives back the header of the section.
  2252     std::string header() {
  2253       return "@attributes " + name;
  2254     }
  2255 
  2256     /// \brief  Writer function of the section.
  2257     ///
  2258     /// Write the content of the section.
  2259     void write(std::ostream& os) {
  2260       typename Writers::iterator it;
  2261       for (it = writers.begin(); it != writers.end(); ++it) {
  2262 	os << it->first << ' ';
  2263 	it->second->write(os);
  2264 	os << std::endl;
  2265       }
  2266     }    
  2267 
  2268     /// \brief Gives back true when the section should be written.
  2269     ///
  2270     /// Gives back true when the section should be written.
  2271     virtual bool valid() { return !writers.empty(); }
  2272 
  2273   private:
  2274     std::string name;
  2275 
  2276     typedef std::vector<std::pair<std::string, 
  2277 				  _writer_bits::ValueWriterBase*> > Writers;
  2278     Writers writers;  
  2279   };
  2280 
  2281 
  2282 }
  2283 #endif