lemon/lgf_reader.h
changeset 784 1a7fe3bef514
parent 598 a3402913cffe
parent 584 33c6b6e755cd
child 786 e20173729589
child 937 17e36e175725
     1.1 --- a/lemon/lgf_reader.h	Fri Oct 16 10:21:37 2009 +0200
     1.2 +++ b/lemon/lgf_reader.h	Thu Nov 05 15:50:01 2009 +0100
     1.3 @@ -2,7 +2,7 @@
     1.4   *
     1.5   * This file is a part of LEMON, a generic C++ optimization library.
     1.6   *
     1.7 - * Copyright (C) 2003-2008
     1.8 + * Copyright (C) 2003-2009
     1.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    1.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
    1.11   *
    1.12 @@ -101,23 +101,23 @@
    1.13        }
    1.14      };
    1.15  
    1.16 -    template <typename _Graph, bool _dir, typename _Map,
    1.17 +    template <typename _GR, bool _dir, typename _Map,
    1.18                typename _Converter = DefaultConverter<typename _Map::Value> >
    1.19 -    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
    1.20 +    class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
    1.21      public:
    1.22        typedef _Map Map;
    1.23        typedef _Converter Converter;
    1.24 -      typedef _Graph Graph;
    1.25 -      typedef typename Graph::Edge Item;
    1.26 +      typedef _GR GR;
    1.27 +      typedef typename GR::Edge Item;
    1.28        static const bool dir = _dir;
    1.29  
    1.30      private:
    1.31 -      const Graph& _graph;
    1.32 +      const GR& _graph;
    1.33        Map& _map;
    1.34        Converter _converter;
    1.35  
    1.36      public:
    1.37 -      GraphArcMapStorage(const Graph& graph, Map& map,
    1.38 +      GraphArcMapStorage(const GR& graph, Map& map,
    1.39                           const Converter& converter = Converter())
    1.40          : _graph(graph), _map(map), _converter(converter) {}
    1.41        virtual ~GraphArcMapStorage() {}
    1.42 @@ -173,21 +173,21 @@
    1.43        }
    1.44      };
    1.45  
    1.46 -    template <typename Graph>
    1.47 +    template <typename GR>
    1.48      struct GraphArcLookUpConverter {
    1.49 -      const Graph& _graph;
    1.50 -      const std::map<std::string, typename Graph::Edge>& _map;
    1.51 -
    1.52 -      GraphArcLookUpConverter(const Graph& graph,
    1.53 +      const GR& _graph;
    1.54 +      const std::map<std::string, typename GR::Edge>& _map;
    1.55 +
    1.56 +      GraphArcLookUpConverter(const GR& graph,
    1.57                                const std::map<std::string,
    1.58 -                                             typename Graph::Edge>& map)
    1.59 +                                             typename GR::Edge>& map)
    1.60          : _graph(graph), _map(map) {}
    1.61  
    1.62 -      typename Graph::Arc operator()(const std::string& str) {
    1.63 +      typename GR::Arc operator()(const std::string& str) {
    1.64          if (str.empty() || (str[0] != '+' && str[0] != '-')) {
    1.65            throw FormatError("Item must start with '+' or '-'");
    1.66          }
    1.67 -        typename std::map<std::string, typename Graph::Edge>
    1.68 +        typename std::map<std::string, typename GR::Edge>
    1.69            ::const_iterator it = _map.find(str.substr(1));
    1.70          if (it == _map.end()) {
    1.71            throw FormatError("Item not found");
    1.72 @@ -387,16 +387,15 @@
    1.73  
    1.74    }
    1.75  
    1.76 -  template <typename Digraph>
    1.77 +  template <typename DGR>
    1.78    class DigraphReader;
    1.79  
    1.80 -  template <typename Digraph>
    1.81 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
    1.82 -                                       std::istream& is = std::cin);
    1.83 -  template <typename Digraph>
    1.84 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
    1.85 -  template <typename Digraph>
    1.86 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
    1.87 +  template <typename TDGR>
    1.88 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
    1.89 +  template <typename TDGR>
    1.90 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
    1.91 +  template <typename TDGR>
    1.92 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
    1.93  
    1.94    /// \ingroup lemon_io
    1.95    ///
    1.96 @@ -419,7 +418,7 @@
    1.97    /// rules.
    1.98    ///
    1.99    ///\code
   1.100 -  /// DigraphReader<Digraph>(digraph, std::cin).
   1.101 +  /// DigraphReader<DGR>(digraph, std::cin).
   1.102    ///   nodeMap("coordinates", coord_map).
   1.103    ///   arcMap("capacity", cap_map).
   1.104    ///   node("source", src).
   1.105 @@ -448,21 +447,21 @@
   1.106    /// It is impossible to read this in
   1.107    /// a single pass, because the arcs are not constructed when the node
   1.108    /// maps are read.
   1.109 -  template <typename _Digraph>
   1.110 +  template <typename DGR>
   1.111    class DigraphReader {
   1.112    public:
   1.113  
   1.114 -    typedef _Digraph Digraph;
   1.115 -    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   1.116 +    typedef DGR Digraph;
   1.117  
   1.118    private:
   1.119  
   1.120 +    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
   1.121  
   1.122      std::istream* _is;
   1.123      bool local_is;
   1.124      std::string _filename;
   1.125  
   1.126 -    Digraph& _digraph;
   1.127 +    DGR& _digraph;
   1.128  
   1.129      std::string _nodes_caption;
   1.130      std::string _arcs_caption;
   1.131 @@ -500,7 +499,7 @@
   1.132      ///
   1.133      /// Construct a directed graph reader, which reads from the given
   1.134      /// input stream.
   1.135 -    DigraphReader(Digraph& digraph, std::istream& is = std::cin)
   1.136 +    DigraphReader(DGR& digraph, std::istream& is = std::cin)
   1.137        : _is(&is), local_is(false), _digraph(digraph),
   1.138          _use_nodes(false), _use_arcs(false),
   1.139          _skip_nodes(false), _skip_arcs(false) {}
   1.140 @@ -509,7 +508,7 @@
   1.141      ///
   1.142      /// Construct a directed graph reader, which reads from the given
   1.143      /// file.
   1.144 -    DigraphReader(Digraph& digraph, const std::string& fn)
   1.145 +    DigraphReader(DGR& digraph, const std::string& fn)
   1.146        : _is(new std::ifstream(fn.c_str())), local_is(true),
   1.147          _filename(fn), _digraph(digraph),
   1.148          _use_nodes(false), _use_arcs(false),
   1.149 @@ -524,7 +523,7 @@
   1.150      ///
   1.151      /// Construct a directed graph reader, which reads from the given
   1.152      /// file.
   1.153 -    DigraphReader(Digraph& digraph, const char* fn)
   1.154 +    DigraphReader(DGR& digraph, const char* fn)
   1.155        : _is(new std::ifstream(fn)), local_is(true),
   1.156          _filename(fn), _digraph(digraph),
   1.157          _use_nodes(false), _use_arcs(false),
   1.158 @@ -560,13 +559,13 @@
   1.159  
   1.160    private:
   1.161  
   1.162 -    template <typename DGR>
   1.163 -    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
   1.164 -    template <typename DGR>
   1.165 -    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
   1.166 -                                            const std::string& fn);
   1.167 -    template <typename DGR>
   1.168 -    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
   1.169 +    template <typename TDGR>
   1.170 +    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
   1.171 +    template <typename TDGR>
   1.172 +    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, 
   1.173 +                                             const std::string& fn);
   1.174 +    template <typename TDGR>
   1.175 +    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
   1.176  
   1.177      DigraphReader(DigraphReader& other)
   1.178        : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
   1.179 @@ -593,7 +592,7 @@
   1.180  
   1.181    public:
   1.182  
   1.183 -    /// \name Reading rules
   1.184 +    /// \name Reading Rules
   1.185      /// @{
   1.186  
   1.187      /// \brief Node map reading rule
   1.188 @@ -698,7 +697,7 @@
   1.189  
   1.190      /// @}
   1.191  
   1.192 -    /// \name Select section by name
   1.193 +    /// \name Select Section by Name
   1.194      /// @{
   1.195  
   1.196      /// \brief Set \c \@nodes section to be read
   1.197 @@ -727,7 +726,7 @@
   1.198  
   1.199      /// @}
   1.200  
   1.201 -    /// \name Using previously constructed node or arc set
   1.202 +    /// \name Using Previously Constructed Node or Arc Set
   1.203      /// @{
   1.204  
   1.205      /// \brief Use previously constructed node set
   1.206 @@ -847,7 +846,9 @@
   1.207        while (readSuccess() && line >> c && c != '@') {
   1.208          readLine();
   1.209        }
   1.210 -      line.putback(c);
   1.211 +      if (readSuccess()) {
   1.212 +        line.putback(c);
   1.213 +      }
   1.214      }
   1.215  
   1.216      void readNodes() {
   1.217 @@ -1114,7 +1115,7 @@
   1.218  
   1.219    public:
   1.220  
   1.221 -    /// \name Execution of the reader
   1.222 +    /// \name Execution of the Reader
   1.223      /// @{
   1.224  
   1.225      /// \brief Start the batch processing
   1.226 @@ -1186,14 +1187,52 @@
   1.227      /// @}
   1.228  
   1.229    };
   1.230 +  
   1.231 +  /// \ingroup lemon_io
   1.232 +  ///
   1.233 +  /// \brief Return a \ref DigraphReader class
   1.234 +  ///
   1.235 +  /// This function just returns a \ref DigraphReader class.
   1.236 +  ///
   1.237 +  /// With this function a digraph can be read from an 
   1.238 +  /// \ref lgf-format "LGF" file or input stream with several maps and
   1.239 +  /// attributes. For example, there is network flow problem on a
   1.240 +  /// digraph, i.e. a digraph with a \e capacity map on the arcs and
   1.241 +  /// \e source and \e target nodes. This digraph can be read with the
   1.242 +  /// following code:
   1.243 +  ///
   1.244 +  ///\code
   1.245 +  ///ListDigraph digraph;
   1.246 +  ///ListDigraph::ArcMap<int> cm(digraph);
   1.247 +  ///ListDigraph::Node src, trg;
   1.248 +  ///digraphReader(digraph, std::cin).
   1.249 +  ///  arcMap("capacity", cap).
   1.250 +  ///  node("source", src).
   1.251 +  ///  node("target", trg).
   1.252 +  ///  run();
   1.253 +  ///\endcode
   1.254 +  ///
   1.255 +  /// For a complete documentation, please see the \ref DigraphReader
   1.256 +  /// class documentation.
   1.257 +  /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
   1.258 +  /// to the end of the parameter list.
   1.259 +  /// \relates DigraphReader
   1.260 +  /// \sa digraphReader(TDGR& digraph, const std::string& fn)
   1.261 +  /// \sa digraphReader(TDGR& digraph, const char* fn)
   1.262 +  template <typename TDGR>
   1.263 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
   1.264 +    DigraphReader<TDGR> tmp(digraph, is);
   1.265 +    return tmp;
   1.266 +  }
   1.267  
   1.268    /// \brief Return a \ref DigraphReader class
   1.269    ///
   1.270    /// This function just returns a \ref DigraphReader class.
   1.271    /// \relates DigraphReader
   1.272 -  template <typename Digraph>
   1.273 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
   1.274 -    DigraphReader<Digraph> tmp(digraph, is);
   1.275 +  /// \sa digraphReader(TDGR& digraph, std::istream& is)
   1.276 +  template <typename TDGR>
   1.277 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
   1.278 +    DigraphReader<TDGR> tmp(digraph, fn);
   1.279      return tmp;
   1.280    }
   1.281  
   1.282 @@ -1201,33 +1240,22 @@
   1.283    ///
   1.284    /// This function just returns a \ref DigraphReader class.
   1.285    /// \relates DigraphReader
   1.286 -  template <typename Digraph>
   1.287 -  DigraphReader<Digraph> digraphReader(Digraph& digraph,
   1.288 -                                       const std::string& fn) {
   1.289 -    DigraphReader<Digraph> tmp(digraph, fn);
   1.290 +  /// \sa digraphReader(TDGR& digraph, std::istream& is)
   1.291 +  template <typename TDGR>
   1.292 +  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
   1.293 +    DigraphReader<TDGR> tmp(digraph, fn);
   1.294      return tmp;
   1.295    }
   1.296  
   1.297 -  /// \brief Return a \ref DigraphReader class
   1.298 -  ///
   1.299 -  /// This function just returns a \ref DigraphReader class.
   1.300 -  /// \relates DigraphReader
   1.301 -  template <typename Digraph>
   1.302 -  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
   1.303 -    DigraphReader<Digraph> tmp(digraph, fn);
   1.304 -    return tmp;
   1.305 -  }
   1.306 -
   1.307 -  template <typename Graph>
   1.308 +  template <typename GR>
   1.309    class GraphReader;
   1.310   
   1.311 -  template <typename Graph>
   1.312 -  GraphReader<Graph> graphReader(Graph& graph, 
   1.313 -                                 std::istream& is = std::cin);
   1.314 -  template <typename Graph>
   1.315 -  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
   1.316 -  template <typename Graph>
   1.317 -  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
   1.318 +  template <typename TGR>
   1.319 +  GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
   1.320 +  template <typename TGR>
   1.321 +  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
   1.322 +  template <typename TGR>
   1.323 +  GraphReader<TGR> graphReader(TGR& graph, const char *fn);
   1.324  
   1.325    /// \ingroup lemon_io
   1.326    ///
   1.327 @@ -1244,20 +1272,21 @@
   1.328    /// prefixed with \c '+' and \c '-', then these can be read into an
   1.329    /// arc map.  Similarly, an attribute can be read into an arc, if
   1.330    /// it's value is an edge label prefixed with \c '+' or \c '-'.
   1.331 -  template <typename _Graph>
   1.332 +  template <typename GR>
   1.333    class GraphReader {
   1.334    public:
   1.335  
   1.336 -    typedef _Graph Graph;
   1.337 -    TEMPLATE_GRAPH_TYPEDEFS(Graph);
   1.338 +    typedef GR Graph;
   1.339  
   1.340    private:
   1.341  
   1.342 +    TEMPLATE_GRAPH_TYPEDEFS(GR);
   1.343 +
   1.344      std::istream* _is;
   1.345      bool local_is;
   1.346      std::string _filename;
   1.347  
   1.348 -    Graph& _graph;
   1.349 +    GR& _graph;
   1.350  
   1.351      std::string _nodes_caption;
   1.352      std::string _edges_caption;
   1.353 @@ -1295,7 +1324,7 @@
   1.354      ///
   1.355      /// Construct an undirected graph reader, which reads from the given
   1.356      /// input stream.
   1.357 -    GraphReader(Graph& graph, std::istream& is = std::cin)
   1.358 +    GraphReader(GR& graph, std::istream& is = std::cin)
   1.359        : _is(&is), local_is(false), _graph(graph),
   1.360          _use_nodes(false), _use_edges(false),
   1.361          _skip_nodes(false), _skip_edges(false) {}
   1.362 @@ -1304,7 +1333,7 @@
   1.363      ///
   1.364      /// Construct an undirected graph reader, which reads from the given
   1.365      /// file.
   1.366 -    GraphReader(Graph& graph, const std::string& fn)
   1.367 +    GraphReader(GR& graph, const std::string& fn)
   1.368        : _is(new std::ifstream(fn.c_str())), local_is(true),
   1.369          _filename(fn), _graph(graph),
   1.370          _use_nodes(false), _use_edges(false),
   1.371 @@ -1319,7 +1348,7 @@
   1.372      ///
   1.373      /// Construct an undirected graph reader, which reads from the given
   1.374      /// file.
   1.375 -    GraphReader(Graph& graph, const char* fn)
   1.376 +    GraphReader(GR& graph, const char* fn)
   1.377        : _is(new std::ifstream(fn)), local_is(true),
   1.378          _filename(fn), _graph(graph),
   1.379          _use_nodes(false), _use_edges(false),
   1.380 @@ -1354,12 +1383,12 @@
   1.381      }
   1.382  
   1.383    private:
   1.384 -    template <typename GR>
   1.385 -    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
   1.386 -    template <typename GR>
   1.387 -    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
   1.388 -    template <typename GR>
   1.389 -    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
   1.390 +    template <typename TGR>
   1.391 +    friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
   1.392 +    template <typename TGR>
   1.393 +    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn); 
   1.394 +    template <typename TGR>
   1.395 +    friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
   1.396  
   1.397      GraphReader(GraphReader& other)
   1.398        : _is(other._is), local_is(other.local_is), _graph(other._graph),
   1.399 @@ -1386,7 +1415,7 @@
   1.400  
   1.401    public:
   1.402  
   1.403 -    /// \name Reading rules
   1.404 +    /// \name Reading Rules
   1.405      /// @{
   1.406  
   1.407      /// \brief Node map reading rule
   1.408 @@ -1451,7 +1480,7 @@
   1.409          new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
   1.410        _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
   1.411        _reader_bits::MapStorageBase<Edge>* backward_storage =
   1.412 -        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
   1.413 +        new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
   1.414        _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
   1.415        return *this;
   1.416      }
   1.417 @@ -1465,11 +1494,11 @@
   1.418                            const Converter& converter = Converter()) {
   1.419        checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   1.420        _reader_bits::MapStorageBase<Edge>* forward_storage =
   1.421 -        new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
   1.422 +        new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
   1.423          (_graph, map, converter);
   1.424        _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
   1.425        _reader_bits::MapStorageBase<Edge>* backward_storage =
   1.426 -        new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
   1.427 +        new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
   1.428          (_graph, map, converter);
   1.429        _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
   1.430        return *this;
   1.431 @@ -1527,7 +1556,7 @@
   1.432      ///
   1.433      /// Add an arc reading rule to reader.
   1.434      GraphReader& arc(const std::string& caption, Arc& arc) {
   1.435 -      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
   1.436 +      typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
   1.437        Converter converter(_graph, _edge_index);
   1.438        _reader_bits::ValueStorageBase* storage =
   1.439          new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
   1.440 @@ -1537,7 +1566,7 @@
   1.441  
   1.442      /// @}
   1.443  
   1.444 -    /// \name Select section by name
   1.445 +    /// \name Select Section by Name
   1.446      /// @{
   1.447  
   1.448      /// \brief Set \c \@nodes section to be read
   1.449 @@ -1566,7 +1595,7 @@
   1.450  
   1.451      /// @}
   1.452  
   1.453 -    /// \name Using previously constructed node or edge set
   1.454 +    /// \name Using Previously Constructed Node or Edge Set
   1.455      /// @{
   1.456  
   1.457      /// \brief Use previously constructed node set
   1.458 @@ -1687,7 +1716,9 @@
   1.459        while (readSuccess() && line >> c && c != '@') {
   1.460          readLine();
   1.461        }
   1.462 -      line.putback(c);
   1.463 +      if (readSuccess()) {
   1.464 +        line.putback(c);
   1.465 +      }
   1.466      }
   1.467  
   1.468      void readNodes() {
   1.469 @@ -1954,7 +1985,7 @@
   1.470  
   1.471    public:
   1.472  
   1.473 -    /// \name Execution of the reader
   1.474 +    /// \name Execution of the Reader
   1.475      /// @{
   1.476  
   1.477      /// \brief Start the batch processing
   1.478 @@ -2028,13 +2059,47 @@
   1.479  
   1.480    };
   1.481  
   1.482 +  /// \ingroup lemon_io
   1.483 +  ///
   1.484 +  /// \brief Return a \ref GraphReader class
   1.485 +  ///
   1.486 +  /// This function just returns a \ref GraphReader class. 
   1.487 +  ///
   1.488 +  /// With this function a graph can be read from an 
   1.489 +  /// \ref lgf-format "LGF" file or input stream with several maps and
   1.490 +  /// attributes. For example, there is weighted matching problem on a
   1.491 +  /// graph, i.e. a graph with a \e weight map on the edges. This
   1.492 +  /// graph can be read with the following code:
   1.493 +  ///
   1.494 +  ///\code
   1.495 +  ///ListGraph graph;
   1.496 +  ///ListGraph::EdgeMap<int> weight(graph);
   1.497 +  ///graphReader(graph, std::cin).
   1.498 +  ///  edgeMap("weight", weight).
   1.499 +  ///  run();
   1.500 +  ///\endcode
   1.501 +  ///
   1.502 +  /// For a complete documentation, please see the \ref GraphReader
   1.503 +  /// class documentation.
   1.504 +  /// \warning Don't forget to put the \ref GraphReader::run() "run()"
   1.505 +  /// to the end of the parameter list.
   1.506 +  /// \relates GraphReader
   1.507 +  /// \sa graphReader(TGR& graph, const std::string& fn)
   1.508 +  /// \sa graphReader(TGR& graph, const char* fn)
   1.509 +  template <typename TGR>
   1.510 +  GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
   1.511 +    GraphReader<TGR> tmp(graph, is);
   1.512 +    return tmp;
   1.513 +  }
   1.514 +
   1.515    /// \brief Return a \ref GraphReader class
   1.516    ///
   1.517    /// This function just returns a \ref GraphReader class.
   1.518    /// \relates GraphReader
   1.519 -  template <typename Graph>
   1.520 -  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
   1.521 -    GraphReader<Graph> tmp(graph, is);
   1.522 +  /// \sa graphReader(TGR& graph, std::istream& is)
   1.523 +  template <typename TGR>
   1.524 +  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
   1.525 +    GraphReader<TGR> tmp(graph, fn);
   1.526      return tmp;
   1.527    }
   1.528  
   1.529 @@ -2042,19 +2107,10 @@
   1.530    ///
   1.531    /// This function just returns a \ref GraphReader class.
   1.532    /// \relates GraphReader
   1.533 -  template <typename Graph>
   1.534 -  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
   1.535 -    GraphReader<Graph> tmp(graph, fn);
   1.536 -    return tmp;
   1.537 -  }
   1.538 -
   1.539 -  /// \brief Return a \ref GraphReader class
   1.540 -  ///
   1.541 -  /// This function just returns a \ref GraphReader class.
   1.542 -  /// \relates GraphReader
   1.543 -  template <typename Graph>
   1.544 -  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
   1.545 -    GraphReader<Graph> tmp(graph, fn);
   1.546 +  /// \sa graphReader(TGR& graph, std::istream& is)
   1.547 +  template <typename TGR>
   1.548 +  GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
   1.549 +    GraphReader<TGR> tmp(graph, fn);
   1.550      return tmp;
   1.551    }
   1.552  
   1.553 @@ -2153,7 +2209,7 @@
   1.554  
   1.555    public:
   1.556  
   1.557 -    /// \name Section readers
   1.558 +    /// \name Section Readers
   1.559      /// @{
   1.560  
   1.561      /// \brief Add a section processor with line oriented reading
   1.562 @@ -2244,13 +2300,15 @@
   1.563        while (readSuccess() && line >> c && c != '@') {
   1.564          readLine();
   1.565        }
   1.566 -      line.putback(c);
   1.567 +      if (readSuccess()) {
   1.568 +        line.putback(c);
   1.569 +      }
   1.570      }
   1.571  
   1.572    public:
   1.573  
   1.574  
   1.575 -    /// \name Execution of the reader
   1.576 +    /// \name Execution of the Reader
   1.577      /// @{
   1.578  
   1.579      /// \brief Start the batch processing
   1.580 @@ -2309,12 +2367,30 @@
   1.581  
   1.582    };
   1.583  
   1.584 +  /// \ingroup lemon_io
   1.585 +  ///
   1.586 +  /// \brief Return a \ref SectionReader class
   1.587 +  ///
   1.588 +  /// This function just returns a \ref SectionReader class.
   1.589 +  ///
   1.590 +  /// Please see SectionReader documentation about the custom section
   1.591 +  /// input.
   1.592 +  ///
   1.593 +  /// \relates SectionReader
   1.594 +  /// \sa sectionReader(const std::string& fn)
   1.595 +  /// \sa sectionReader(const char *fn)
   1.596 +  inline SectionReader sectionReader(std::istream& is) {
   1.597 +    SectionReader tmp(is);
   1.598 +    return tmp;
   1.599 +  }
   1.600 +
   1.601    /// \brief Return a \ref SectionReader class
   1.602    ///
   1.603    /// This function just returns a \ref SectionReader class.
   1.604    /// \relates SectionReader
   1.605 -  inline SectionReader sectionReader(std::istream& is) {
   1.606 -    SectionReader tmp(is);
   1.607 +  /// \sa sectionReader(std::istream& is)
   1.608 +  inline SectionReader sectionReader(const std::string& fn) {
   1.609 +    SectionReader tmp(fn);
   1.610      return tmp;
   1.611    }
   1.612  
   1.613 @@ -2322,15 +2398,7 @@
   1.614    ///
   1.615    /// This function just returns a \ref SectionReader class.
   1.616    /// \relates SectionReader
   1.617 -  inline SectionReader sectionReader(const std::string& fn) {
   1.618 -    SectionReader tmp(fn);
   1.619 -    return tmp;
   1.620 -  }
   1.621 -
   1.622 -  /// \brief Return a \ref SectionReader class
   1.623 -  ///
   1.624 -  /// This function just returns a \ref SectionReader class.
   1.625 -  /// \relates SectionReader
   1.626 +  /// \sa sectionReader(std::istream& is)
   1.627    inline SectionReader sectionReader(const char* fn) {
   1.628      SectionReader tmp(fn);
   1.629      return tmp;
   1.630 @@ -2432,7 +2500,7 @@
   1.631    public:
   1.632  
   1.633  
   1.634 -    /// \name Node sections
   1.635 +    /// \name Node Sections
   1.636      /// @{
   1.637  
   1.638      /// \brief Gives back the number of node sections in the file.
   1.639 @@ -2458,7 +2526,7 @@
   1.640  
   1.641      /// @}
   1.642  
   1.643 -    /// \name Arc/Edge sections
   1.644 +    /// \name Arc/Edge Sections
   1.645      /// @{
   1.646  
   1.647      /// \brief Gives back the number of arc/edge sections in the file.
   1.648 @@ -2516,7 +2584,7 @@
   1.649  
   1.650      /// @}
   1.651  
   1.652 -    /// \name Attribute sections
   1.653 +    /// \name Attribute Sections
   1.654      /// @{
   1.655  
   1.656      /// \brief Gives back the number of attribute sections in the file.
   1.657 @@ -2542,7 +2610,7 @@
   1.658  
   1.659      /// @}
   1.660  
   1.661 -    /// \name Extra sections
   1.662 +    /// \name Extra Sections
   1.663      /// @{
   1.664  
   1.665      /// \brief Gives back the number of extra sections in the file.
   1.666 @@ -2585,7 +2653,9 @@
   1.667        while (readSuccess() && line >> c && c != '@') {
   1.668          readLine();
   1.669        }
   1.670 -      line.putback(c);
   1.671 +      if (readSuccess()) {
   1.672 +        line.putback(c);
   1.673 +      }
   1.674      }
   1.675  
   1.676      void readMaps(std::vector<std::string>& maps) {
   1.677 @@ -2616,7 +2686,7 @@
   1.678  
   1.679    public:
   1.680  
   1.681 -    /// \name Execution of the contents reader
   1.682 +    /// \name Execution of the Contents Reader
   1.683      /// @{
   1.684  
   1.685      /// \brief Starts the reading