lemon/lgf_writer.h
changeset 156 e561aa7675de
parent 148 4e2581021300
child 163 c82fd9568d75
     1.1 --- a/lemon/lgf_writer.h	Mon May 05 11:41:30 2008 +0200
     1.2 +++ b/lemon/lgf_writer.h	Sat May 17 06:30:02 2008 +0100
     1.3 @@ -204,6 +204,7 @@
     1.4      }
     1.5  
     1.6      bool requireEscape(const std::string& str) {
     1.7 +      if (str.empty() || str[0] == '@') return true;
     1.8        std::istringstream is(str);
     1.9        char c;
    1.10        while (is.get(c)) {
    1.11 @@ -231,7 +232,50 @@
    1.12  
    1.13    }
    1.14    
    1.15 -  /// \e
    1.16 +  /// \ingroup lemon_io
    1.17 +  ///  
    1.18 +  /// \brief LGF writer for directed graphs
    1.19 +  ///
    1.20 +  /// This utility writes an \ref lgf-format "LGF" file.
    1.21 +  ///
    1.22 +  /// The writing method does a batch processing. The user creates a
    1.23 +  /// writer object, then various writing rules can be added to the
    1.24 +  /// writer, and eventually the writing is executed with the \c run()
    1.25 +  /// member function. A map writing rule can be added to the writer
    1.26 +  /// with the \c nodeMap() or \c arcMap() members. An optional
    1.27 +  /// converter parameter can also be added as a standard functor converting from
    1.28 +  /// the value type of the map to std::string. If it is set, it will
    1.29 +  /// determine how the map's value type is written to the output
    1.30 +  /// stream. If the functor is not set, then a default conversion
    1.31 +  /// will be used. The \c attribute(), \c node() and \c arc() functions
    1.32 +  /// are used to add attribute writing rules.
    1.33 +  ///
    1.34 +  ///\code
    1.35 +  ///     DigraphWriter<Digraph>(std::cout, digraph).
    1.36 +  ///       nodeMap("coordinates", coord_map).
    1.37 +  ///       nodeMap("size", size).
    1.38 +  ///       nodeMap("title", title).
    1.39 +  ///       arcMap("capacity", cap_map).
    1.40 +  ///       node("source", src).
    1.41 +  ///       node("target", trg).
    1.42 +  ///       attribute("caption", caption).
    1.43 +  ///       run();
    1.44 +  ///\endcode
    1.45 +  ///
    1.46 +  ///
    1.47 +  /// By default, the writer does not write additional captions to the
    1.48 +  /// sections, but they can be give as an optional parameter of
    1.49 +  /// the \c nodes(), \c arcs() or \c
    1.50 +  /// attributes() functions.
    1.51 +  ///
    1.52 +  /// The \c skipNodes() and \c skipArcs() functions forbid the
    1.53 +  /// writing of the sections. If two arc sections should be written to the
    1.54 +  /// output, it can be done in two passes, the first pass writes the
    1.55 +  /// node section and the first arc section, then the second pass
    1.56 +  /// skips the node section and writes just the arc section to the
    1.57 +  /// stream. The output stream can be retrieved with the \c ostream()
    1.58 +  /// function, hence the second pass can append its output to the output of the
    1.59 +  /// first pass.
    1.60    template <typename _Digraph>
    1.61    class DigraphWriter {
    1.62    public:
    1.63 @@ -273,21 +317,34 @@
    1.64  
    1.65    public:
    1.66  
    1.67 -    /// \e
    1.68 +    /// \brief Constructor
    1.69 +    ///
    1.70 +    /// Construct a directed graph writer, which writes to the given
    1.71 +    /// output stream.
    1.72      DigraphWriter(std::ostream& is, Digraph& digraph) 
    1.73        : _os(&is), local_os(false), _digraph(digraph),
    1.74  	_skip_nodes(false), _skip_arcs(false) {}
    1.75  
    1.76 -    /// \e
    1.77 +    /// \brief Constructor
    1.78 +    ///
    1.79 +    /// Construct a directed graph writer, which writes to the given
    1.80 +    /// output file.
    1.81      DigraphWriter(const std::string& fn, Digraph& digraph) 
    1.82        : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
    1.83  	_skip_nodes(false), _skip_arcs(false) {}
    1.84  
    1.85 -    /// \e
    1.86 +    /// \brief Constructor
    1.87 +    ///
    1.88 +    /// Construct a directed graph writer, which writes to the given
    1.89 +    /// output file.
    1.90      DigraphWriter(const char* fn, Digraph& digraph) 
    1.91        : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
    1.92  	_skip_nodes(false), _skip_arcs(false) {}
    1.93  
    1.94 +    /// \brief Copy constructor
    1.95 +    ///
    1.96 +    /// The copy constructor transfers all data from the other writer,
    1.97 +    /// therefore the copied writer will not be usable more. 
    1.98      DigraphWriter(DigraphWriter& other) 
    1.99        : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
   1.100  	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   1.101 @@ -307,7 +364,7 @@
   1.102        _attributes_caption = other._attributes_caption;
   1.103      }
   1.104  
   1.105 -    /// \e
   1.106 +    /// \brief Destructor
   1.107      ~DigraphWriter() {
   1.108        for (typename NodeMaps::iterator it = _node_maps.begin(); 
   1.109  	   it != _node_maps.end(); ++it) {
   1.110 @@ -335,7 +392,12 @@
   1.111  
   1.112    public:
   1.113  
   1.114 -    /// \e
   1.115 +    /// \name Writing rules
   1.116 +    /// @{
   1.117 +    
   1.118 +    /// \brief Node map reading rule
   1.119 +    ///
   1.120 +    /// Add a node map reading rule to the writer.
   1.121      template <typename Map>
   1.122      DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
   1.123        checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   1.124 @@ -345,7 +407,10 @@
   1.125        return *this;
   1.126      }
   1.127  
   1.128 -    /// \e
   1.129 +    /// \brief Node map writing rule
   1.130 +    ///
   1.131 +    /// Add a node map writing rule with specialized converter to the
   1.132 +    /// writer.
   1.133      template <typename Map, typename Converter>
   1.134      DigraphWriter& nodeMap(const std::string& caption, const Map& map, 
   1.135  			   const Converter& converter = Converter()) {
   1.136 @@ -356,7 +421,9 @@
   1.137        return *this;
   1.138      }
   1.139  
   1.140 -    /// \e
   1.141 +    /// \brief Arc map writing rule
   1.142 +    ///
   1.143 +    /// Add an arc map writing rule to the writer.
   1.144      template <typename Map>
   1.145      DigraphWriter& arcMap(const std::string& caption, const Map& map) {
   1.146        checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   1.147 @@ -366,7 +433,10 @@
   1.148        return *this;
   1.149      }
   1.150  
   1.151 -    /// \e
   1.152 +    /// \brief Arc map writing rule
   1.153 +    ///
   1.154 +    /// Add an arc map writing rule with specialized converter to the
   1.155 +    /// writer.
   1.156      template <typename Map, typename Converter>
   1.157      DigraphWriter& arcMap(const std::string& caption, const Map& map, 
   1.158  			  const Converter& converter = Converter()) {
   1.159 @@ -377,7 +447,9 @@
   1.160        return *this;
   1.161      }
   1.162  
   1.163 -    /// \e
   1.164 +    /// \brief Attribute writing rule
   1.165 +    ///
   1.166 +    /// Add an attribute writing rule to the writer.
   1.167      template <typename Value>
   1.168      DigraphWriter& attribute(const std::string& caption, const Value& value) {
   1.169        _writer_bits::ValueStorageBase* storage = 
   1.170 @@ -386,7 +458,10 @@
   1.171        return *this;
   1.172      }
   1.173  
   1.174 -    /// \e
   1.175 +    /// \brief Attribute writing rule
   1.176 +    ///
   1.177 +    /// Add an attribute writing rule with specialized converter to the
   1.178 +    /// writer.
   1.179      template <typename Value, typename Converter>
   1.180      DigraphWriter& attribute(const std::string& caption, const Value& value, 
   1.181  			     const Converter& converter = Converter()) {
   1.182 @@ -396,7 +471,9 @@
   1.183        return *this;
   1.184      }
   1.185  
   1.186 -    /// \e
   1.187 +    /// \brief Node writing rule
   1.188 +    ///
   1.189 +    /// Add a node writing rule to the writer.
   1.190      DigraphWriter& node(const std::string& caption, const Node& node) {
   1.191        typedef _writer_bits::MapLookUpConverter<Node> Converter;
   1.192        Converter converter(_node_index);
   1.193 @@ -406,7 +483,9 @@
   1.194        return *this;
   1.195      }
   1.196  
   1.197 -    /// \e
   1.198 +    /// \brief Arc writing rule
   1.199 +    ///
   1.200 +    /// Add an arc writing rule to writer.
   1.201      DigraphWriter& arc(const std::string& caption, const Arc& arc) {
   1.202        typedef _writer_bits::MapLookUpConverter<Arc> Converter;
   1.203        Converter converter(_arc_index);
   1.204 @@ -416,34 +495,54 @@
   1.205        return *this;
   1.206      }
   1.207  
   1.208 -    /// \e
   1.209 +    /// \name Select section by name
   1.210 +    /// @{
   1.211 +
   1.212 +    /// \brief Set \c \@nodes section to be read
   1.213 +    ///
   1.214 +    /// Set \c \@nodes section to be read
   1.215      DigraphWriter& nodes(const std::string& caption) {
   1.216        _nodes_caption = caption;
   1.217        return *this;
   1.218      }
   1.219  
   1.220 -    /// \e
   1.221 +    /// \brief Set \c \@arcs section to be read
   1.222 +    ///
   1.223 +    /// Set \c \@arcs section to be read
   1.224      DigraphWriter& arcs(const std::string& caption) {
   1.225        _arcs_caption = caption;
   1.226        return *this;
   1.227      }
   1.228  
   1.229 -    /// \e
   1.230 +    /// \brief Set \c \@attributes section to be read
   1.231 +    ///
   1.232 +    /// Set \c \@attributes section to be read
   1.233      DigraphWriter& attributes(const std::string& caption) {
   1.234        _attributes_caption = caption;
   1.235        return *this;
   1.236      }
   1.237  
   1.238 +    /// \name Skipping section
   1.239 +    /// @{
   1.240 +
   1.241 +    /// \brief Skip writing the node set
   1.242 +    ///
   1.243 +    /// The \c \@nodes section will be not written to the stream.
   1.244      DigraphWriter& skipNodes() {
   1.245        LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
   1.246        return *this;
   1.247      }
   1.248  
   1.249 +    /// \brief Skip writing arc set
   1.250 +    ///
   1.251 +    /// The \c \@arcs section will be not written to the stream.
   1.252      DigraphWriter& skipArcs() {
   1.253        LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
   1.254        return *this;
   1.255      }
   1.256  
   1.257 +    /// @}
   1.258 +
   1.259    private:
   1.260  
   1.261      void writeNodes() {
   1.262 @@ -458,7 +557,7 @@
   1.263  
   1.264        *_os << "@nodes";
   1.265        if (!_nodes_caption.empty()) {
   1.266 -	*_os << ' ' << _nodes_caption;
   1.267 +	_writer_bits::writeToken(*_os << ' ', _nodes_caption);
   1.268        }
   1.269        *_os << std::endl;
   1.270  
   1.271 @@ -467,7 +566,7 @@
   1.272        }
   1.273        for (typename NodeMaps::iterator it = _node_maps.begin();
   1.274  	   it != _node_maps.end(); ++it) {
   1.275 -	*_os << it->first << '\t';
   1.276 +	_writer_bits::writeToken(*_os, it->first) << '\t';
   1.277        }
   1.278        *_os << std::endl;
   1.279  
   1.280 @@ -518,7 +617,7 @@
   1.281  
   1.282        *_os << "@arcs";
   1.283        if (!_arcs_caption.empty()) {
   1.284 -	*_os << ' ' << _arcs_caption;
   1.285 +	_writer_bits::writeToken(*_os << ' ', _arcs_caption);
   1.286        }
   1.287        *_os << std::endl;
   1.288  
   1.289 @@ -528,7 +627,7 @@
   1.290        }
   1.291        for (typename ArcMaps::iterator it = _arc_maps.begin();
   1.292  	   it != _arc_maps.end(); ++it) {
   1.293 -	*_os << it->first << '\t';
   1.294 +	_writer_bits::writeToken(*_os, it->first) << '\t';
   1.295        }
   1.296        *_os << std::endl;
   1.297  
   1.298 @@ -577,12 +676,12 @@
   1.299        if (_attributes.empty()) return;
   1.300        *_os << "@attributes";
   1.301        if (!_attributes_caption.empty()) {
   1.302 -	*_os << ' ' << _attributes_caption;
   1.303 +	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
   1.304        }
   1.305        *_os << std::endl;
   1.306        for (typename Attributes::iterator it = _attributes.begin();
   1.307  	   it != _attributes.end(); ++it) {
   1.308 -	*_os << it->first << ' ';
   1.309 +	_writer_bits::writeToken(*_os, it->first) << ' ';
   1.310  	_writer_bits::writeToken(*_os, it->second->get());
   1.311  	*_os << std::endl;
   1.312        }
   1.313 @@ -590,7 +689,12 @@
   1.314      
   1.315    public:
   1.316      
   1.317 -    /// \e
   1.318 +    /// \name Execution of the writer    
   1.319 +    /// @{
   1.320 +
   1.321 +    /// \brief Start the batch processing
   1.322 +    ///
   1.323 +    /// This function starts the batch processing
   1.324      void run() {
   1.325        if (!_skip_nodes) {
   1.326  	writeNodes();
   1.327 @@ -601,23 +705,30 @@
   1.328        writeAttributes();
   1.329      }
   1.330  
   1.331 -    /// \e
   1.332 -    std::ostream& stream() {
   1.333 +    /// \brief Gives back the stream of the writer
   1.334 +    ///
   1.335 +    /// Gives back the stream of the writer
   1.336 +    std::ostream& ostream() {
   1.337        return *_os;
   1.338      }
   1.339 +
   1.340 +    /// @}
   1.341    };
   1.342  
   1.343 +  /// \relates DigraphWriter
   1.344    template <typename Digraph>
   1.345    DigraphWriter<Digraph> digraphWriter(std::istream& is, Digraph& digraph) {
   1.346      return DigraphWriter<Digraph>(is, digraph);
   1.347    }
   1.348  
   1.349 +  /// \relates DigraphWriter
   1.350    template <typename Digraph>
   1.351    DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
   1.352  				       Digraph& digraph) {
   1.353      return DigraphWriter<Digraph>(fn, digraph);
   1.354    }
   1.355  
   1.356 +  /// \relates DigraphWriter
   1.357    template <typename Digraph>
   1.358    DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
   1.359      return DigraphWriter<Digraph>(fn, digraph);