lemon/lemon_writer.h
changeset 1903 f3d24016dad5
parent 1875 98698b69a902
child 1909 2d806130e700
equal deleted inserted replaced
8:2a332d65368e 9:f56ab4dfc450
    44 namespace lemon {
    44 namespace lemon {
    45 
    45 
    46   namespace _writer_bits {
    46   namespace _writer_bits {
    47     
    47     
    48     template <typename Item>
    48     template <typename Item>
    49     class ItemIdWriter {
    49     class ItemLabelWriter {
    50     public:
    50     public:
    51 
    51 
    52       bool isIdWriter() { return true; }
    52       bool isLabelWriter() { return true; }
    53 
    53 
    54       void writeId(std::ostream&, const Item&) {}
    54       void writeLabel(std::ostream&, const Item&) {}
    55       
    55       
    56       template <class _ItemIdWriter>
    56       template <class _ItemLabelWriter>
    57       struct Constraints {
    57       struct Constraints {
    58 	void constraints() {
    58 	void constraints() {
    59 	  bool b = writer.isIdWriter();
    59 	  bool b = writer.isLabelWriter();
    60 	  ignore_unused_variable_warning(b);
    60 	  ignore_unused_variable_warning(b);
    61 	  writer.writeId(os, item);
    61 	  writer.writeLabel(os, item);
    62 	}
    62 	}
    63 	_ItemIdWriter& writer;
    63 	_ItemLabelWriter& writer;
    64 	std::ostream& os;
    64 	std::ostream& os;
    65 	const Item& item;
    65 	const Item& item;
    66       };
    66       };
    67 
    67 
    68     };
    68     };
   223       Writer writer;
   223       Writer writer;
   224     };
   224     };
   225     
   225     
   226 
   226 
   227     template <typename _Item>
   227     template <typename _Item>
   228     class IdWriterBase {
   228     class LabelWriterBase {
   229     public:
   229     public:
   230       typedef _Item Item;
   230       typedef _Item Item;
   231       virtual ~IdWriterBase() {}
   231       virtual ~LabelWriterBase() {}
   232       virtual void write(std::ostream&, const Item&) const = 0;
   232       virtual void write(std::ostream&, const Item&) const = 0;
   233       virtual bool isIdWriter() const = 0;
   233       virtual bool isLabelWriter() const = 0;
   234     };
   234     };
   235 
   235 
   236     template <typename _Item, typename _BoxedIdWriter>
   236     template <typename _Item, typename _BoxedLabelWriter>
   237     class IdWriter : public IdWriterBase<_Item> {
   237     class LabelWriter : public LabelWriterBase<_Item> {
   238     public:
   238     public:
   239       typedef _Item Item;
   239       typedef _Item Item;
   240       typedef _BoxedIdWriter BoxedIdWriter;
   240       typedef _BoxedLabelWriter BoxedLabelWriter;
   241 
   241 
   242       const BoxedIdWriter& idWriter;
   242       const BoxedLabelWriter& labelWriter;
   243 
   243 
   244       IdWriter(const BoxedIdWriter& _idWriter) 
   244       LabelWriter(const BoxedLabelWriter& _labelWriter) 
   245 	: idWriter(_idWriter) {}
   245 	: labelWriter(_labelWriter) {}
   246 
   246 
   247       virtual void write(std::ostream& os, const Item& item) const {
   247       virtual void write(std::ostream& os, const Item& item) const {
   248 	idWriter.writeId(os, item);
   248 	labelWriter.writeLabel(os, item);
   249       }
   249       }
   250 
   250 
   251       virtual bool isIdWriter() const {
   251       virtual bool isLabelWriter() const {
   252 	return idWriter.isIdWriter();
   252 	return labelWriter.isLabelWriter();
   253       }
   253       }
   254     };
   254     };
   255 
   255 
   256   }
   256   }
   257 
   257 
   372 
   372 
   373   /// \ingroup io_group
   373   /// \ingroup io_group
   374   /// \brief SectionWriter for writing a graph's nodeset.
   374   /// \brief SectionWriter for writing a graph's nodeset.
   375   ///
   375   ///
   376   /// The lemon format can store multiple graph nodesets with several maps.
   376   /// The lemon format can store multiple graph nodesets with several maps.
   377   /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
   377   /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but 
   378   /// \c nodeset_id may be empty.
   378   /// the \c nodeset_name may be empty.
   379   ///
   379   ///
   380   /// The first line of the section contains the names of the maps separated
   380   /// The first line of the section contains the names of the maps separated
   381   /// with white spaces. Each next lines describes a node in the nodeset, and
   381   /// with white spaces. Each next lines describes a node in the nodeset, and
   382   /// contains the mapped values for each map.
   382   /// contains the mapped values for each map.
   383   ///
   383   ///
   384   /// If the nodeset contains an \c "id" named map then it will be regarded
   384   /// If the nodeset contains an \c "label" named map then it will be regarded
   385   /// as id map. This map should contain only unique values and when the 
   385   /// as label map. This map should contain only unique values and when the 
   386   /// \c writeId() member will be called with a node it will write it's id.
   386   /// \c writeLabel() member will be called with a node it will write it's 
   387   /// Otherwise if the \c _forceIdMap constructor parameter is true then
   387   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   388   /// the id map will be the id in the graph.
   388   /// then the label map will be the id in the graph.
   389   ///
   389   ///
   390   /// \relates LemonWriter
   390   /// \relates LemonWriter
   391   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   391   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   392   class NodeSetWriter : public LemonWriter::SectionWriter {
   392   class NodeSetWriter : public LemonWriter::SectionWriter {
   393     typedef LemonWriter::SectionWriter Parent;
   393     typedef LemonWriter::SectionWriter Parent;
   398     typedef typename Graph::Node Node;
   398     typedef typename Graph::Node Node;
   399 
   399 
   400     /// \brief Constructor.
   400     /// \brief Constructor.
   401     ///
   401     ///
   402     /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
   402     /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
   403     /// attach it into the given LemonWriter. If the \c _forceIdMap
   403     /// attach it into the given LemonWriter. If the \c _forceLabelMap
   404     /// parameter is true then the writer will write own id map when
   404     /// parameter is true then the writer will write own label map when
   405     /// the user does not give "id" named map.
   405     /// the user does not give "label" named map.
   406     NodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   406     NodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   407 		  const std::string& _id = std::string(), 
   407 		  const std::string& _name = std::string(), 
   408 		  bool _forceIdMap = true) 
   408 		  bool _forceLabelMap = true) 
   409       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), 
   409       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), 
   410 	graph(_graph), id(_id) {}
   410 	graph(_graph), name(_name) {}
   411 
   411 
   412     /// \brief Destructor.
   412     /// \brief Destructor.
   413     ///
   413     ///
   414     /// Destructor for NodeSetWriter.
   414     /// Destructor for NodeSetWriter.
   415     virtual ~NodeSetWriter() {
   415     virtual ~NodeSetWriter() {
   452 
   452 
   453     /// \brief The header of the section.
   453     /// \brief The header of the section.
   454     ///
   454     ///
   455     /// It gives back the header of the section.
   455     /// It gives back the header of the section.
   456     virtual std::string header() {
   456     virtual std::string header() {
   457       return "@nodeset " + id;
   457       return "@nodeset " + name;
   458     }
   458     }
   459 
   459 
   460     /// \brief  Writer function of the section.
   460     /// \brief  Writer function of the section.
   461     ///
   461     ///
   462     /// Write the content of the section.
   462     /// Write the content of the section.
   463     virtual void write(std::ostream& os) {
   463     virtual void write(std::ostream& os) {
   464       for (int i = 0; i < (int)writers.size(); ++i) {
   464       for (int i = 0; i < (int)writers.size(); ++i) {
   465 	if (writers[i].first == "id") {
   465 	if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) {
   466 	  idMap = writers[i].second;
   466 	  labelMap = writers[i].second;
   467 	  forceIdMap = false;
   467 	  forceLabelMap = false;
   468 	  break;
   468 	  break;
   469 	}
   469 	}
   470       }
   470       }
   471       if (forceIdMap) {
   471       if (forceLabelMap) {
   472 	os << "id\t";
   472 	os << "label\t";
   473       }
   473       }
   474       for (int i = 0; i < (int)writers.size(); ++i) {
   474       for (int i = 0; i < (int)writers.size(); ++i) {
   475 	os << writers[i].first << '\t';
   475 	os << writers[i].first << '\t';
   476       }
   476       }
   477       os << std::endl;
   477       os << std::endl;
   478       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
   478       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
   479 	if (forceIdMap) {
   479 	if (forceLabelMap) {
   480 	  os << graph.id(it) << '\t';
   480 	  os << graph.id(it) << '\t';
   481 	}
   481 	}
   482 	for (int i = 0; i < (int)writers.size(); ++i) {
   482 	for (int i = 0; i < (int)writers.size(); ++i) {
   483 	  writers[i].second->write(os, it);
   483 	  writers[i].second->write(os, it);
   484 	  os << '\t';
   484 	  os << '\t';
   487       }
   487       }
   488     }
   488     }
   489 
   489 
   490   public:
   490   public:
   491 
   491 
   492     /// \brief Returns true if the nodeset can write the ids of the nodes.
   492     /// \brief Returns true if the nodeset can write the labels of the nodes.
   493     ///
   493     ///
   494     /// Returns true if the nodeset can write the ids of the nodes.
   494     /// Returns true if the nodeset can write the labels of the nodes.
   495     /// It is possible only if an "id" named map was written or the 
   495     /// It is possible only if an "label" named map was written or the 
   496     /// \c _forceIdMap constructor parameter was true.
   496     /// \c _forceLabelMap constructor parameter was true.
   497     bool isIdWriter() const {
   497     bool isLabelWriter() const {
   498       return idMap != 0 || forceIdMap;
   498       return labelMap != 0 || forceLabelMap;
   499     }
   499     }
   500 
   500 
   501     /// \brief Write the id of the given node.
   501     /// \brief Write the label of the given node.
   502     ///
   502     ///
   503     /// It writes the id of the given node. If there was written an "id"
   503     /// It writes the label of the given node. If there was written an "label"
   504     /// named map then it will write the map value belongs to the node.
   504     /// named map then it will write the map value belongs to the node.
   505     /// Otherwise if the \c forceId parameter was true it will write
   505     /// Otherwise if the \c forceLabel parameter was true it will write
   506     /// its id in the graph. 
   506     /// its label in the graph. 
   507     void writeId(std::ostream& os, const Node& item) const {
   507     void writeLabel(std::ostream& os, const Node& item) const {
   508       if (forceIdMap) {
   508       if (forceLabelMap) {
   509 	os << graph.id(item);
   509 	os << graph.id(item);
   510       } else {
   510       } else {
   511 	idMap->write(os, item);
   511 	labelMap->write(os, item);
   512       }
   512       }
   513     }
   513     }
   514 
   514 
   515   private:
   515   private:
   516 
   516 
   517     typedef std::vector<std::pair<std::string, _writer_bits::
   517     typedef std::vector<std::pair<std::string, _writer_bits::
   518 				  MapWriterBase<Node>*> > MapWriters;
   518 				  MapWriterBase<Node>*> > MapWriters;
   519     MapWriters writers;
   519     MapWriters writers;
   520 
   520 
   521     _writer_bits::MapWriterBase<Node>* idMap;
   521     _writer_bits::MapWriterBase<Node>* labelMap;
   522     bool forceIdMap;
   522     bool forceLabelMap;
   523    
   523    
   524     const Graph& graph;   
   524     const Graph& graph;   
   525     std::string id;
   525     std::string name;
   526 
   526 
   527   };
   527   };
   528 
   528 
   529   /// \ingroup io_group
   529   /// \ingroup io_group
   530   /// \brief SectionWriter for writing a graph's edgesets.
   530   /// \brief SectionWriter for writing a graph's edgesets.
   531   ///
   531   ///
   532   /// The lemon format can store multiple graph edgesets with several maps. 
   532   /// The lemon format can store multiple graph edgesets with several maps. 
   533   /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
   533   /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but 
   534   /// \c edgeset_id may be empty.
   534   /// the \c edgeset_name may be empty.
   535   ///
   535   ///
   536   /// The first line of the section contains the names of the maps separated
   536   /// The first line of the section contains the names of the maps separated
   537   /// with white spaces. Each next lines describes a edge in the edgeset. The
   537   /// with white spaces. Each next lines describes a edge in the edgeset. The
   538   /// line contains the source and the target nodes' id and the mapped 
   538   /// line contains the source and the target nodes' label and the mapped 
   539   /// values for each map.
   539   /// values for each map.
   540   ///
   540   ///
   541   /// If the edgeset contains an \c "id" named map then it will be regarded
   541   /// If the edgeset contains an \c "label" named map then it will be regarded
   542   /// as id map. This map should contain only unique values and when the 
   542   /// as label map. This map should contain only unique values and when the 
   543   /// \c writeId() member will be called with an edge it will write it's id.
   543   /// \c writeLabel() member will be called with an edge it will write it's 
   544   /// Otherwise if the \c _forceIdMap constructor parameter is true then
   544   /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   545   /// the id map will be the id in the graph.
   545   /// then the label map will be the id in the graph.
   546   ///
   546   ///
   547   /// The edgeset writer needs a node id writer to identify which nodes
   547   /// The edgeset writer needs a node label writer to identify which nodes
   548   /// have to be connected. If a NodeSetWriter can write the nodes' id,
   548   /// have to be connected. If a NodeSetWriter can write the nodes' label,
   549   /// it will be able to use with this class.
   549   /// it will be able to use with this class.
   550   ///
   550   ///
   551   /// \relates LemonWriter
   551   /// \relates LemonWriter
   552   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   552   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   553   class EdgeSetWriter : public LemonWriter::SectionWriter {
   553   class EdgeSetWriter : public LemonWriter::SectionWriter {
   560     typedef typename Graph::Edge Edge;
   560     typedef typename Graph::Edge Edge;
   561 
   561 
   562     /// \brief Constructor.
   562     /// \brief Constructor.
   563     ///
   563     ///
   564     /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
   564     /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
   565     /// attach it into the given LemonWriter. It will write node ids by
   565     /// attach it into the given LemonWriter. It will write node labels by
   566     /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true 
   566     /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true 
   567     /// then the writer will write own id map if the user does not give 
   567     /// then the writer will write own label map if the user does not give 
   568     /// "id" named map.
   568     /// "label" named map.
   569     template <typename NodeIdWriter>
   569     template <typename NodeLabelWriter>
   570     EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   570     EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   571 		  const NodeIdWriter& _nodeIdWriter, 
   571 		  const NodeLabelWriter& _nodeLabelWriter, 
   572 		  const std::string& _id = std::string(),
   572 		  const std::string& _name = std::string(),
   573 		  bool _forceIdMap = true)
   573 		  bool _forceLabelMap = true)
   574       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   574       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
   575 	graph(_graph), id(_id) {
   575 	graph(_graph), name(_name) {
   576       checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
   576       checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
   577       nodeIdWriter.reset(new _writer_bits::
   577       nodeLabelWriter.reset(new _writer_bits::
   578 			 IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
   578 			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   579     } 
   579     } 
   580 
   580 
   581     /// \brief Destructor.
   581     /// \brief Destructor.
   582     ///
   582     ///
   583     /// Destructor for EdgeSetWriter.
   583     /// Destructor for EdgeSetWriter.
   621 
   621 
   622     /// \brief The header of the section.
   622     /// \brief The header of the section.
   623     ///
   623     ///
   624     /// It gives back the header of the section.
   624     /// It gives back the header of the section.
   625     virtual std::string header() {
   625     virtual std::string header() {
   626       return "@edgeset " + id;
   626       return "@edgeset " + name;
   627     }
   627     }
   628 
   628 
   629     /// \brief  Writer function of the section.
   629     /// \brief  Writer function of the section.
   630     ///
   630     ///
   631     /// Write the content of the section.
   631     /// Write the content of the section.
   632     virtual void write(std::ostream& os) {
   632     virtual void write(std::ostream& os) {
   633       if (!nodeIdWriter->isIdWriter()) {
   633       if (!nodeLabelWriter->isLabelWriter()) {
   634 	throw DataFormatError("Cannot find nodeset or ID map");
   634 	throw DataFormatError("Cannot find nodeset or label map");
   635       }
   635       }
   636       for (int i = 0; i < (int)writers.size(); ++i) {
   636       for (int i = 0; i < (int)writers.size(); ++i) {
   637 	if (writers[i].first == "id") {
   637 	if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) {
   638 	  idMap = writers[i].second;
   638 	  labelMap = writers[i].second;
   639 	  forceIdMap = false;
   639 	  forceLabelMap = false;
   640 	  break;
   640 	  break;
   641 	}
   641 	}
   642       }
   642       }
   643       os << "\t\t";
   643       os << "\t\t";
   644       if (forceIdMap) {
   644       if (forceLabelMap) {
   645 	os << "id\t";
   645 	os << "label\t";
   646       }
   646       }
   647       for (int i = 0; i < (int)writers.size(); ++i) {
   647       for (int i = 0; i < (int)writers.size(); ++i) {
   648 	os << writers[i].first << '\t';
   648 	os << writers[i].first << '\t';
   649       }
   649       }
   650       os << std::endl;
   650       os << std::endl;
   651       for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
   651       for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
   652 	nodeIdWriter->write(os, graph.source(it));
   652 	nodeLabelWriter->write(os, graph.source(it));
   653 	os << '\t';
   653 	os << '\t';
   654 	nodeIdWriter->write(os, graph.target(it));
   654 	nodeLabelWriter->write(os, graph.target(it));
   655 	os << '\t';
   655 	os << '\t';
   656 	if (forceIdMap) {
   656 	if (forceLabelMap) {
   657 	  os << graph.id(it) << '\t';
   657 	  os << graph.id(it) << '\t';
   658 	}
   658 	}
   659 	for (int i = 0; i < (int)writers.size(); ++i) {
   659 	for (int i = 0; i < (int)writers.size(); ++i) {
   660 	  writers[i].second->write(os, it);
   660 	  writers[i].second->write(os, it);
   661 	  os << '\t';
   661 	  os << '\t';
   664       }
   664       }
   665     }
   665     }
   666 
   666 
   667   public:
   667   public:
   668 
   668 
   669     /// \brief Returns true if the edgeset can write the ids of the edges.
   669     /// \brief Returns true if the edgeset can write the labels of the edges.
   670     ///
   670     ///
   671     /// Returns true if the edgeset can write the ids of the edges.
   671     /// Returns true if the edgeset can write the labels of the edges.
   672     /// It is possible only if an "id" named map was written or the 
   672     /// It is possible only if an "label" named map was written or the 
   673     /// \c _forceIdMap constructor parameter was true.
   673     /// \c _forceLabelMap constructor parameter was true.
   674     bool isIdWriter() const {
   674     bool isLabelWriter() const {
   675       return forceIdMap || idMap != 0;
   675       return forceLabelMap || labelMap != 0;
   676     }
   676     }
   677 
   677 
   678     /// \brief Write the id of the given edge.
   678     /// \brief Write the label of the given edge.
   679     ///
   679     ///
   680     /// It writes the id of the given edge. If there was written an "id"
   680     /// It writes the label of the given edge. If there was written an "label"
   681     /// named map then it will write the map value belongs to the edge.
   681     /// named map then it will write the map value belongs to the edge.
   682     /// Otherwise if the \c forceId parameter was true it will write
   682     /// Otherwise if the \c forceLabel parameter was true it will write
   683     /// its id in the graph. 
   683     /// its label in the graph. 
   684     void writeId(std::ostream& os, const Edge& item) const {
   684     void writeLabel(std::ostream& os, const Edge& item) const {
   685       if (forceIdMap) {
   685       if (forceLabelMap) {
   686 	os << graph.id(item);
   686 	os << graph.id(item);
   687       } else {
   687       } else {
   688 	idMap->write(os, item);
   688 	labelMap->write(os, item);
   689       }
   689       }
   690     } 
   690     } 
   691 
   691 
   692   private:
   692   private:
   693 
   693 
   694     typedef std::vector<std::pair<std::string, _writer_bits::
   694     typedef std::vector<std::pair<std::string, _writer_bits::
   695 				  MapWriterBase<Edge>*> > MapWriters;
   695 				  MapWriterBase<Edge>*> > MapWriters;
   696     MapWriters writers;
   696     MapWriters writers;
   697 
   697 
   698     _writer_bits::MapWriterBase<Edge>* idMap;
   698     _writer_bits::MapWriterBase<Edge>* labelMap;
   699     bool forceIdMap;
   699     bool forceLabelMap;
   700    
   700    
   701     const Graph& graph;   
   701     const Graph& graph;   
   702     std::string id;
   702     std::string name;
   703 
   703 
   704     std::auto_ptr<_writer_bits::IdWriterBase<Node> > nodeIdWriter;
   704     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
   705   };
   705   };
   706 
   706 
   707   /// \ingroup io_group
   707   /// \ingroup io_group
   708   /// \brief SectionWriter for writing a undirected edgeset.
   708   /// \brief SectionWriter for writing a undirected edgeset.
   709   ///
   709   ///
   710   /// The lemon format can store multiple undirected edgesets with several 
   710   /// The lemon format can store multiple undirected edgesets with several 
   711   /// maps. The undirected edgeset section's header line is \c \@undiredgeset 
   711   /// maps. The undirected edgeset section's header line is \c \@undiredgeset 
   712   /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
   712   /// \c undiredgeset_name, but the \c undiredgeset_name may be empty.
   713   ///
   713   ///
   714   /// The first line of the section contains the names of the maps separated
   714   /// The first line of the section contains the names of the maps separated
   715   /// with white spaces. Each next lines describes an undirected edge in the 
   715   /// with white spaces. Each next lines describes an undirected edge in the 
   716   /// edgeset. The line contains the two connected nodes' id and the mapped 
   716   /// edgeset. The line contains the two connected nodes' label and the mapped 
   717   /// values for each undirected map.
   717   /// values for each undirected map.
   718   ///
   718   ///
   719   /// The section can handle the directed as a syntactical sugar. Two
   719   /// The section can handle the directed as a syntactical sugar. Two
   720   /// undirected edge map describes one directed edge map. This two maps
   720   /// undirected edge map describes one directed edge map. This two maps
   721   /// are the forward map and the backward map and the names of this map
   721   /// are the forward map and the backward map and the names of this map
   722   /// is near the same just with a prefix \c '+' or \c '-' character 
   722   /// is near the same just with a prefix \c '+' or \c '-' character 
   723   /// difference.
   723   /// difference.
   724   ///
   724   ///
   725   /// If the edgeset contains an \c "id" named map then it will be regarded
   725   /// If the edgeset contains an \c "label" named map then it will be regarded
   726   /// as id map. This map should contain only unique values and when the 
   726   /// as label map. This map should contain only unique values and when the 
   727   /// \c writeId() member will be called with an undirected edge it will 
   727   /// \c writeLabel() member will be called with an undirected edge it will 
   728   /// write it's id. Otherwise if the \c _forceIdMap constructor parameter
   728   /// write it's label. Otherwise if the \c _forceLabelMap constructor 
   729   /// is true then the id map will be the id in the graph.
   729   /// parameter is true then the label map will be the id in the graph.
   730   ///
   730   ///
   731   /// The undirected edgeset writer needs a node id writer to identify 
   731   /// The undirected edgeset writer needs a node label writer to identify 
   732   /// which nodes have to be connected. If a NodeSetWriter can write the 
   732   /// which nodes have to be connected. If a NodeSetWriter can write the 
   733   /// nodes' id, it will be able to use with this class.
   733   /// nodes' label, it will be able to use with this class.
   734   ///
   734   ///
   735   /// \relates LemonWriter
   735   /// \relates LemonWriter
   736   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   736   template <typename _Graph, typename _Traits = DefaultWriterTraits>
   737   class UndirEdgeSetWriter : public LemonWriter::SectionWriter {
   737   class UndirEdgeSetWriter : public LemonWriter::SectionWriter {
   738     typedef LemonWriter::SectionWriter Parent;
   738     typedef LemonWriter::SectionWriter Parent;
   745     typedef typename Graph::UndirEdge UndirEdge;
   745     typedef typename Graph::UndirEdge UndirEdge;
   746 
   746 
   747     /// \brief Constructor.
   747     /// \brief Constructor.
   748     ///
   748     ///
   749     /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
   749     /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
   750     /// and attach it into the given LemonWriter. It will write node ids by
   750     /// and attach it into the given LemonWriter. It will write node labels by
   751     /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true 
   751     /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true 
   752     /// then the writer will write own id map if the user does not give 
   752     /// then the writer will write own label map if the user does not give 
   753     /// "id" named map.
   753     /// "label" named map.
   754     template <typename NodeIdWriter>
   754     template <typename NodeLabelWriter>
   755     UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   755     UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   756 		       const NodeIdWriter& _nodeIdWriter, 
   756 		       const NodeLabelWriter& _nodeLabelWriter, 
   757 		       const std::string& _id = std::string(),
   757 		       const std::string& _name = std::string(),
   758 		       bool _forceIdMap = true)
   758 		       bool _forceLabelMap = true)
   759       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   759       : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
   760 	graph(_graph), id(_id) {
   760 	graph(_graph), name(_name) {
   761       checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
   761       checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
   762       nodeIdWriter.reset(new _writer_bits::
   762       nodeLabelWriter.reset(new _writer_bits::
   763 			 IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
   763 			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   764     } 
   764     } 
   765 
   765 
   766     /// \brief Destructor.
   766     /// \brief Destructor.
   767     ///
   767     ///
   768     /// Destructor for UndirEdgeSetWriter.
   768     /// Destructor for UndirEdgeSetWriter.
   830 
   830 
   831     /// \brief The header of the section.
   831     /// \brief The header of the section.
   832     ///
   832     ///
   833     /// It gives back the header of the section.
   833     /// It gives back the header of the section.
   834     virtual std::string header() {
   834     virtual std::string header() {
   835       return "@undiredgeset " + id;
   835       return "@undiredgeset " + name;
   836     }
   836     }
   837 
   837 
   838     /// \brief  Writer function of the section.
   838     /// \brief  Writer function of the section.
   839     ///
   839     ///
   840     /// Write the content of the section.
   840     /// Write the content of the section.
   841     virtual void write(std::ostream& os) {
   841     virtual void write(std::ostream& os) {
   842       if (!nodeIdWriter->isIdWriter()) {
   842       if (!nodeLabelWriter->isLabelWriter()) {
   843 	throw DataFormatError("Cannot find nodeset or ID map");
   843 	throw DataFormatError("Cannot find nodeset or label map");
   844       }
   844       }
   845       for (int i = 0; i < (int)writers.size(); ++i) {
   845       for (int i = 0; i < (int)writers.size(); ++i) {
   846 	if (writers[i].first == "id") {
   846 	if (writers[i].first == "label") {
   847 	  idMap = writers[i].second;
   847 	  labelMap = writers[i].second;
   848 	  forceIdMap = false;
   848 	  forceLabelMap = false;
   849 	  break;
   849 	  break;
   850 	}
   850 	}
   851       }
   851       }
   852       os << "\t\t";
   852       os << "\t\t";
   853       if (forceIdMap) {
   853       if (forceLabelMap) {
   854 	os << "id\t";
   854 	os << "label\t";
   855       }
   855       }
   856       for (int i = 0; i < (int)writers.size(); ++i) {
   856       for (int i = 0; i < (int)writers.size(); ++i) {
   857 	os << writers[i].first << '\t';
   857 	os << writers[i].first << '\t';
   858       }
   858       }
   859       os << std::endl;
   859       os << std::endl;
   860       for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
   860       for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
   861 	nodeIdWriter->write(os, graph.source(it));
   861 	nodeLabelWriter->write(os, graph.source(it));
   862 	os << '\t';
   862 	os << '\t';
   863 	nodeIdWriter->write(os, graph.target(it));
   863 	nodeLabelWriter->write(os, graph.target(it));
   864 	os << '\t';
   864 	os << '\t';
   865 	if (forceIdMap) {
   865 	if (forceLabelMap) {
   866 	  os << graph.id(it) << '\t';
   866 	  os << graph.id(it) << '\t';
   867 	}
   867 	}
   868 	for (int i = 0; i < (int)writers.size(); ++i) {
   868 	for (int i = 0; i < (int)writers.size(); ++i) {
   869 	  writers[i].second->write(os, it);
   869 	  writers[i].second->write(os, it);
   870 	  os << '\t';
   870 	  os << '\t';
   873       }
   873       }
   874     }
   874     }
   875 
   875 
   876   public:
   876   public:
   877 
   877 
   878     /// \brief Returns true if the undirected edgeset can write the ids of 
   878     /// \brief Returns true if the undirected edgeset can write the labels of 
   879     /// the edges.
   879     /// the edges.
   880     ///
   880     ///
   881     /// Returns true if the undirected edgeset can write the ids of the 
   881     /// Returns true if the undirected edgeset can write the labels of the 
   882     /// undirected edges. It is possible only if an "id" named map was 
   882     /// undirected edges. It is possible only if an "label" named map was 
   883     /// written or the \c _forceIdMap constructor parameter was true.
   883     /// written or the \c _forceLabelMap constructor parameter was true.
   884     bool isIdWriter() const {
   884     bool isLabelWriter() const {
   885       return forceIdMap || idMap != 0;
   885       return forceLabelMap || labelMap != 0;
   886     }
   886     }
   887 
   887 
   888     /// \brief Write the id of the given undirected edge.
   888     /// \brief Write the label of the given undirected edge.
   889     ///
   889     ///
   890     /// It writes the id of the given undirected edge. If there was written 
   890     /// It writes the label of the given undirected edge. If there was written 
   891     /// an "id" named map then it will write the map value belongs to the 
   891     /// an "label" named map then it will write the map value belongs to the 
   892     /// undirected edge. Otherwise if the \c forceId parameter was true it 
   892     /// undirected edge. Otherwise if the \c forceLabel parameter was true it 
   893     /// will write its id in the graph. 
   893     /// will write its id in the graph. 
   894     void writeId(std::ostream& os, const UndirEdge& item) const {
   894     void writeLabel(std::ostream& os, const UndirEdge& item) const {
   895       if (forceIdMap) {
   895       if (forceLabelMap) {
   896 	os << graph.id(item);
   896 	os << graph.id(item);
   897       } else {
   897       } else {
   898 	idMap->write(os, item);
   898 	labelMap->write(os, item);
   899       }
   899       }
   900     } 
   900     } 
   901 
   901 
   902     /// \brief Write the id of the given edge.
   902     /// \brief Write the label of the given edge.
   903     ///
   903     ///
   904     /// It writes the id of the given edge. If there was written 
   904     /// It writes the label of the given edge. If there was written 
   905     /// an "id" named map then it will write the map value belongs to the 
   905     /// an "label" named map then it will write the map value belongs to the 
   906     /// edge. Otherwise if the \c forceId parameter was true it 
   906     /// edge. Otherwise if the \c forceLabel parameter was true it 
   907     /// will write its id in the graph. If the edge is forward map
   907     /// will write its id in the graph. If the edge is forward map
   908     /// then its prefix character is \c '+' elsewhere \c '-'.
   908     /// then its prefix character is \c '+' elsewhere \c '-'.
   909     void writeId(std::ostream& os, const Edge& item) const {
   909     void writeLabel(std::ostream& os, const Edge& item) const {
   910       if (graph.direction(item)) {
   910       if (graph.direction(item)) {
   911 	os << "+ ";
   911 	os << "+ ";
   912       } else {
   912       } else {
   913 	os << "- ";
   913 	os << "- ";
   914       }
   914       }
   915       if (forceIdMap) {
   915       if (forceLabelMap) {
   916 	os << graph.id(item);
   916 	os << graph.id(item);
   917       } else {
   917       } else {
   918 	idMap->write(os, item);
   918 	labelMap->write(os, item);
   919       }
   919       }
   920     } 
   920     } 
   921 
   921 
   922   private:
   922   private:
   923 
   923 
   924     typedef std::vector<std::pair<std::string, _writer_bits::
   924     typedef std::vector<std::pair<std::string, _writer_bits::
   925 				  MapWriterBase<UndirEdge>*> > MapWriters;
   925 				  MapWriterBase<UndirEdge>*> > MapWriters;
   926     MapWriters writers;
   926     MapWriters writers;
   927 
   927 
   928     _writer_bits::MapWriterBase<UndirEdge>* idMap;
   928     _writer_bits::MapWriterBase<UndirEdge>* labelMap;
   929     bool forceIdMap;
   929     bool forceLabelMap;
   930    
   930    
   931     const Graph& graph;   
   931     const Graph& graph;   
   932     std::string id;
   932     std::string name;
   933 
   933 
   934     std::auto_ptr<_writer_bits::IdWriterBase<Node> > nodeIdWriter;
   934     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
   935   };
   935   };
   936 
   936 
   937   /// \ingroup io_group
   937   /// \ingroup io_group
   938   /// \brief SectionWriter for writing labeled nodes.
   938   /// \brief SectionWriter for writing named nodes.
   939   ///
   939   ///
   940   /// The nodes section's header line is \c \@nodes \c nodes_id, but the
   940   /// The nodes section's header line is \c \@nodes \c nodes_name, but the
   941   /// \c nodes_id may be empty.
   941   /// \c nodes_name may be empty.
   942   ///
   942   ///
   943   /// Each line in the section contains the label of the node and 
   943   /// Each line in the section contains the name of the node and 
   944   /// then the node id. 
   944   /// then the node label. 
   945   ///
   945   ///
   946   /// \relates LemonWriter
   946   /// \relates LemonWriter
   947   template <typename _Graph>
   947   template <typename _Graph>
   948   class NodeWriter : public LemonWriter::SectionWriter {
   948   class NodeWriter : public LemonWriter::SectionWriter {
   949     typedef LemonWriter::SectionWriter Parent;
   949     typedef LemonWriter::SectionWriter Parent;
   952   public:
   952   public:
   953     
   953     
   954     /// \brief Constructor.
   954     /// \brief Constructor.
   955     ///
   955     ///
   956     /// Constructor for NodeWriter. It creates the NodeWriter and
   956     /// Constructor for NodeWriter. It creates the NodeWriter and
   957     /// attach it into the given LemonWriter. The given \c _IdWriter
   957     /// attach it into the given LemonWriter. The given \c _LabelWriter
   958     /// will write the nodes' id what can be a nodeset writer.
   958     /// will write the nodes' label what can be a nodeset writer.
   959     template <typename _IdWriter>
   959     template <typename _LabelWriter>
   960     NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
   960     NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
   961 	       const std::string& _id = std::string()) 
   961 	       const std::string& _name = std::string()) 
   962       : Parent(_writer), id(_id) {
   962       : Parent(_writer), name(_name) {
   963       checkConcept<_writer_bits::ItemIdWriter<Node>, _IdWriter>();
   963       checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
   964       idWriter.reset(new _writer_bits::IdWriter<Node, _IdWriter>(_idWriter));
   964       labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
       
   965                         (_labelWriter));
   965     }
   966     }
   966 
   967 
   967 
   968 
   968     /// \brief Destructor.
   969     /// \brief Destructor.
   969     ///
   970     ///
   983       writers.push_back(make_pair(name, &item));
   984       writers.push_back(make_pair(name, &item));
   984     }
   985     }
   985 
   986 
   986   protected:
   987   protected:
   987 
   988 
   988     /// \brief Header checking function.
   989     /// \brief The header of the section.
   989     ///
   990     ///
   990     /// It gives back true when the header line start with \c \@nodes,
   991     /// It gives back the header of the section.
   991     /// and the header line's id and the writer's id are the same.
       
   992     virtual std::string header() {
   992     virtual std::string header() {
   993       return "@nodes " + id;
   993       return "@nodes " + name;
   994     }
   994     }
   995 
   995 
   996     /// \brief  Writer function of the section.
   996     /// \brief  Writer function of the section.
   997     ///
   997     ///
   998     /// Write the content of the section.
   998     /// Write the content of the section.
   999     virtual void write(std::ostream& os) {
   999     virtual void write(std::ostream& os) {
  1000       if (!idWriter->isIdWriter()) {
  1000       if (!labelWriter->isLabelWriter()) {
  1001 	throw DataFormatError("Cannot find nodeset or ID map");
  1001 	throw DataFormatError("Cannot find nodeset or label map");
  1002       }
  1002       }
  1003       for (int i = 0; i < (int)writers.size(); ++i) {
  1003       for (int i = 0; i < (int)writers.size(); ++i) {
  1004 	os << writers[i].first << ' ';
  1004 	os << writers[i].first << ' ';
  1005 	idWriter->write(os, *(writers[i].second));
  1005 	labelWriter->write(os, *(writers[i].second));
  1006 	os << std::endl;
  1006 	os << std::endl;
  1007       }
  1007       }
  1008     }
  1008     }
  1009     
  1009     
  1010   private:
  1010   private:
  1011 
  1011 
  1012     std::string id;
  1012     std::string name;
  1013 
  1013 
  1014     typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
  1014     typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
  1015     NodeWriters writers;
  1015     NodeWriters writers;
  1016     std::auto_ptr<_writer_bits::IdWriterBase<Node> > idWriter;
  1016     std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
  1017   };
  1017   };
  1018 
  1018 
  1019   /// \ingroup io_group
  1019   /// \ingroup io_group
  1020   /// \brief SectionWriter for writing labeled edges.
  1020   /// \brief SectionWriter for writing named edges.
  1021   ///
  1021   ///
  1022   /// The edges section's header line is \c \@edges \c edges_id, but the
  1022   /// The edges section's header line is \c \@edges \c edges_name, but the
  1023   /// \c edges_id may be empty.
  1023   /// \c edges_name may be empty.
  1024   ///
  1024   ///
  1025   /// Each line in the section contains the label of the edge and 
  1025   /// Each line in the section contains the name of the edge and 
  1026   /// then the edge id. 
  1026   /// then the edge label. 
  1027   ///
  1027   ///
  1028   /// \relates LemonWriter
  1028   /// \relates LemonWriter
  1029   template <typename _Graph>
  1029   template <typename _Graph>
  1030   class EdgeWriter : public LemonWriter::SectionWriter {
  1030   class EdgeWriter : public LemonWriter::SectionWriter {
  1031     typedef LemonWriter::SectionWriter Parent;
  1031     typedef LemonWriter::SectionWriter Parent;
  1034   public:
  1034   public:
  1035     
  1035     
  1036     /// \brief Constructor.
  1036     /// \brief Constructor.
  1037     ///
  1037     ///
  1038     /// Constructor for EdgeWriter. It creates the EdgeWriter and
  1038     /// Constructor for EdgeWriter. It creates the EdgeWriter and
  1039     /// attach it into the given LemonWriter. The given \c _IdWriter
  1039     /// attach it into the given LemonWriter. The given \c _LabelWriter
  1040     /// will write the edges' id what can be a edgeset writer.
  1040     /// will write the edges' label what can be a edgeset writer.
  1041     template <typename _IdWriter>
  1041     template <typename _LabelWriter>
  1042     EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
  1042     EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
  1043 	       const std::string& _id = std::string()) 
  1043 	       const std::string& _name = std::string()) 
  1044       : Parent(_writer), id(_id) {
  1044       : Parent(_writer), name(_name) {
  1045       checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
  1045       checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
  1046       idWriter.reset(new _writer_bits::IdWriter<Edge, _IdWriter>(_idWriter));
  1046       labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
  1047     }
  1047     }
  1048 
  1048 
  1049     /// \brief Destructor.
  1049     /// \brief Destructor.
  1050     ///
  1050     ///
  1051     /// Destructor for EdgeWriter.
  1051     /// Destructor for EdgeWriter.
  1063       writers.push_back(make_pair(name, &item));
  1063       writers.push_back(make_pair(name, &item));
  1064     }
  1064     }
  1065 
  1065 
  1066   protected:
  1066   protected:
  1067 
  1067 
  1068     /// \brief Header checking function.
  1068     /// \brief The header of the section.
  1069     ///
  1069     ///
  1070     /// It gives back true when the header line start with \c \@edges,
  1070     /// It gives back the header of the section.
  1071     /// and the header line's id and the writer's id are the same.
       
  1072     virtual std::string header() {
  1071     virtual std::string header() {
  1073       return "@edges " + id;
  1072       return "@edges " + name;
  1074     }
  1073     }
  1075 
  1074 
  1076     /// \brief  Writer function of the section.
  1075     /// \brief  Writer function of the section.
  1077     ///
  1076     ///
  1078     /// Write the content of the section.
  1077     /// Write the content of the section.
  1079     virtual void write(std::ostream& os) {
  1078     virtual void write(std::ostream& os) {
  1080       if (!idWriter->isIdWriter()) {
  1079       if (!labelWriter->isLabelWriter()) {
  1081 	throw DataFormatError("Cannot find edgeset or ID map");
  1080 	throw DataFormatError("Cannot find edgeset or label map");
  1082       }
  1081       }
  1083       for (int i = 0; i < (int)writers.size(); ++i) {
  1082       for (int i = 0; i < (int)writers.size(); ++i) {
  1084 	os << writers[i].first << ' ';
  1083 	os << writers[i].first << ' ';
  1085 	idWriter->write(os, *(writers[i].second));
  1084 	labelWriter->write(os, *(writers[i].second));
  1086 	os << std::endl;
  1085 	os << std::endl;
  1087       }
  1086       }
  1088     }
  1087     }
  1089     
  1088     
  1090   private:
  1089   private:
  1091 
  1090 
  1092     std::string id;
  1091     std::string name;
  1093 
  1092 
  1094     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
  1093     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
  1095     EdgeWriters writers;
  1094     EdgeWriters writers;
  1096 
  1095 
  1097     std::auto_ptr<_writer_bits::IdWriterBase<Edge> > idWriter;
  1096     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
  1098   };
  1097   };
  1099 
  1098 
  1100   /// \ingroup io_group
  1099   /// \ingroup io_group
  1101   /// \brief SectionWriter for writing labeled undirected edges.
  1100   /// \brief SectionWriter for writing named undirected edges.
  1102   ///
  1101   ///
  1103   /// The undirected edges section's header line is \c \@undiredges 
  1102   /// The undirected edges section's header line is \c \@undiredges 
  1104   /// \c undiredges_id, but the \c undiredges_id may be empty.
  1103   /// \c undiredges_name, but the \c undiredges_name may be empty.
  1105   ///
  1104   ///
  1106   /// Each line in the section contains the label of the undirected edge and 
  1105   /// Each line in the section contains the name of the undirected edge and 
  1107   /// then the undirected edge id. 
  1106   /// then the undirected edge label. 
  1108   ///
  1107   ///
  1109   /// \relates LemonWriter
  1108   /// \relates LemonWriter
  1110   template <typename _Graph>
  1109   template <typename _Graph>
  1111   class UndirEdgeWriter : public LemonWriter::SectionWriter {
  1110   class UndirEdgeWriter : public LemonWriter::SectionWriter {
  1112     typedef LemonWriter::SectionWriter Parent;
  1111     typedef LemonWriter::SectionWriter Parent;
  1117   public:
  1116   public:
  1118     
  1117     
  1119     /// \brief Constructor.
  1118     /// \brief Constructor.
  1120     ///
  1119     ///
  1121     /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
  1120     /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
  1122     /// attach it into the given LemonWriter. The given \c _IdWriter
  1121     /// attach it into the given LemonWriter. The given \c _LabelWriter
  1123     /// will write the undirected edges' id what can be an undirected 
  1122     /// will write the undirected edges' label what can be an undirected 
  1124     /// edgeset writer.
  1123     /// edgeset writer.
  1125     template <typename _IdWriter>
  1124     template <typename _LabelWriter>
  1126     UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
  1125     UndirEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
  1127 	       const std::string& _id = std::string()) 
  1126 	       const std::string& _name = std::string()) 
  1128       : Parent(_writer), id(_id) {
  1127       : Parent(_writer), name(_name) {
  1129       checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
  1128       checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
  1130       checkConcept<_writer_bits::ItemIdWriter<UndirEdge>, _IdWriter>();
  1129       checkConcept<_writer_bits::ItemLabelWriter<UndirEdge>, _LabelWriter>();
  1131       undirEdgeIdWriter.reset(new _writer_bits::
  1130       undirEdgeLabelWriter.reset(new _writer_bits::
  1132 			      IdWriter<UndirEdge, _IdWriter>(_idWriter));
  1131 			      LabelWriter<UndirEdge, _LabelWriter>(_labelWriter));
  1133       edgeIdWriter.reset(new _writer_bits::
  1132       edgeLabelWriter.reset(new _writer_bits::
  1134 			 IdWriter<Edge, _IdWriter>(_idWriter));
  1133 			 LabelWriter<Edge, _LabelWriter>(_labelWriter));
  1135     }
  1134     }
  1136 
  1135 
  1137     /// \brief Destructor.
  1136     /// \brief Destructor.
  1138     ///
  1137     ///
  1139     /// Destructor for UndirEdgeWriter.
  1138     /// Destructor for UndirEdgeWriter.
  1158       undirEdgeWriters.push_back(make_pair(name, &item));
  1157       undirEdgeWriters.push_back(make_pair(name, &item));
  1159     }
  1158     }
  1160 
  1159 
  1161   protected:
  1160   protected:
  1162 
  1161 
  1163     /// \brief Header checking function.
  1162     /// \brief The header of the section.
  1164     ///
  1163     ///
  1165     /// It gives back true when the header line start with \c \@undiredges,
  1164     /// It gives back the header of the section.
  1166     /// and the header line's id and the writer's id are the same.
       
  1167     virtual std::string header() {
  1165     virtual std::string header() {
  1168       return "@undiredges " + id;
  1166       return "@undiredges " + name;
  1169     }
  1167     }
  1170 
  1168 
  1171     /// \brief  Writer function of the section.
  1169     /// \brief  Writer function of the section.
  1172     ///
  1170     ///
  1173     /// Write the content of the section.
  1171     /// Write the content of the section.
  1174     virtual void write(std::ostream& os) {
  1172     virtual void write(std::ostream& os) {
  1175       if (!edgeIdWriter->isIdWriter()) {
  1173       if (!edgeLabelWriter->isLabelWriter()) {
  1176 	throw DataFormatError("Cannot find undirected edgeset or ID map");
  1174 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1177       }
  1175       }
  1178       if (!undirEdgeIdWriter->isIdWriter()) {
  1176       if (!undirEdgeLabelWriter->isLabelWriter()) {
  1179 	throw DataFormatError("Cannot find undirected edgeset or ID map");
  1177 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1180       }
  1178       }
  1181       for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
  1179       for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
  1182 	os << undirEdgeWriters[i].first << ' ';
  1180 	os << undirEdgeWriters[i].first << ' ';
  1183 	undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));
  1181 	undirEdgeLabelWriter->write(os, *(undirEdgeWriters[i].second));
  1184 	os << std::endl;
  1182 	os << std::endl;
  1185       }
  1183       }
  1186       for (int i = 0; i < (int)edgeWriters.size(); ++i) {
  1184       for (int i = 0; i < (int)edgeWriters.size(); ++i) {
  1187 	os << edgeWriters[i].first << ' ';
  1185 	os << edgeWriters[i].first << ' ';
  1188 	edgeIdWriter->write(os, *(edgeWriters[i].second));
  1186 	edgeLabelWriter->write(os, *(edgeWriters[i].second));
  1189 	os << std::endl;
  1187 	os << std::endl;
  1190       }
  1188       }
  1191     }
  1189     }
  1192     
  1190     
  1193   private:
  1191   private:
  1194 
  1192 
  1195     std::string id;
  1193     std::string name;
  1196 
  1194 
  1197     typedef std::vector<std::pair<std::string, 
  1195     typedef std::vector<std::pair<std::string, 
  1198 				  const UndirEdge*> > UndirEdgeWriters;
  1196 				  const UndirEdge*> > UndirEdgeWriters;
  1199     UndirEdgeWriters undirEdgeWriters;
  1197     UndirEdgeWriters undirEdgeWriters;
  1200     std::auto_ptr<_writer_bits::IdWriterBase<UndirEdge> > undirEdgeIdWriter;
  1198     std::auto_ptr<_writer_bits::LabelWriterBase<UndirEdge> > undirEdgeLabelWriter;
  1201 
  1199 
  1202     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
  1200     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
  1203     EdgeWriters edgeWriters;
  1201     EdgeWriters edgeWriters;
  1204     std::auto_ptr<_writer_bits::IdWriterBase<Edge> > edgeIdWriter;
  1202     std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
  1205 
  1203 
  1206   };
  1204   };
  1207 
  1205 
  1208   /// \ingroup io_group
  1206   /// \ingroup io_group
  1209   /// \brief SectionWriter for attributes.
  1207   /// \brief SectionWriter for attributes.
  1210   ///
  1208   ///
  1211   /// The lemon format can store multiple attribute set. Each set has
  1209   /// The lemon format can store multiple attribute set. Each set has
  1212   /// the header line \c \@attributes \c attributeset_id, but the 
  1210   /// the header line \c \@attributes \c attributes_name, but the 
  1213   /// attributeset_id may be empty.
  1211   /// attributeset_name may be empty.
  1214   ///
  1212   ///
  1215   /// The attributeset section contains several lines. Each of them starts
  1213   /// The attributeset section contains several lines. Each of them starts
  1216   /// with the name of attribute and then the value.
  1214   /// with the name of attribute and then the value.
  1217   ///
  1215   ///
  1218   /// \relates LemonWriter
  1216   /// \relates LemonWriter
  1224     /// \brief Constructor.
  1222     /// \brief Constructor.
  1225     ///
  1223     ///
  1226     /// Constructor for AttributeWriter. It creates the AttributeWriter and
  1224     /// Constructor for AttributeWriter. It creates the AttributeWriter and
  1227     /// attach it into the given LemonWriter.
  1225     /// attach it into the given LemonWriter.
  1228     AttributeWriter(LemonWriter& _writer, 
  1226     AttributeWriter(LemonWriter& _writer, 
  1229 		    const std::string& _id = std::string()) 
  1227 		    const std::string& _name = std::string()) 
  1230       : Parent(_writer), id(_id) {}
  1228       : Parent(_writer), name(_name) {}
  1231 
  1229 
  1232     /// \brief Destructor.
  1230     /// \brief Destructor.
  1233     ///
  1231     ///
  1234     /// Destructor for AttributeWriter.
  1232     /// Destructor for AttributeWriter.
  1235     virtual ~AttributeWriter() {
  1233     virtual ~AttributeWriter() {
  1246   public:
  1244   public:
  1247     /// \brief Add an attribute writer command for the writer.
  1245     /// \brief Add an attribute writer command for the writer.
  1248     ///
  1246     ///
  1249     /// Add an attribute writer command for the writer.
  1247     /// Add an attribute writer command for the writer.
  1250     template <typename Value>
  1248     template <typename Value>
  1251     AttributeWriter& writeAttribute(const std::string& id, 
  1249     AttributeWriter& writeAttribute(const std::string& name, 
  1252 				    const Value& value) {
  1250 				    const Value& value) {
  1253       return 
  1251       return 
  1254 	writeAttribute<typename Traits::template Writer<Value> >(id, value);
  1252 	writeAttribute<typename Traits::template Writer<Value> >(name, value);
  1255     }
  1253     }
  1256 
  1254 
  1257     /// \brief Add an attribute writer command for the writer.
  1255     /// \brief Add an attribute writer command for the writer.
  1258     ///
  1256     ///
  1259     /// Add an attribute writer command for the writer.
  1257     /// Add an attribute writer command for the writer.
  1271 
  1269 
  1272     /// \brief The header of section.
  1270     /// \brief The header of section.
  1273     ///
  1271     ///
  1274     /// It gives back the header of the section.
  1272     /// It gives back the header of the section.
  1275     std::string header() {
  1273     std::string header() {
  1276       return "@attributes " + id;
  1274       return "@attributes " + name;
  1277     }
  1275     }
  1278 
  1276 
  1279     /// \brief  Writer function of the section.
  1277     /// \brief  Writer function of the section.
  1280     ///
  1278     ///
  1281     /// Write the content of the section.
  1279     /// Write the content of the section.
  1287 	os << std::endl;
  1285 	os << std::endl;
  1288       }
  1286       }
  1289     }    
  1287     }    
  1290 
  1288 
  1291   private:
  1289   private:
  1292     std::string id;
  1290     std::string name;
  1293 
  1291 
  1294     typedef std::vector<std::pair<std::string, 
  1292     typedef std::vector<std::pair<std::string, 
  1295 				  _writer_bits::ValueWriterBase*> > Writers;
  1293 				  _writer_bits::ValueWriterBase*> > Writers;
  1296     Writers writers;  
  1294     Writers writers;  
  1297   };
  1295   };