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);