lemon/lgf_reader.h
changeset 156 e561aa7675de
parent 148 4e2581021300
child 162 33247f6fff16
     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);