src/lemon/graph_reader.h
changeset 1421 7a21e1414c38
parent 1408 892c29484414
child 1429 4283998fb2be
     1.1 --- a/src/lemon/graph_reader.h	Sat May 14 17:37:33 2005 +0000
     1.2 +++ b/src/lemon/graph_reader.h	Sat May 14 17:39:37 2005 +0000
     1.3 @@ -56,8 +56,7 @@
     1.4    /// parameters.
     1.5    ///
     1.6    /// \code
     1.7 -  /// reader.readNodeMap("x-coord", xCoordMap);
     1.8 -  /// reader.readNodeMap("y-coord", yCoordMap);
     1.9 +  /// reader.readNodeMap("coords", coords);
    1.10    ///
    1.11    /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
    1.12    /// reader.skipNodeMap<QuotedStringReader>("description");
    1.13 @@ -114,12 +113,13 @@
    1.14      ///
    1.15      /// Construct a new GraphReader. It reads into the given graph
    1.16      /// and it use the given reader as the default skipper.
    1.17 -    GraphReader(std::istream& _is, Graph& _graph, 
    1.18 +    GraphReader(std::istream& _is, 
    1.19 +		typename SmartParameter<Graph>::Type _graph, 
    1.20  		const DefaultSkipper& _skipper = DefaultSkipper()) 
    1.21 -      : reader(new LemonReader(_is)), own_reader(true), 
    1.22 -	graph(_graph), skipper(_skipper),
    1.23 -	nodeset_reader(*reader, graph, std::string(), skipper),
    1.24 -	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
    1.25 +      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
    1.26 +	nodeset_reader(*reader, _graph, std::string(), skipper),
    1.27 +	edgeset_reader(*reader, _graph, nodeset_reader, 
    1.28 +		       std::string(), skipper),
    1.29  	node_reader(*reader, nodeset_reader, std::string()),
    1.30  	edge_reader(*reader, edgeset_reader, std::string()),
    1.31  	attribute_reader(*reader, std::string()) {}
    1.32 @@ -128,12 +128,14 @@
    1.33      ///
    1.34      /// Construct a new GraphReader. It reads into the given graph
    1.35      /// and it use the given reader as the default skipper.
    1.36 -    GraphReader(const std::string& _filename, Graph& _graph, 
    1.37 +    GraphReader(const std::string& _filename, 
    1.38 +		typename SmartParameter<Graph>::Type _graph, 
    1.39  		const DefaultSkipper& _skipper = DefaultSkipper()) 
    1.40        : reader(new LemonReader(_filename)), own_reader(true), 
    1.41 -	graph(_graph), skipper(_skipper),
    1.42 -	nodeset_reader(*reader, graph, std::string(), skipper),
    1.43 -	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
    1.44 +	skipper(_skipper),
    1.45 +	nodeset_reader(*reader, _graph, std::string(), skipper),
    1.46 +	edgeset_reader(*reader, _graph, nodeset_reader, 
    1.47 +		       std::string(), skipper),
    1.48  	node_reader(*reader, nodeset_reader, std::string()),
    1.49  	edge_reader(*reader, edgeset_reader, std::string()),
    1.50  	attribute_reader(*reader, std::string()) {}
    1.51 @@ -142,12 +144,13 @@
    1.52      ///
    1.53      /// Construct a new GraphReader. It reads into the given graph
    1.54      /// and it use the given reader as the default skipper.
    1.55 -    GraphReader(LemonReader& _reader, Graph& _graph, 
    1.56 +    GraphReader(LemonReader& _reader, 
    1.57 +		typename SmartParameter<Graph>::Type _graph, 
    1.58  		const DefaultSkipper& _skipper = DefaultSkipper()) 
    1.59 -      : reader(_reader), own_reader(false), 
    1.60 -	graph(_graph), skipper(_skipper),
    1.61 -	nodeset_reader(*reader, graph, std::string(), skipper),
    1.62 -	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
    1.63 +      : reader(_reader), own_reader(false), skipper(_skipper),
    1.64 +	nodeset_reader(*reader, _graph, std::string(), skipper),
    1.65 +	edgeset_reader(*reader, _graph, nodeset_reader, 
    1.66 +		       std::string(), skipper),
    1.67  	node_reader(*reader, nodeset_reader, std::string()),
    1.68  	edge_reader(*reader, edgeset_reader, std::string()),
    1.69  	attribute_reader(*reader, std::string()) {}
    1.70 @@ -165,7 +168,13 @@
    1.71      /// Add a new node map reader command for the reader.
    1.72      template <typename Map>
    1.73      GraphReader& readNodeMap(std::string name, Map& map) {
    1.74 -      nodeset_reader.readMap(name, map);
    1.75 +      nodeset_reader.readNodeMap(name, map);
    1.76 +      return *this;
    1.77 +    }
    1.78 +
    1.79 +    template <typename Map>
    1.80 +    GraphReader& readNodeMap(std::string name, const Map& map) {
    1.81 +      nodeset_reader.readNodeMap(name, map);
    1.82        return *this;
    1.83      }
    1.84  
    1.85 @@ -175,7 +184,14 @@
    1.86      template <typename Reader, typename Map>
    1.87      GraphReader& readNodeMap(std::string name, Map& map, 
    1.88  			     const Reader& reader = Reader()) {
    1.89 -      nodeset_reader.readMap(name, map, reader);
    1.90 +      nodeset_reader.readNodeMap(name, map, reader);
    1.91 +      return *this;
    1.92 +    }
    1.93 +
    1.94 +    template <typename Reader, typename Map>
    1.95 +    GraphReader& readNodeMap(std::string name, const Map& map, 
    1.96 +			     const Reader& reader = Reader()) {
    1.97 +      nodeset_reader.readNodeMap(name, map, reader);
    1.98        return *this;
    1.99      }
   1.100  
   1.101 @@ -185,7 +201,7 @@
   1.102      template <typename Reader>
   1.103      GraphReader& skipNodeMap(std::string name, 
   1.104  			     const Reader& reader = Reader()) {
   1.105 -      nodeset_reader.skipMap(name, reader);
   1.106 +      nodeset_reader.skipNodeMap(name, reader);
   1.107        return *this;
   1.108      }
   1.109  
   1.110 @@ -194,7 +210,13 @@
   1.111      /// Add a new edge map reader command for the reader.
   1.112      template <typename Map>
   1.113      GraphReader& readEdgeMap(std::string name, Map& map) { 
   1.114 -      edgeset_reader.readMap(name, map);
   1.115 +      edgeset_reader.readEdgeMap(name, map);
   1.116 +      return *this;
   1.117 +    }
   1.118 +
   1.119 +    template <typename Map>
   1.120 +    GraphReader& readEdgeMap(std::string name, const Map& map) { 
   1.121 +      edgeset_reader.readEdgeMap(name, map);
   1.122        return *this;
   1.123      }
   1.124  
   1.125 @@ -205,7 +227,14 @@
   1.126      template <typename Reader, typename Map>
   1.127      GraphReader& readEdgeMap(std::string name, Map& map,
   1.128  			     const Reader& reader = Reader()) {
   1.129 -      edgeset_reader.readMap(name, map, reader);
   1.130 +      edgeset_reader.readEdgeMap(name, map, reader);
   1.131 +      return *this;
   1.132 +    }
   1.133 +
   1.134 +    template <typename Reader, typename Map>
   1.135 +    GraphReader& readEdgeMap(std::string name, const Map& map,
   1.136 +			     const Reader& reader = Reader()) {
   1.137 +      edgeset_reader.readEdgeMap(name, map, reader);
   1.138        return *this;
   1.139      }
   1.140  
   1.141 @@ -213,10 +242,9 @@
   1.142      ///
   1.143      /// Add a new edge map skipper command for the reader.
   1.144      template <typename Reader>
   1.145 -    GraphReader& skipEdgeMap(std::string name,
   1.146 +    GraphReader& skipEdgeMap(std::string name, 
   1.147  			     const Reader& reader = Reader()) {
   1.148 -
   1.149 -      edgeset_reader.skipMap(name, reader);
   1.150 +      edgeset_reader.skipEdgeMap(name, reader);
   1.151        return *this;
   1.152      }
   1.153  
   1.154 @@ -276,8 +304,6 @@
   1.155      LemonReader* reader;
   1.156      bool own_reader;
   1.157  
   1.158 -    Graph& graph;
   1.159 -
   1.160      DefaultSkipper skipper;
   1.161  
   1.162      NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   1.163 @@ -368,6 +394,365 @@
   1.164      reader.run();
   1.165    }
   1.166  
   1.167 +  /// \brief The undir graph reader class.
   1.168 +  ///
   1.169 +  /// The given file format may contain several maps and labeled nodes or 
   1.170 +  /// edges.
   1.171 +  ///
   1.172 +  /// If you read a graph you need not read all the maps and items just those
   1.173 +  /// that you need. The interface of the \c GraphReader is very similar to
   1.174 +  /// the GraphWriter but the reading method does not depend on the order the
   1.175 +  /// given commands.
   1.176 +  ///
   1.177 +  /// The reader object suppose that each not readed value does not contain 
   1.178 +  /// whitespaces, therefore it has some extra possibilities to control how
   1.179 +  /// it should skip the values when the string representation contains spaces.
   1.180 +  ///
   1.181 +  /// \code
   1.182 +  /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
   1.183 +  /// \endcode
   1.184 +  ///
   1.185 +  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
   1.186 +  /// If there is a map that you do not want to read from the file and there is
   1.187 +  /// whitespace in the string represenation of the values then you should
   1.188 +  /// call the \c skipNodeMap() template member function with proper 
   1.189 +  /// parameters.
   1.190 +  ///
   1.191 +  /// \code
   1.192 +  /// reader.readNodeMap("coords", coords);
   1.193 +  ///
   1.194 +  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
   1.195 +  /// reader.skipNodeMap<QuotedStringReader>("description");
   1.196 +  ///
   1.197 +  /// reader.readNodeMap("color", colorMap);
   1.198 +  /// \endcode
   1.199 +  ///
   1.200 +  /// With the \c readUndirEdgeMap() member function you can give an 
   1.201 +  /// undir edge map reading command similar to the NodeMaps. 
   1.202 +  ///
   1.203 +  /// \code
   1.204 +  /// reader.readUndirEdgeMap("capacity", capacityMap);
   1.205 +  /// \endcode
   1.206 +  ///
   1.207 +  /// The reading of the directed edge maps is just a syntactical sugar.
   1.208 +  /// It reads two undirected edgemaps into a directed edge map. The 
   1.209 +  /// undirected edge maps' name should be start with the \c '+' and the
   1.210 +  /// \c '-' character and the same.
   1.211 +  ///
   1.212 +  /// \code
   1.213 +  /// reader.readEdgeMap("flow", flowMap);
   1.214 +  /// \endcode 
   1.215 +  ///
   1.216 +  /// With \c readNode() and \c readUndirEdge() functions you can read 
   1.217 +  /// labeled Nodes and UndirEdges.
   1.218 +  ///
   1.219 +  /// \code
   1.220 +  /// reader.readNode("source", sourceNode);
   1.221 +  /// reader.readNode("target", targetNode);
   1.222 +  ///
   1.223 +  /// reader.readUndirEdge("observed", undirEdge);
   1.224 +  /// \endcode
   1.225 +  ///
   1.226 +  /// With the \c readAttribute() functions you can read an attribute
   1.227 +  /// in a variable. You can specify the reader for the attribute as
   1.228 +  /// the nodemaps.
   1.229 +  ///
   1.230 +  /// After you give all read commands you must call the \c run() member
   1.231 +  /// function, which execute all the commands.
   1.232 +  ///
   1.233 +  /// \code
   1.234 +  /// reader.run();
   1.235 +  /// \endcode
   1.236 +  ///
   1.237 +  /// \see GraphReader
   1.238 +  /// \see DefaultReaderTraits
   1.239 +  /// \see \ref UndirGraphWriter
   1.240 +  /// \see \ref graph-io-page
   1.241 +  ///
   1.242 +  /// \author Balazs Dezso
   1.243 +  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   1.244 +  class UndirGraphReader {
   1.245 +  public:
   1.246 +    
   1.247 +    typedef _Graph Graph;
   1.248 +    typedef typename Graph::Node Node;
   1.249 +    typedef typename Graph::Edge Edge;
   1.250 +    typedef typename Graph::UndirEdge UndirEdge;
   1.251 +
   1.252 +    typedef _ReaderTraits ReaderTraits;
   1.253 +    typedef typename ReaderTraits::Skipper DefaultSkipper;
   1.254 +
   1.255 +    /// \brief Construct a new UndirGraphReader.
   1.256 +    ///
   1.257 +    /// Construct a new UndirGraphReader. It reads into the given graph
   1.258 +    /// and it use the given reader as the default skipper.
   1.259 +    UndirGraphReader(std::istream& _is, Graph& _graph, 
   1.260 +		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   1.261 +      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
   1.262 +	nodeset_reader(*reader, _graph, std::string(), skipper),
   1.263 +	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
   1.264 +			     std::string(), skipper),
   1.265 +	node_reader(*reader, nodeset_reader, std::string()),
   1.266 +	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
   1.267 +	attribute_reader(*reader, std::string()) {}
   1.268 +
   1.269 +    /// \brief Construct a new UndirGraphReader.
   1.270 +    ///
   1.271 +    /// Construct a new UndirGraphReader. It reads into the given graph
   1.272 +    /// and it use the given reader as the default skipper.
   1.273 +    UndirGraphReader(const std::string& _filename, Graph& _graph, 
   1.274 +		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   1.275 +      : reader(new LemonReader(_filename)), own_reader(true), 
   1.276 +	skipper(_skipper),
   1.277 +	nodeset_reader(*reader, _graph, std::string(), skipper),
   1.278 +	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
   1.279 +			     std::string(), skipper),
   1.280 +	node_reader(*reader, nodeset_reader, std::string()),
   1.281 +	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
   1.282 +	attribute_reader(*reader, std::string()) {}
   1.283 +
   1.284 +    /// \brief Construct a new UndirGraphReader.
   1.285 +    ///
   1.286 +    /// Construct a new UndirGraphReader. It reads into the given graph
   1.287 +    /// and it use the given reader as the default skipper.
   1.288 +    UndirGraphReader(LemonReader& _reader, Graph& _graph, 
   1.289 +		     const DefaultSkipper& _skipper = DefaultSkipper()) 
   1.290 +      : reader(_reader), own_reader(false), skipper(_skipper),
   1.291 +	nodeset_reader(*reader, _graph, std::string(), skipper),
   1.292 +	undir_edgeset_reader(*reader, _graph, nodeset_reader, 
   1.293 +			     std::string(), skipper),
   1.294 +	node_reader(*reader, nodeset_reader, std::string()),
   1.295 +	undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
   1.296 +	attribute_reader(*reader, std::string()) {}
   1.297 +
   1.298 +    /// \brief Destruct the graph reader.
   1.299 +    ///
   1.300 +    /// Destruct the graph reader.
   1.301 +    ~UndirGraphReader() {
   1.302 +      if (own_reader) 
   1.303 +	delete reader;
   1.304 +    }
   1.305 +
   1.306 +    /// \brief Add a new node map reader command for the reader.
   1.307 +    ///
   1.308 +    /// Add a new node map reader command for the reader.
   1.309 +    template <typename Map>
   1.310 +    UndirGraphReader& readNodeMap(std::string name, Map& map) {
   1.311 +      nodeset_reader.readNodeMap(name, map);
   1.312 +      return *this;
   1.313 +    }
   1.314 +
   1.315 +    template <typename Map>
   1.316 +    UndirGraphReader& readNodeMap(std::string name, const Map& map) {
   1.317 +      nodeset_reader.readNodeMap(name, map);
   1.318 +      return *this;
   1.319 +    }
   1.320 +
   1.321 +    /// \brief Add a new node map reader command for the reader.
   1.322 +    ///
   1.323 +    /// Add a new node map reader command for the reader.
   1.324 +    template <typename Reader, typename Map>
   1.325 +    UndirGraphReader& readNodeMap(std::string name, Map& map, 
   1.326 +				  const Reader& reader = Reader()) {
   1.327 +      nodeset_reader.readNodeMap(name, map, reader);
   1.328 +      return *this;
   1.329 +    }
   1.330 +
   1.331 +    template <typename Reader, typename Map>
   1.332 +    UndirGraphReader& readNodeMap(std::string name, const Map& map, 
   1.333 +				  const Reader& reader = Reader()) {
   1.334 +      nodeset_reader.readNodeMap(name, map, reader);
   1.335 +      return *this;
   1.336 +    }
   1.337 +
   1.338 +    /// \brief Add a new node map skipper command for the reader.
   1.339 +    ///
   1.340 +    /// Add a new node map skipper command for the reader.
   1.341 +    template <typename Reader>
   1.342 +    UndirGraphReader& skipNodeMap(std::string name, 
   1.343 +			     const Reader& reader = Reader()) {
   1.344 +      nodeset_reader.skipNodeMap(name, reader);
   1.345 +      return *this;
   1.346 +    }
   1.347 +
   1.348 +    /// \brief Add a new undirected edge map reader command for the reader.
   1.349 +    ///
   1.350 +    /// Add a new undirected edge map reader command for the reader.
   1.351 +    template <typename Map>
   1.352 +    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) { 
   1.353 +      undir_edgeset_reader.readUndirEdgeMap(name, map);
   1.354 +      return *this;
   1.355 +    }
   1.356 +
   1.357 +    template <typename Map>
   1.358 +    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) { 
   1.359 +      undir_edgeset_reader.readUndirEdgeMap(name, map);
   1.360 +      return *this;
   1.361 +    }
   1.362 +
   1.363 +
   1.364 +    /// \brief Add a new undirected edge map reader command for the reader.
   1.365 +    ///
   1.366 +    /// Add a new undirected edge map reader command for the reader.
   1.367 +    template <typename Reader, typename Map>
   1.368 +    UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
   1.369 +				       const Reader& reader = Reader()) {
   1.370 +      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
   1.371 +      return *this;
   1.372 +    }
   1.373 +
   1.374 +    template <typename Reader, typename Map>
   1.375 +    UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
   1.376 +				       const Reader& reader = Reader()) {
   1.377 +      undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
   1.378 +      return *this;
   1.379 +    }
   1.380 +
   1.381 +    /// \brief Add a new undirected edge map skipper command for the reader.
   1.382 +    ///
   1.383 +    /// Add a new undirected edge map skipper command for the reader.
   1.384 +    template <typename Reader>
   1.385 +    UndirGraphReader& skipUndirEdgeMap(std::string name,
   1.386 +				       const Reader& reader = Reader()) {
   1.387 +      undir_edgeset_reader.skipUndirMap(name, reader);
   1.388 +      return *this;
   1.389 +    }
   1.390 +
   1.391 +
   1.392 +    /// \brief Add a new edge map reader command for the reader.
   1.393 +    ///
   1.394 +    /// Add a new edge map reader command for the reader.
   1.395 +    template <typename Map>
   1.396 +    UndirGraphReader& readEdgeMap(std::string name, Map& map) { 
   1.397 +      undir_edgeset_reader.readEdgeMap(name, map);
   1.398 +      return *this;
   1.399 +    }
   1.400 +
   1.401 +    template <typename Map>
   1.402 +    UndirGraphReader& readEdgeMap(std::string name, const Map& map) { 
   1.403 +      undir_edgeset_reader.readEdgeMap(name, map);
   1.404 +      return *this;
   1.405 +    }
   1.406 +
   1.407 +
   1.408 +    /// \brief Add a new edge map reader command for the reader.
   1.409 +    ///
   1.410 +    /// Add a new edge map reader command for the reader.
   1.411 +    template <typename Reader, typename Map>
   1.412 +    UndirGraphReader& readEdgeMap(std::string name, Map& map,
   1.413 +				       const Reader& reader = Reader()) {
   1.414 +      undir_edgeset_reader.readEdgeMap(name, map, reader);
   1.415 +      return *this;
   1.416 +    }
   1.417 +
   1.418 +    template <typename Reader, typename Map>
   1.419 +    UndirGraphReader& readEdgeMap(std::string name, const Map& map,
   1.420 +				       const Reader& reader = Reader()) {
   1.421 +      undir_edgeset_reader.readEdgeMap(name, map, reader);
   1.422 +      return *this;
   1.423 +    }
   1.424 +
   1.425 +    /// \brief Add a new edge map skipper command for the reader.
   1.426 +    ///
   1.427 +    /// Add a new edge map skipper command for the reader.
   1.428 +    template <typename Reader>
   1.429 +    UndirGraphReader& skipEdgeMap(std::string name,
   1.430 +				       const Reader& reader = Reader()) {
   1.431 +      undir_edgeset_reader.skipEdgeMap(name, reader);
   1.432 +      return *this;
   1.433 +    }
   1.434 +
   1.435 +    /// \brief Add a new labeled node reader for the reader.
   1.436 +    ///
   1.437 +    /// Add a new labeled node reader for the reader.
   1.438 +    UndirGraphReader& readNode(std::string name, Node& node) {
   1.439 +      node_reader.readNode(name, node);
   1.440 +      return *this;
   1.441 +    }
   1.442 +
   1.443 +    /// \brief Add a new labeled edge reader for the reader.
   1.444 +    ///
   1.445 +    /// Add a new labeled edge reader for the reader.
   1.446 +    UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
   1.447 +      undir_edge_reader.readUndirEdge(name, edge);
   1.448 +    }
   1.449 +
   1.450 +    /// \brief Add a new attribute reader command.
   1.451 +    ///
   1.452 +    ///  Add a new attribute reader command.
   1.453 +    template <typename Value>
   1.454 +    UndirGraphReader& readAttribute(std::string name, Value& value) {
   1.455 +      attribute_reader.readAttribute(name, value);
   1.456 +      return *this;
   1.457 +    }
   1.458 +    
   1.459 +    /// \brief Add a new attribute reader command.
   1.460 +    ///
   1.461 +    ///  Add a new attribute reader command.
   1.462 +    template <typename Reader, typename Value>
   1.463 +    UndirGraphReader& readAttribute(std::string name, Value& value, 
   1.464 +			       const Reader& reader) {
   1.465 +      attribute_reader.readAttribute<Reader>(name, value, reader);
   1.466 +      return *this;
   1.467 +    }
   1.468 +
   1.469 +    /// \brief Conversion operator to LemonReader.
   1.470 +    ///
   1.471 +    /// Conversion operator to LemonReader. It make possible
   1.472 +    /// to access the encapsulated \e LemonReader, this way
   1.473 +    /// you can attach to this reader new instances of 
   1.474 +    /// \e LemonReader::SectionReader.
   1.475 +    operator LemonReader&() {
   1.476 +      return *reader;
   1.477 +    }
   1.478 +
   1.479 +    /// \brief Executes the reader commands.
   1.480 +    ///
   1.481 +    /// Executes the reader commands.
   1.482 +    void run() {
   1.483 +      reader->run();
   1.484 +    }
   1.485 +
   1.486 +  private:
   1.487 +
   1.488 +    LemonReader* reader;
   1.489 +    bool own_reader;
   1.490 +
   1.491 +    DefaultSkipper skipper;
   1.492 +
   1.493 +    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   1.494 +    UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
   1.495 +
   1.496 +    NodeReader<Graph> node_reader;
   1.497 +    UndirEdgeReader<Graph> undir_edge_reader;
   1.498 +    
   1.499 +    AttributeReader<ReaderTraits> attribute_reader;
   1.500 +  };
   1.501 +
   1.502 +  /// \brief Read an undir graph from the input.
   1.503 +  ///
   1.504 +  /// Read an undir graph from the input.
   1.505 +  /// \param is The input stream.
   1.506 +  /// \param g The graph.
   1.507 +  /// \param capacity The capacity map.
   1.508 +  template<typename Graph, typename CapacityMap>
   1.509 +  void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
   1.510 +    UndirGraphReader<Graph> reader(is, g);
   1.511 +    reader.readUndirEdgeMap("capacity", capacity);
   1.512 +    reader.run();
   1.513 +  }
   1.514 +
   1.515 +  /// \brief Read an undir graph from the input.
   1.516 +  ///
   1.517 +  /// Read an undir graph from the input.
   1.518 +  /// \param is The input stream.
   1.519 +  /// \param g The graph.
   1.520 +  template<typename Graph>
   1.521 +  void readUndirGraph(std::istream& is, Graph &g) {
   1.522 +    UndirGraphReader<Graph> reader(is, g);
   1.523 +    reader.run();
   1.524 +  }
   1.525 +
   1.526    /// @}
   1.527  }
   1.528