lemon/lgf_writer.h
changeset 159 c7d30f7810e5
parent 148 4e2581021300
child 163 c82fd9568d75
equal deleted inserted replaced
3:dab83e468fc6 4:512d95c69100
   202 	return;
   202 	return;
   203       }     
   203       }     
   204     }
   204     }
   205 
   205 
   206     bool requireEscape(const std::string& str) {
   206     bool requireEscape(const std::string& str) {
       
   207       if (str.empty() || str[0] == '@') return true;
   207       std::istringstream is(str);
   208       std::istringstream is(str);
   208       char c;
   209       char c;
   209       while (is.get(c)) {
   210       while (is.get(c)) {
   210 	if (isWhiteSpace(c) || isEscaped(c)) {
   211 	if (isWhiteSpace(c) || isEscaped(c)) {
   211 	  return true;
   212 	  return true;
   229       return os;
   230       return os;
   230     }
   231     }
   231 
   232 
   232   }
   233   }
   233   
   234   
   234   /// \e
   235   /// \ingroup lemon_io
       
   236   ///  
       
   237   /// \brief LGF writer for directed graphs
       
   238   ///
       
   239   /// This utility writes an \ref lgf-format "LGF" file.
       
   240   ///
       
   241   /// The writing method does a batch processing. The user creates a
       
   242   /// writer object, then various writing rules can be added to the
       
   243   /// writer, and eventually the writing is executed with the \c run()
       
   244   /// member function. A map writing rule can be added to the writer
       
   245   /// with the \c nodeMap() or \c arcMap() members. An optional
       
   246   /// converter parameter can also be added as a standard functor converting from
       
   247   /// the value type of the map to std::string. If it is set, it will
       
   248   /// determine how the map's value type is written to the output
       
   249   /// stream. If the functor is not set, then a default conversion
       
   250   /// will be used. The \c attribute(), \c node() and \c arc() functions
       
   251   /// are used to add attribute writing rules.
       
   252   ///
       
   253   ///\code
       
   254   ///     DigraphWriter<Digraph>(std::cout, digraph).
       
   255   ///       nodeMap("coordinates", coord_map).
       
   256   ///       nodeMap("size", size).
       
   257   ///       nodeMap("title", title).
       
   258   ///       arcMap("capacity", cap_map).
       
   259   ///       node("source", src).
       
   260   ///       node("target", trg).
       
   261   ///       attribute("caption", caption).
       
   262   ///       run();
       
   263   ///\endcode
       
   264   ///
       
   265   ///
       
   266   /// By default, the writer does not write additional captions to the
       
   267   /// sections, but they can be give as an optional parameter of
       
   268   /// the \c nodes(), \c arcs() or \c
       
   269   /// attributes() functions.
       
   270   ///
       
   271   /// The \c skipNodes() and \c skipArcs() functions forbid the
       
   272   /// writing of the sections. If two arc sections should be written to the
       
   273   /// output, it can be done in two passes, the first pass writes the
       
   274   /// node section and the first arc section, then the second pass
       
   275   /// skips the node section and writes just the arc section to the
       
   276   /// stream. The output stream can be retrieved with the \c ostream()
       
   277   /// function, hence the second pass can append its output to the output of the
       
   278   /// first pass.
   235   template <typename _Digraph>
   279   template <typename _Digraph>
   236   class DigraphWriter {
   280   class DigraphWriter {
   237   public:
   281   public:
   238 
   282 
   239     typedef _Digraph Digraph;
   283     typedef _Digraph Digraph;
   271     bool _skip_nodes;
   315     bool _skip_nodes;
   272     bool _skip_arcs;
   316     bool _skip_arcs;
   273 
   317 
   274   public:
   318   public:
   275 
   319 
   276     /// \e
   320     /// \brief Constructor
       
   321     ///
       
   322     /// Construct a directed graph writer, which writes to the given
       
   323     /// output stream.
   277     DigraphWriter(std::ostream& is, Digraph& digraph) 
   324     DigraphWriter(std::ostream& is, Digraph& digraph) 
   278       : _os(&is), local_os(false), _digraph(digraph),
   325       : _os(&is), local_os(false), _digraph(digraph),
   279 	_skip_nodes(false), _skip_arcs(false) {}
   326 	_skip_nodes(false), _skip_arcs(false) {}
   280 
   327 
   281     /// \e
   328     /// \brief Constructor
       
   329     ///
       
   330     /// Construct a directed graph writer, which writes to the given
       
   331     /// output file.
   282     DigraphWriter(const std::string& fn, Digraph& digraph) 
   332     DigraphWriter(const std::string& fn, Digraph& digraph) 
   283       : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
   333       : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
   284 	_skip_nodes(false), _skip_arcs(false) {}
   334 	_skip_nodes(false), _skip_arcs(false) {}
   285 
   335 
   286     /// \e
   336     /// \brief Constructor
       
   337     ///
       
   338     /// Construct a directed graph writer, which writes to the given
       
   339     /// output file.
   287     DigraphWriter(const char* fn, Digraph& digraph) 
   340     DigraphWriter(const char* fn, Digraph& digraph) 
   288       : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
   341       : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
   289 	_skip_nodes(false), _skip_arcs(false) {}
   342 	_skip_nodes(false), _skip_arcs(false) {}
   290 
   343 
       
   344     /// \brief Copy constructor
       
   345     ///
       
   346     /// The copy constructor transfers all data from the other writer,
       
   347     /// therefore the copied writer will not be usable more. 
   291     DigraphWriter(DigraphWriter& other) 
   348     DigraphWriter(DigraphWriter& other) 
   292       : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
   349       : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
   293 	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   350 	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   294 
   351 
   295       other.is = 0;
   352       other.is = 0;
   305       _nodes_caption = other._nodes_caption;
   362       _nodes_caption = other._nodes_caption;
   306       _arcs_caption = other._arcs_caption;
   363       _arcs_caption = other._arcs_caption;
   307       _attributes_caption = other._attributes_caption;
   364       _attributes_caption = other._attributes_caption;
   308     }
   365     }
   309 
   366 
   310     /// \e
   367     /// \brief Destructor
   311     ~DigraphWriter() {
   368     ~DigraphWriter() {
   312       for (typename NodeMaps::iterator it = _node_maps.begin(); 
   369       for (typename NodeMaps::iterator it = _node_maps.begin(); 
   313 	   it != _node_maps.end(); ++it) {
   370 	   it != _node_maps.end(); ++it) {
   314 	delete it->second;
   371 	delete it->second;
   315       }
   372       }
   333     
   390     
   334     DigraphWriter& operator=(const DigraphWriter&);
   391     DigraphWriter& operator=(const DigraphWriter&);
   335 
   392 
   336   public:
   393   public:
   337 
   394 
   338     /// \e
   395     /// \name Writing rules
       
   396     /// @{
       
   397     
       
   398     /// \brief Node map reading rule
       
   399     ///
       
   400     /// Add a node map reading rule to the writer.
   339     template <typename Map>
   401     template <typename Map>
   340     DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
   402     DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
   341       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   403       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   342       _writer_bits::MapStorageBase<Node>* storage = 
   404       _writer_bits::MapStorageBase<Node>* storage = 
   343 	new _writer_bits::MapStorage<Node, Map>(map);
   405 	new _writer_bits::MapStorage<Node, Map>(map);
   344       _node_maps.push_back(std::make_pair(caption, storage));
   406       _node_maps.push_back(std::make_pair(caption, storage));
   345       return *this;
   407       return *this;
   346     }
   408     }
   347 
   409 
   348     /// \e
   410     /// \brief Node map writing rule
       
   411     ///
       
   412     /// Add a node map writing rule with specialized converter to the
       
   413     /// writer.
   349     template <typename Map, typename Converter>
   414     template <typename Map, typename Converter>
   350     DigraphWriter& nodeMap(const std::string& caption, const Map& map, 
   415     DigraphWriter& nodeMap(const std::string& caption, const Map& map, 
   351 			   const Converter& converter = Converter()) {
   416 			   const Converter& converter = Converter()) {
   352       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   417       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   353       _writer_bits::MapStorageBase<Node>* storage = 
   418       _writer_bits::MapStorageBase<Node>* storage = 
   354 	new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
   419 	new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
   355       _node_maps.push_back(std::make_pair(caption, storage));
   420       _node_maps.push_back(std::make_pair(caption, storage));
   356       return *this;
   421       return *this;
   357     }
   422     }
   358 
   423 
   359     /// \e
   424     /// \brief Arc map writing rule
       
   425     ///
       
   426     /// Add an arc map writing rule to the writer.
   360     template <typename Map>
   427     template <typename Map>
   361     DigraphWriter& arcMap(const std::string& caption, const Map& map) {
   428     DigraphWriter& arcMap(const std::string& caption, const Map& map) {
   362       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   429       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   363       _writer_bits::MapStorageBase<Arc>* storage = 
   430       _writer_bits::MapStorageBase<Arc>* storage = 
   364 	new _writer_bits::MapStorage<Arc, Map>(map);
   431 	new _writer_bits::MapStorage<Arc, Map>(map);
   365       _arc_maps.push_back(std::make_pair(caption, storage));
   432       _arc_maps.push_back(std::make_pair(caption, storage));
   366       return *this;
   433       return *this;
   367     }
   434     }
   368 
   435 
   369     /// \e
   436     /// \brief Arc map writing rule
       
   437     ///
       
   438     /// Add an arc map writing rule with specialized converter to the
       
   439     /// writer.
   370     template <typename Map, typename Converter>
   440     template <typename Map, typename Converter>
   371     DigraphWriter& arcMap(const std::string& caption, const Map& map, 
   441     DigraphWriter& arcMap(const std::string& caption, const Map& map, 
   372 			  const Converter& converter = Converter()) {
   442 			  const Converter& converter = Converter()) {
   373       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   443       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   374       _writer_bits::MapStorageBase<Arc>* storage = 
   444       _writer_bits::MapStorageBase<Arc>* storage = 
   375 	new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
   445 	new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
   376       _arc_maps.push_back(std::make_pair(caption, storage));
   446       _arc_maps.push_back(std::make_pair(caption, storage));
   377       return *this;
   447       return *this;
   378     }
   448     }
   379 
   449 
   380     /// \e
   450     /// \brief Attribute writing rule
       
   451     ///
       
   452     /// Add an attribute writing rule to the writer.
   381     template <typename Value>
   453     template <typename Value>
   382     DigraphWriter& attribute(const std::string& caption, const Value& value) {
   454     DigraphWriter& attribute(const std::string& caption, const Value& value) {
   383       _writer_bits::ValueStorageBase* storage = 
   455       _writer_bits::ValueStorageBase* storage = 
   384 	new _writer_bits::ValueStorage<Value>(value);
   456 	new _writer_bits::ValueStorage<Value>(value);
   385       _attributes.push_back(std::make_pair(caption, storage));
   457       _attributes.push_back(std::make_pair(caption, storage));
   386       return *this;
   458       return *this;
   387     }
   459     }
   388 
   460 
   389     /// \e
   461     /// \brief Attribute writing rule
       
   462     ///
       
   463     /// Add an attribute writing rule with specialized converter to the
       
   464     /// writer.
   390     template <typename Value, typename Converter>
   465     template <typename Value, typename Converter>
   391     DigraphWriter& attribute(const std::string& caption, const Value& value, 
   466     DigraphWriter& attribute(const std::string& caption, const Value& value, 
   392 			     const Converter& converter = Converter()) {
   467 			     const Converter& converter = Converter()) {
   393       _writer_bits::ValueStorageBase* storage = 
   468       _writer_bits::ValueStorageBase* storage = 
   394 	new _writer_bits::ValueStorage<Value, Converter>(value, converter);
   469 	new _writer_bits::ValueStorage<Value, Converter>(value, converter);
   395       _attributes.push_back(std::make_pair(caption, storage));
   470       _attributes.push_back(std::make_pair(caption, storage));
   396       return *this;
   471       return *this;
   397     }
   472     }
   398 
   473 
   399     /// \e
   474     /// \brief Node writing rule
       
   475     ///
       
   476     /// Add a node writing rule to the writer.
   400     DigraphWriter& node(const std::string& caption, const Node& node) {
   477     DigraphWriter& node(const std::string& caption, const Node& node) {
   401       typedef _writer_bits::MapLookUpConverter<Node> Converter;
   478       typedef _writer_bits::MapLookUpConverter<Node> Converter;
   402       Converter converter(_node_index);
   479       Converter converter(_node_index);
   403       _writer_bits::ValueStorageBase* storage = 
   480       _writer_bits::ValueStorageBase* storage = 
   404 	new _writer_bits::ValueStorage<Node, Converter>(node, converter);
   481 	new _writer_bits::ValueStorage<Node, Converter>(node, converter);
   405       _attributes.push_back(std::make_pair(caption, storage));
   482       _attributes.push_back(std::make_pair(caption, storage));
   406       return *this;
   483       return *this;
   407     }
   484     }
   408 
   485 
   409     /// \e
   486     /// \brief Arc writing rule
       
   487     ///
       
   488     /// Add an arc writing rule to writer.
   410     DigraphWriter& arc(const std::string& caption, const Arc& arc) {
   489     DigraphWriter& arc(const std::string& caption, const Arc& arc) {
   411       typedef _writer_bits::MapLookUpConverter<Arc> Converter;
   490       typedef _writer_bits::MapLookUpConverter<Arc> Converter;
   412       Converter converter(_arc_index);
   491       Converter converter(_arc_index);
   413       _writer_bits::ValueStorageBase* storage = 
   492       _writer_bits::ValueStorageBase* storage = 
   414 	new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
   493 	new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
   415       _attributes.push_back(std::make_pair(caption, storage));
   494       _attributes.push_back(std::make_pair(caption, storage));
   416       return *this;
   495       return *this;
   417     }
   496     }
   418 
   497 
   419     /// \e
   498     /// \name Select section by name
       
   499     /// @{
       
   500 
       
   501     /// \brief Set \c \@nodes section to be read
       
   502     ///
       
   503     /// Set \c \@nodes section to be read
   420     DigraphWriter& nodes(const std::string& caption) {
   504     DigraphWriter& nodes(const std::string& caption) {
   421       _nodes_caption = caption;
   505       _nodes_caption = caption;
   422       return *this;
   506       return *this;
   423     }
   507     }
   424 
   508 
   425     /// \e
   509     /// \brief Set \c \@arcs section to be read
       
   510     ///
       
   511     /// Set \c \@arcs section to be read
   426     DigraphWriter& arcs(const std::string& caption) {
   512     DigraphWriter& arcs(const std::string& caption) {
   427       _arcs_caption = caption;
   513       _arcs_caption = caption;
   428       return *this;
   514       return *this;
   429     }
   515     }
   430 
   516 
   431     /// \e
   517     /// \brief Set \c \@attributes section to be read
       
   518     ///
       
   519     /// Set \c \@attributes section to be read
   432     DigraphWriter& attributes(const std::string& caption) {
   520     DigraphWriter& attributes(const std::string& caption) {
   433       _attributes_caption = caption;
   521       _attributes_caption = caption;
   434       return *this;
   522       return *this;
   435     }
   523     }
   436 
   524 
       
   525     /// \name Skipping section
       
   526     /// @{
       
   527 
       
   528     /// \brief Skip writing the node set
       
   529     ///
       
   530     /// The \c \@nodes section will be not written to the stream.
   437     DigraphWriter& skipNodes() {
   531     DigraphWriter& skipNodes() {
   438       LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
   532       LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
   439       return *this;
   533       return *this;
   440     }
   534     }
   441 
   535 
       
   536     /// \brief Skip writing arc set
       
   537     ///
       
   538     /// The \c \@arcs section will be not written to the stream.
   442     DigraphWriter& skipArcs() {
   539     DigraphWriter& skipArcs() {
   443       LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
   540       LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
   444       return *this;
   541       return *this;
   445     }
   542     }
       
   543 
       
   544     /// @}
   446 
   545 
   447   private:
   546   private:
   448 
   547 
   449     void writeNodes() {
   548     void writeNodes() {
   450       _writer_bits::MapStorageBase<Node>* label = 0;
   549       _writer_bits::MapStorageBase<Node>* label = 0;
   456 	}
   555 	}
   457       }
   556       }
   458 
   557 
   459       *_os << "@nodes";
   558       *_os << "@nodes";
   460       if (!_nodes_caption.empty()) {
   559       if (!_nodes_caption.empty()) {
   461 	*_os << ' ' << _nodes_caption;
   560 	_writer_bits::writeToken(*_os << ' ', _nodes_caption);
   462       }
   561       }
   463       *_os << std::endl;
   562       *_os << std::endl;
   464 
   563 
   465       if (label == 0) {
   564       if (label == 0) {
   466 	*_os << "label" << '\t';
   565 	*_os << "label" << '\t';
   467       }
   566       }
   468       for (typename NodeMaps::iterator it = _node_maps.begin();
   567       for (typename NodeMaps::iterator it = _node_maps.begin();
   469 	   it != _node_maps.end(); ++it) {
   568 	   it != _node_maps.end(); ++it) {
   470 	*_os << it->first << '\t';
   569 	_writer_bits::writeToken(*_os, it->first) << '\t';
   471       }
   570       }
   472       *_os << std::endl;
   571       *_os << std::endl;
   473 
   572 
   474       std::vector<Node> nodes;
   573       std::vector<Node> nodes;
   475       for (NodeIt n(_digraph); n != INVALID; ++n) {
   574       for (NodeIt n(_digraph); n != INVALID; ++n) {
   516 	}
   615 	}
   517       }
   616       }
   518 
   617 
   519       *_os << "@arcs";
   618       *_os << "@arcs";
   520       if (!_arcs_caption.empty()) {
   619       if (!_arcs_caption.empty()) {
   521 	*_os << ' ' << _arcs_caption;
   620 	_writer_bits::writeToken(*_os << ' ', _arcs_caption);
   522       }
   621       }
   523       *_os << std::endl;
   622       *_os << std::endl;
   524 
   623 
   525       *_os << '\t' << '\t';
   624       *_os << '\t' << '\t';
   526       if (label == 0) {
   625       if (label == 0) {
   527 	*_os << "label" << '\t';
   626 	*_os << "label" << '\t';
   528       }
   627       }
   529       for (typename ArcMaps::iterator it = _arc_maps.begin();
   628       for (typename ArcMaps::iterator it = _arc_maps.begin();
   530 	   it != _arc_maps.end(); ++it) {
   629 	   it != _arc_maps.end(); ++it) {
   531 	*_os << it->first << '\t';
   630 	_writer_bits::writeToken(*_os, it->first) << '\t';
   532       }
   631       }
   533       *_os << std::endl;
   632       *_os << std::endl;
   534 
   633 
   535       std::vector<Arc> arcs;
   634       std::vector<Arc> arcs;
   536       for (ArcIt n(_digraph); n != INVALID; ++n) {
   635       for (ArcIt n(_digraph); n != INVALID; ++n) {
   575 
   674 
   576     void writeAttributes() {
   675     void writeAttributes() {
   577       if (_attributes.empty()) return;
   676       if (_attributes.empty()) return;
   578       *_os << "@attributes";
   677       *_os << "@attributes";
   579       if (!_attributes_caption.empty()) {
   678       if (!_attributes_caption.empty()) {
   580 	*_os << ' ' << _attributes_caption;
   679 	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
   581       }
   680       }
   582       *_os << std::endl;
   681       *_os << std::endl;
   583       for (typename Attributes::iterator it = _attributes.begin();
   682       for (typename Attributes::iterator it = _attributes.begin();
   584 	   it != _attributes.end(); ++it) {
   683 	   it != _attributes.end(); ++it) {
   585 	*_os << it->first << ' ';
   684 	_writer_bits::writeToken(*_os, it->first) << ' ';
   586 	_writer_bits::writeToken(*_os, it->second->get());
   685 	_writer_bits::writeToken(*_os, it->second->get());
   587 	*_os << std::endl;
   686 	*_os << std::endl;
   588       }
   687       }
   589     }
   688     }
   590     
   689     
   591   public:
   690   public:
   592     
   691     
   593     /// \e
   692     /// \name Execution of the writer    
       
   693     /// @{
       
   694 
       
   695     /// \brief Start the batch processing
       
   696     ///
       
   697     /// This function starts the batch processing
   594     void run() {
   698     void run() {
   595       if (!_skip_nodes) {
   699       if (!_skip_nodes) {
   596 	writeNodes();
   700 	writeNodes();
   597       }
   701       }
   598       if (!_skip_arcs) {      
   702       if (!_skip_arcs) {      
   599 	writeArcs();
   703 	writeArcs();
   600       }
   704       }
   601       writeAttributes();
   705       writeAttributes();
   602     }
   706     }
   603 
   707 
   604     /// \e
   708     /// \brief Gives back the stream of the writer
   605     std::ostream& stream() {
   709     ///
       
   710     /// Gives back the stream of the writer
       
   711     std::ostream& ostream() {
   606       return *_os;
   712       return *_os;
   607     }
   713     }
       
   714 
       
   715     /// @}
   608   };
   716   };
   609 
   717 
       
   718   /// \relates DigraphWriter
   610   template <typename Digraph>
   719   template <typename Digraph>
   611   DigraphWriter<Digraph> digraphWriter(std::istream& is, Digraph& digraph) {
   720   DigraphWriter<Digraph> digraphWriter(std::istream& is, Digraph& digraph) {
   612     return DigraphWriter<Digraph>(is, digraph);
   721     return DigraphWriter<Digraph>(is, digraph);
   613   }
   722   }
   614 
   723 
       
   724   /// \relates DigraphWriter
   615   template <typename Digraph>
   725   template <typename Digraph>
   616   DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
   726   DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
   617 				       Digraph& digraph) {
   727 				       Digraph& digraph) {
   618     return DigraphWriter<Digraph>(fn, digraph);
   728     return DigraphWriter<Digraph>(fn, digraph);
   619   }
   729   }
   620 
   730 
       
   731   /// \relates DigraphWriter
   621   template <typename Digraph>
   732   template <typename Digraph>
   622   DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
   733   DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
   623     return DigraphWriter<Digraph>(fn, digraph);
   734     return DigraphWriter<Digraph>(fn, digraph);
   624   }
   735   }
   625 }
   736 }