1.1 --- a/lemon/lgf_reader.h Mon May 05 11:41:30 2008 +0200
1.2 +++ b/lemon/lgf_reader.h Sat May 17 06:30:02 2008 +0100
1.3 @@ -268,35 +268,58 @@
1.4 str = os.str();
1.5 return is;
1.6 }
1.7 -
1.8 - std::istream& readIdentifier(std::istream& is, std::string& str) {
1.9 - std::ostringstream os;
1.10 -
1.11 - char c;
1.12 - is >> std::ws;
1.13 -
1.14 - if (!is.get(c))
1.15 - return is;
1.16 -
1.17 - if (!isIdentifierFirstChar(c))
1.18 - throw DataFormatError("Wrong char in identifier");
1.19 -
1.20 - os << c;
1.21 -
1.22 - while (is.get(c) && !isWhiteSpace(c)) {
1.23 - if (!isIdentifierChar(c))
1.24 - throw DataFormatError("Wrong char in identifier");
1.25 - os << c;
1.26 - }
1.27 - if (!is) is.clear();
1.28 -
1.29 - str = os.str();
1.30 - return is;
1.31 - }
1.32
1.33 }
1.34 -
1.35 - /// \e
1.36 +
1.37 + /// \ingroup lemon_io
1.38 + ///
1.39 + /// \brief LGF reader for directed graphs
1.40 + ///
1.41 + /// This utility reads an \ref lgf-format "LGF" file.
1.42 + ///
1.43 + /// The reading method does a batch processing. The user creates a
1.44 + /// reader object, then various reading rules can be added to the
1.45 + /// reader, and eventually the reading is executed with the \c run()
1.46 + /// member function. A map reading rule can be added to the reader
1.47 + /// with the \c nodeMap() or \c arcMap() members. An optional
1.48 + /// converter parameter can also be added as a standard functor converting from
1.49 + /// std::string to the value type of the map. If it is set, it will
1.50 + /// determine how the tokens in the file should be is converted to the map's
1.51 + /// value type. If the functor is not set, then a default conversion
1.52 + /// will be used. One map can be read into multiple map objects at the
1.53 + /// same time. The \c attribute(), \c node() and \c arc() functions
1.54 + /// are used to add attribute reading rules.
1.55 + ///
1.56 + ///\code
1.57 + /// DigraphReader<Digraph>(std::cin, digraph).
1.58 + /// nodeMap("coordinates", coord_map).
1.59 + /// arcMap("capacity", cap_map).
1.60 + /// node("source", src).
1.61 + /// node("target", trg).
1.62 + /// attribute("caption", caption).
1.63 + /// run();
1.64 + ///\endcode
1.65 + ///
1.66 + /// By default the reader uses the first section in the file of the
1.67 + /// proper type. If a section has an optional name, then it can be
1.68 + /// selected for reading by giving an optional name parameter to
1.69 + /// the \c nodes(), \c arcs() or \c attributes()
1.70 + /// functions.
1.71 + ///
1.72 + /// The \c useNodes() and \c useArcs() functions are used to tell the reader
1.73 + /// that the nodes or arcs should not be constructed (added to the
1.74 + /// graph) during the reading, but instead the label map of the items
1.75 + /// are given as a parameter of these functions. An
1.76 + /// application of these function is multipass reading, which is
1.77 + /// important if two \e \@arcs sections must be read from the
1.78 + /// file. In this example the first phase would read the node set and one
1.79 + /// of the arc sets, while the second phase would read the second arc
1.80 + /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
1.81 + /// The previously read label node map should be passed to the \c
1.82 + /// useNodes() functions. Another application of multipass reading when
1.83 + /// paths are given as a node map or an arc map. It is impossible read this in
1.84 + /// a single pass, because the arcs are not constructed when the node
1.85 + /// maps are read.
1.86 template <typename _Digraph>
1.87 class DigraphReader {
1.88 public:
1.89 @@ -341,23 +364,34 @@
1.90
1.91 public:
1.92
1.93 - /// \e
1.94 + /// \brief Constructor
1.95 + ///
1.96 + /// Construct a directed graph reader, which reads from the given
1.97 + /// input stream.
1.98 DigraphReader(std::istream& is, Digraph& digraph)
1.99 : _is(&is), local_is(false), _digraph(digraph),
1.100 _use_nodes(false), _use_arcs(false) {}
1.101
1.102 - /// \e
1.103 + /// \brief Constructor
1.104 + ///
1.105 + /// Construct a directed graph reader, which reads from the given
1.106 + /// file.
1.107 DigraphReader(const std::string& fn, Digraph& digraph)
1.108 : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
1.109 _use_nodes(false), _use_arcs(false) {}
1.110 -
1.111 -
1.112 - /// \e
1.113 +
1.114 + /// \brief Constructor
1.115 + ///
1.116 + /// Construct a directed graph reader, which reads from the given
1.117 + /// file.
1.118 DigraphReader(const char* fn, Digraph& digraph)
1.119 : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
1.120 _use_nodes(false), _use_arcs(false) {}
1.121
1.122 - /// \e
1.123 + /// \brief Copy constructor
1.124 + ///
1.125 + /// The copy constructor transfers all data from the other reader,
1.126 + /// therefore the copied reader will not be usable more.
1.127 DigraphReader(DigraphReader& other)
1.128 : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
1.129 _use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
1.130 @@ -377,7 +411,7 @@
1.131 _attributes_caption = other._attributes_caption;
1.132 }
1.133
1.134 - /// \e
1.135 + /// \brief Destructor
1.136 ~DigraphReader() {
1.137 for (typename NodeMaps::iterator it = _node_maps.begin();
1.138 it != _node_maps.end(); ++it) {
1.139 @@ -406,7 +440,12 @@
1.140
1.141 public:
1.142
1.143 - /// \e
1.144 + /// \name Reading rules
1.145 + /// @{
1.146 +
1.147 + /// \brief Node map reading rule
1.148 + ///
1.149 + /// Add a node map reading rule to the reader.
1.150 template <typename Map>
1.151 DigraphReader& nodeMap(const std::string& caption, Map& map) {
1.152 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.153 @@ -416,7 +455,10 @@
1.154 return *this;
1.155 }
1.156
1.157 - /// \e
1.158 + /// \brief Node map reading rule
1.159 + ///
1.160 + /// Add a node map reading rule with specialized converter to the
1.161 + /// reader.
1.162 template <typename Map, typename Converter>
1.163 DigraphReader& nodeMap(const std::string& caption, Map& map,
1.164 const Converter& converter = Converter()) {
1.165 @@ -427,7 +469,9 @@
1.166 return *this;
1.167 }
1.168
1.169 - /// \e
1.170 + /// \brief Arc map reading rule
1.171 + ///
1.172 + /// Add an arc map reading rule to the reader.
1.173 template <typename Map>
1.174 DigraphReader& arcMap(const std::string& caption, Map& map) {
1.175 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1.176 @@ -437,7 +481,10 @@
1.177 return *this;
1.178 }
1.179
1.180 - /// \e
1.181 + /// \brief Arc map reading rule
1.182 + ///
1.183 + /// Add an arc map reading rule with specialized converter to the
1.184 + /// reader.
1.185 template <typename Map, typename Converter>
1.186 DigraphReader& arcMap(const std::string& caption, Map& map,
1.187 const Converter& converter = Converter()) {
1.188 @@ -448,7 +495,9 @@
1.189 return *this;
1.190 }
1.191
1.192 - /// \e
1.193 + /// \brief Attribute reading rule
1.194 + ///
1.195 + /// Add an attribute reading rule to the reader.
1.196 template <typename Value>
1.197 DigraphReader& attribute(const std::string& caption, Value& value) {
1.198 _reader_bits::ValueStorageBase* storage =
1.199 @@ -457,7 +506,10 @@
1.200 return *this;
1.201 }
1.202
1.203 - /// \e
1.204 + /// \brief Attribute reading rule
1.205 + ///
1.206 + /// Add an attribute reading rule with specialized converter to the
1.207 + /// reader.
1.208 template <typename Value, typename Converter>
1.209 DigraphReader& attribute(const std::string& caption, Value& value,
1.210 const Converter& converter = Converter()) {
1.211 @@ -467,7 +519,9 @@
1.212 return *this;
1.213 }
1.214
1.215 - /// \e
1.216 + /// \brief Node reading rule
1.217 + ///
1.218 + /// Add a node reading rule to reader.
1.219 DigraphReader& node(const std::string& caption, Node& node) {
1.220 typedef _reader_bits::MapLookUpConverter<Node> Converter;
1.221 Converter converter(_node_index);
1.222 @@ -477,7 +531,9 @@
1.223 return *this;
1.224 }
1.225
1.226 - /// \e
1.227 + /// \brief Arc reading rule
1.228 + ///
1.229 + /// Add an arc reading rule to reader.
1.230 DigraphReader& arc(const std::string& caption, Arc& arc) {
1.231 typedef _reader_bits::MapLookUpConverter<Arc> Converter;
1.232 Converter converter(_arc_index);
1.233 @@ -487,25 +543,44 @@
1.234 return *this;
1.235 }
1.236
1.237 - /// \e
1.238 + /// @}
1.239 +
1.240 + /// \name Select section by name
1.241 + /// @{
1.242 +
1.243 + /// \brief Set \c \@nodes section to be read
1.244 + ///
1.245 + /// Set \c \@nodes section to be read
1.246 DigraphReader& nodes(const std::string& caption) {
1.247 _nodes_caption = caption;
1.248 return *this;
1.249 }
1.250
1.251 - /// \e
1.252 + /// \brief Set \c \@arcs section to be read
1.253 + ///
1.254 + /// Set \c \@arcs section to be read
1.255 DigraphReader& arcs(const std::string& caption) {
1.256 _arcs_caption = caption;
1.257 return *this;
1.258 }
1.259
1.260 - /// \e
1.261 + /// \brief Set \c \@attributes section to be read
1.262 + ///
1.263 + /// Set \c \@attributes section to be read
1.264 DigraphReader& attributes(const std::string& caption) {
1.265 _attributes_caption = caption;
1.266 return *this;
1.267 }
1.268
1.269 - /// \e
1.270 + /// @}
1.271 +
1.272 + /// \name Using previously constructed node or arc set
1.273 + /// @{
1.274 +
1.275 + /// \brief Use previously constructed node set
1.276 + ///
1.277 + /// Use previously constructed node set, and specify the node
1.278 + /// label map.
1.279 template <typename Map>
1.280 DigraphReader& useNodes(const Map& map) {
1.281 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1.282 @@ -518,7 +593,11 @@
1.283 return *this;
1.284 }
1.285
1.286 - /// \e
1.287 + /// \brief Use previously constructed node set
1.288 + ///
1.289 + /// Use previously constructed node set, and specify the node
1.290 + /// label map and a functor which converts the label map values to
1.291 + /// std::string.
1.292 template <typename Map, typename Converter>
1.293 DigraphReader& useNodes(const Map& map,
1.294 const Converter& converter = Converter()) {
1.295 @@ -531,7 +610,10 @@
1.296 return *this;
1.297 }
1.298
1.299 - /// \e
1.300 + /// \brief Use previously constructed arc set
1.301 + ///
1.302 + /// Use previously constructed arc set, and specify the arc
1.303 + /// label map.
1.304 template <typename Map>
1.305 DigraphReader& useArcs(const Map& map) {
1.306 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1.307 @@ -544,7 +626,11 @@
1.308 return *this;
1.309 }
1.310
1.311 - /// \e
1.312 + /// \brief Use previously constructed arc set
1.313 + ///
1.314 + /// Use previously constructed arc set, and specify the arc
1.315 + /// label map and a functor which converts the label map values to
1.316 + /// std::string.
1.317 template <typename Map, typename Converter>
1.318 DigraphReader& useArcs(const Map& map,
1.319 const Converter& converter = Converter()) {
1.320 @@ -557,6 +643,8 @@
1.321 return *this;
1.322 }
1.323
1.324 + /// @}
1.325 +
1.326 private:
1.327
1.328 bool readLine() {
1.329 @@ -597,7 +685,7 @@
1.330
1.331 std::string map;
1.332 int index = 0;
1.333 - while (_reader_bits::readIdentifier(line, map)) {
1.334 + while (_reader_bits::readToken(line, map)) {
1.335 if (maps.find(map) != maps.end()) {
1.336 std::ostringstream msg;
1.337 msg << "Multiple occurence of node map: " << map;
1.338 @@ -680,7 +768,7 @@
1.339
1.340 std::string map;
1.341 int index = 0;
1.342 - while (_reader_bits::readIdentifier(line, map)) {
1.343 + while (_reader_bits::readToken(line, map)) {
1.344 if (maps.find(map) != maps.end()) {
1.345 std::ostringstream msg;
1.346 msg << "Multiple occurence of arc map: " << map;
1.347 @@ -787,7 +875,7 @@
1.348 line.putback(c);
1.349
1.350 std::string attr, token;
1.351 - if (!_reader_bits::readIdentifier(line, attr))
1.352 + if (!_reader_bits::readToken(line, attr))
1.353 throw DataFormatError("Attribute name not found");
1.354 if (!_reader_bits::readToken(line, token))
1.355 throw DataFormatError("Attribute value not found");
1.356 @@ -827,8 +915,13 @@
1.357 }
1.358
1.359 public:
1.360 -
1.361 - /// \e
1.362 +
1.363 + /// \name Execution of the reader
1.364 + /// @{
1.365 +
1.366 + /// \brief Start the batch processing
1.367 + ///
1.368 + /// This function starts the batch processing
1.369 void run() {
1.370
1.371 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1.372 @@ -846,8 +939,8 @@
1.373 char c;
1.374 std::string section, caption;
1.375 line >> c;
1.376 - _reader_bits::readIdentifier(line, section);
1.377 - _reader_bits::readIdentifier(line, caption);
1.378 + _reader_bits::readToken(line, section);
1.379 + _reader_bits::readToken(line, caption);
1.380
1.381 if (line >> c)
1.382 throw DataFormatError("Extra character on the end of line");
1.383 @@ -891,20 +984,25 @@
1.384 }
1.385
1.386 }
1.387 +
1.388 + /// @}
1.389
1.390 };
1.391
1.392 + /// \relates DigraphReader
1.393 template <typename Digraph>
1.394 DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1.395 return DigraphReader<Digraph>(is, digraph);
1.396 }
1.397
1.398 + /// \relates DigraphReader
1.399 template <typename Digraph>
1.400 DigraphReader<Digraph> digraphReader(const std::string& fn,
1.401 Digraph& digraph) {
1.402 return DigraphReader<Digraph>(fn, digraph);
1.403 }
1.404
1.405 + /// \relates DigraphReader
1.406 template <typename Digraph>
1.407 DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1.408 return DigraphReader<Digraph>(fn, digraph);