lemon/lemon_writer.h
changeset 1476 182da222fceb
parent 1435 8e85e6bbefdf
child 1492 0d58f0301923
equal deleted inserted replaced
0:247a3e0fcb0b 1:9afd8c9d6b90
    34 #include <lemon/graph_utils.h>
    34 #include <lemon/graph_utils.h>
    35 #include <lemon/bits/item_writer.h>
    35 #include <lemon/bits/item_writer.h>
    36 #include <lemon/utility.h>
    36 #include <lemon/utility.h>
    37 #include <lemon/maps.h>
    37 #include <lemon/maps.h>
    38 
    38 
       
    39 #include <lemon/concept_check.h>
       
    40 #include <lemon/concept/maps.h>
       
    41 
    39 
    42 
    40 namespace lemon {
    43 namespace lemon {
       
    44 
       
    45   namespace _writer_bits {
       
    46     
       
    47     template <typename Item>
       
    48     class ItemIdWriter {
       
    49     public:
       
    50 
       
    51       bool isIdWriter() { return true; }
       
    52 
       
    53       void writeId(std::ostream&, const Item&) {}
       
    54       
       
    55       template <class _ItemIdWriter>
       
    56       struct Constraints {
       
    57 	void constraints() {
       
    58 	  const Item item;
       
    59 	  bool b = writer.isIdWriter();
       
    60 	  ignore_unused_variable_warning(b);
       
    61 	  writer.writeId(os, item);
       
    62 	}
       
    63 	_ItemIdWriter& writer;
       
    64 	std::ostream& os;
       
    65       };
       
    66 
       
    67     };
       
    68 
       
    69   }
    41 
    70 
    42   /// \ingroup io_group
    71   /// \ingroup io_group
    43   /// \brief Lemon Format writer class.
    72   /// \brief Lemon Format writer class.
    44   /// 
    73   /// 
    45   /// The Lemon Format contains several sections. We do not want to
    74   /// The Lemon Format contains several sections. We do not want to
   227     template <typename _Item>
   256     template <typename _Item>
   228     class IdWriterBase {
   257     class IdWriterBase {
   229     public:
   258     public:
   230       typedef _Item Item;
   259       typedef _Item Item;
   231       virtual void write(std::ostream&, const Item&) const = 0;
   260       virtual void write(std::ostream&, const Item&) const = 0;
       
   261       virtual bool isIdWriter() const = 0;
   232     };
   262     };
   233 
   263 
   234     template <typename _Item, typename _BoxedIdWriter>
   264     template <typename _Item, typename _BoxedIdWriter>
   235     class IdWriter : public IdWriterBase<_Item> {
   265     class IdWriter : public IdWriterBase<_Item> {
   236     public:
   266     public:
   242       IdWriter(const BoxedIdWriter& _idWriter) 
   272       IdWriter(const BoxedIdWriter& _idWriter) 
   243 	: idWriter(_idWriter) {}
   273 	: idWriter(_idWriter) {}
   244 
   274 
   245       virtual void write(std::ostream& os, const Item& item) const {
   275       virtual void write(std::ostream& os, const Item& item) const {
   246 	idWriter.writeId(os, item);
   276 	idWriter.writeId(os, item);
       
   277       }
       
   278 
       
   279       virtual bool isIdWriter() const {
       
   280 	return idWriter.isIdWriter();
   247       }
   281       }
   248     };
   282     };
   249   };
   283   };
   250 
   284 
   251   /// \ingroup io_group
   285   /// \ingroup io_group
   316     ///
   350     ///
   317     /// Add a new node map writer command for the writer.
   351     /// Add a new node map writer command for the writer.
   318     template <typename Writer, typename Map>
   352     template <typename Writer, typename Map>
   319     NodeSetWriter& writeNodeMap(std::string name, const Map& map, 
   353     NodeSetWriter& writeNodeMap(std::string name, const Map& map, 
   320 			    const Writer& writer = Writer()) {
   354 			    const Writer& writer = Writer()) {
       
   355       checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>();
   321       writers.push_back(
   356       writers.push_back(
   322 	make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
   357 	make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
   323       return *this;
   358       return *this;
   324     }
   359     }
   325 
   360 
   444     EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   479     EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   445 		  const NodeIdWriter& _nodeIdWriter, 
   480 		  const NodeIdWriter& _nodeIdWriter, 
   446 		  const std::string& _id = std::string(),
   481 		  const std::string& _id = std::string(),
   447 		  bool _forceIdMap = true)
   482 		  bool _forceIdMap = true)
   448       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   483       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   449 	graph(_graph), id(_id),
   484 	graph(_graph), id(_id) {
   450 	nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {} 
   485       checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
       
   486       nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
       
   487     } 
   451 
   488 
   452     /// \brief Destructor.
   489     /// \brief Destructor.
   453     ///
   490     ///
   454     /// Destructor for EdgeSetWriter.
   491     /// Destructor for EdgeSetWriter.
   455     virtual ~EdgeSetWriter() {
   492     virtual ~EdgeSetWriter() {
   478     ///
   515     ///
   479     /// Add a new edge map writer command for the writer.
   516     /// Add a new edge map writer command for the writer.
   480     template <typename Writer, typename Map>
   517     template <typename Writer, typename Map>
   481     EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
   518     EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
   482 			    const Writer& writer = Writer()) {
   519 			    const Writer& writer = Writer()) {
       
   520       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
   483       writers.push_back(
   521       writers.push_back(
   484 	make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
   522 	make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
   485       return *this;
   523       return *this;
   486     }
   524     }
   487 
   525 
   496 
   534 
   497     /// \brief  Writer function of the section.
   535     /// \brief  Writer function of the section.
   498     ///
   536     ///
   499     /// Write the content of the section.
   537     /// Write the content of the section.
   500     virtual void write(std::ostream& os) {
   538     virtual void write(std::ostream& os) {
       
   539       if (!nodeIdWriter->isIdWriter()) {
       
   540 	throw DataFormatError("Cannot find nodeset or ID map");
       
   541       }
   501       for (int i = 0; i < (int)writers.size(); ++i) {
   542       for (int i = 0; i < (int)writers.size(); ++i) {
   502 	if (writers[i].first == "id") {
   543 	if (writers[i].first == "id") {
   503 	  idMap = writers[i].second;
   544 	  idMap = writers[i].second;
   504 	  forceIdMap = false;
   545 	  forceIdMap = false;
   505 	  break;
   546 	  break;
   619     UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   660     UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   620 		       const NodeIdWriter& _nodeIdWriter, 
   661 		       const NodeIdWriter& _nodeIdWriter, 
   621 		       const std::string& _id = std::string(),
   662 		       const std::string& _id = std::string(),
   622 		       bool _forceIdMap = true)
   663 		       bool _forceIdMap = true)
   623       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   664       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   624 	graph(_graph), id(_id),
   665 	graph(_graph), id(_id) {
   625 	nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {} 
   666       checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
       
   667       nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
       
   668     } 
   626 
   669 
   627     /// \brief Destructor.
   670     /// \brief Destructor.
   628     ///
   671     ///
   629     /// Destructor for UndirEdgeSetWriter.
   672     /// Destructor for UndirEdgeSetWriter.
   630     virtual ~UndirEdgeSetWriter() {
   673     virtual ~UndirEdgeSetWriter() {
   653     ///
   696     ///
   654     /// Add a new undirected map writer command for the writer.
   697     /// Add a new undirected map writer command for the writer.
   655     template <typename Writer, typename Map>
   698     template <typename Writer, typename Map>
   656     UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, 
   699     UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, 
   657 					  const Writer& writer = Writer()) {
   700 					  const Writer& writer = Writer()) {
       
   701       checkConcept<concept::WriteMap<UndirEdge, typename Map::Value>, Map>();
   658       writers.push_back(
   702       writers.push_back(
   659 	make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
   703 	make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
   660       return *this;
   704       return *this;
   661     }
   705     }
   662 
   706 
   663     /// \brief Add a new directed edge map writer command for the writer.
   707     /// \brief Add a new directed edge map writer command for the writer.
   664     ///
   708     ///
   665     /// Add a new directed map writer command for the writer.
   709     /// Add a new directed map writer command for the writer.
   666     template <typename Map>
   710     template <typename Map>
   667     UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
   711     UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
       
   712       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
   668       writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
   713       writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
   669       writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
   714       writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
   670       return *this;
   715       return *this;
   671     }
   716     }
   672 
   717 
   674     ///
   719     ///
   675     /// Add a new directed map writer command for the writer.
   720     /// Add a new directed map writer command for the writer.
   676     template <typename Writer, typename Map>
   721     template <typename Writer, typename Map>
   677     UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
   722     UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
   678 				     const Writer& writer = Writer()) {
   723 				     const Writer& writer = Writer()) {
       
   724       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
   679       writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
   725       writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
   680       writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
   726       writeUndirEdge("-" + name, composeMap(backwardMap(graph), map), writer);
   681       return *this;
   727       return *this;
   682     }
   728     }
   683 
   729 
   684   protected:
   730   protected:
   685 
   731 
   692 
   738 
   693     /// \brief  Writer function of the section.
   739     /// \brief  Writer function of the section.
   694     ///
   740     ///
   695     /// Write the content of the section.
   741     /// Write the content of the section.
   696     virtual void write(std::ostream& os) {
   742     virtual void write(std::ostream& os) {
       
   743       if (!nodeIdWriter->isIdWriter()) {
       
   744 	throw DataFormatError("Cannot find nodeset or ID map");
       
   745       }
   697       for (int i = 0; i < (int)writers.size(); ++i) {
   746       for (int i = 0; i < (int)writers.size(); ++i) {
   698 	if (writers[i].first == "id") {
   747 	if (writers[i].first == "id") {
   699 	  idMap = writers[i].second;
   748 	  idMap = writers[i].second;
   700 	  forceIdMap = false;
   749 	  forceIdMap = false;
   701 	  break;
   750 	  break;
   809     /// attach it into the given LemonWriter. The given \c _IdWriter
   858     /// attach it into the given LemonWriter. The given \c _IdWriter
   810     /// will write the nodes' id what can be a nodeset writer.
   859     /// will write the nodes' id what can be a nodeset writer.
   811     template <typename _IdWriter>
   860     template <typename _IdWriter>
   812     NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
   861     NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
   813 	       const std::string& _id = std::string()) 
   862 	       const std::string& _id = std::string()) 
   814       : Parent(_writer), id(_id), 
   863       : Parent(_writer), id(_id) {
   815 	idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {} 
   864       checkConcept<_writer_bits::ItemIdWriter<Node>, _IdWriter>();
       
   865       idWriter.reset(new IdWriter<Node, _IdWriter>(_idWriter));
       
   866     }
       
   867 
   816 
   868 
   817     /// \brief Destructor.
   869     /// \brief Destructor.
   818     ///
   870     ///
   819     /// Destructor for NodeWriter.
   871     /// Destructor for NodeWriter.
   820     virtual ~NodeWriter() {}
   872     virtual ~NodeWriter() {}
   844 
   896 
   845     /// \brief  Writer function of the section.
   897     /// \brief  Writer function of the section.
   846     ///
   898     ///
   847     /// Write the content of the section.
   899     /// Write the content of the section.
   848     virtual void write(std::ostream& os) {
   900     virtual void write(std::ostream& os) {
       
   901       if (!idWriter->isIdWriter()) {
       
   902 	throw DataFormatError("Cannot find nodeset or ID map");
       
   903       }
   849       for (int i = 0; i < (int)writers.size(); ++i) {
   904       for (int i = 0; i < (int)writers.size(); ++i) {
   850 	os << writers[i].first << ' ';
   905 	os << writers[i].first << ' ';
   851 	idWriter->write(os, *(writers[i].second));
   906 	idWriter->write(os, *(writers[i].second));
   852 	os << std::endl;
   907 	os << std::endl;
   853       }
   908       }
   885     /// attach it into the given LemonWriter. The given \c _IdWriter
   940     /// attach it into the given LemonWriter. The given \c _IdWriter
   886     /// will write the edges' id what can be a edgeset writer.
   941     /// will write the edges' id what can be a edgeset writer.
   887     template <typename _IdWriter>
   942     template <typename _IdWriter>
   888     EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
   943     EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
   889 	       const std::string& _id = std::string()) 
   944 	       const std::string& _id = std::string()) 
   890       : Parent(_writer), id(_id), 
   945       : Parent(_writer), id(_id) {
   891 	idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {} 
   946       checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
       
   947       idWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
       
   948     }
   892 
   949 
   893     /// \brief Destructor.
   950     /// \brief Destructor.
   894     ///
   951     ///
   895     /// Destructor for EdgeWriter.
   952     /// Destructor for EdgeWriter.
   896     virtual ~EdgeWriter() {}
   953     virtual ~EdgeWriter() {}
   919 
   976 
   920     /// \brief  Writer function of the section.
   977     /// \brief  Writer function of the section.
   921     ///
   978     ///
   922     /// Write the content of the section.
   979     /// Write the content of the section.
   923     virtual void write(std::ostream& os) {
   980     virtual void write(std::ostream& os) {
       
   981       if (!idWriter->isIdWriter()) {
       
   982 	throw DataFormatError("Cannot find edgeset or ID map");
       
   983       }
   924       for (int i = 0; i < (int)writers.size(); ++i) {
   984       for (int i = 0; i < (int)writers.size(); ++i) {
   925 	os << writers[i].first << ' ';
   985 	os << writers[i].first << ' ';
   926 	idWriter->write(os, *(writers[i].second));
   986 	idWriter->write(os, *(writers[i].second));
   927 	os << std::endl;
   987 	os << std::endl;
   928       }
   988       }
   964     /// will write the undirected edges' id what can be an undirected 
  1024     /// will write the undirected edges' id what can be an undirected 
   965     /// edgeset writer.
  1025     /// edgeset writer.
   966     template <typename _IdWriter>
  1026     template <typename _IdWriter>
   967     UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
  1027     UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
   968 	       const std::string& _id = std::string()) 
  1028 	       const std::string& _id = std::string()) 
   969       : Parent(_writer), id(_id), 
  1029       : Parent(_writer), id(_id) {
   970 	undirEdgeIdWriter(new IdWriter<UndirEdge, _IdWriter>(_idWriter)),
  1030       checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
   971 	edgeIdWriter(new IdWriter<Edge, _IdWriter>(_idWriter)) {}
  1031       checkConcept<_writer_bits::ItemIdWriter<UndirEdge>, _IdWriter>();
       
  1032       undirEdgeIdWriter.reset(new IdWriter<UndirEdge, _IdWriter>(_idWriter));
       
  1033       edgeIdWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
       
  1034     }
   972 
  1035 
   973     /// \brief Destructor.
  1036     /// \brief Destructor.
   974     ///
  1037     ///
   975     /// Destructor for UndirEdgeWriter.
  1038     /// Destructor for UndirEdgeWriter.
   976     virtual ~UndirEdgeWriter() {}
  1039     virtual ~UndirEdgeWriter() {}
  1006 
  1069 
  1007     /// \brief  Writer function of the section.
  1070     /// \brief  Writer function of the section.
  1008     ///
  1071     ///
  1009     /// Write the content of the section.
  1072     /// Write the content of the section.
  1010     virtual void write(std::ostream& os) {
  1073     virtual void write(std::ostream& os) {
       
  1074       if (!edgeIdWriter->isIdWriter()) {
       
  1075 	throw DataFormatError("Cannot find undirected edgeset or ID map");
       
  1076       }
       
  1077       if (!undirEdgeIdWriter->isIdWriter()) {
       
  1078 	throw DataFormatError("Cannot find undirected edgeset or ID map");
       
  1079       }
  1011       for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
  1080       for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
  1012 	os << undirEdgeWriters[i].first << ' ';
  1081 	os << undirEdgeWriters[i].first << ' ';
  1013 	undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));
  1082 	undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));
  1014 	os << std::endl;
  1083 	os << std::endl;
  1015       }
  1084       }