src/lemon/graph_reader.h
author deba
Sat, 14 May 2005 17:29:28 +0000
changeset 1417 53c2a0ccc9a4
parent 1396 56f9a4ba9149
child 1421 7a21e1414c38
permissions -rw-r--r--
std:: prefix bug corrected
     1 /* -*- C++ -*-
     2  * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 ///\ingroup io_group
    18 ///\file
    19 ///\brief Lemon Graph Format reader.
    20 
    21 #ifndef LEMON_GRAPH_READER_H
    22 #define LEMON_GRAPH_READER_H
    23 
    24 #include <iostream>
    25 
    26 #include <lemon/error.h>
    27 #include <lemon/lemon_reader.h>
    28 
    29 namespace lemon {
    30 
    31   /// \addtogroup io_group
    32   /// @{
    33 
    34   /// \brief The graph reader class.
    35   ///
    36   /// The given file format may contain several maps and labeled nodes or 
    37   /// edges.
    38   ///
    39   /// If you read a graph you need not read all the maps and items just those
    40   /// that you need. The interface of the \c GraphReader is very similar to
    41   /// the GraphWriter but the reading method does not depend on the order the
    42   /// given commands.
    43   ///
    44   /// The reader object suppose that each not readed value does not contain 
    45   /// whitespaces, therefore it has some extra possibilities to control how
    46   /// it should skip the values when the string representation contains spaces.
    47   ///
    48   /// \code
    49   /// GraphReader<ListGraph> reader(std::cin, graph);
    50   /// \endcode
    51   ///
    52   /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
    53   /// If there is a map that you do not want to read from the file and there is
    54   /// whitespace in the string represenation of the values then you should
    55   /// call the \c skipNodeMap() template member function with proper 
    56   /// parameters.
    57   ///
    58   /// \code
    59   /// reader.readNodeMap("x-coord", xCoordMap);
    60   /// reader.readNodeMap("y-coord", yCoordMap);
    61   ///
    62   /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
    63   /// reader.skipNodeMap<QuotedStringReader>("description");
    64   ///
    65   /// reader.readNodeMap("color", colorMap);
    66   /// \endcode
    67   ///
    68   /// With the \c readEdgeMap() member function you can give an edge map
    69   /// reading command similar to the NodeMaps. 
    70   ///
    71   /// \code
    72   /// reader.readEdgeMap("weight", weightMap);
    73   /// reader.readEdgeMap("label", labelMap);
    74   /// \endcode
    75   ///
    76   /// With \c readNode() and \c readEdge() functions you can read 
    77   /// labeled Nodes and Edges.
    78   ///
    79   /// \code
    80   /// reader.readNode("source", sourceNode);
    81   /// reader.readNode("target", targetNode);
    82   ///
    83   /// reader.readEdge("observed", edge);
    84   /// \endcode
    85   ///
    86   /// With the \c readAttribute() functions you can read an attribute
    87   /// in a variable. You can specify the reader for the attribute as
    88   /// the nodemaps.
    89   ///
    90   /// After you give all read commands you must call the \c run() member
    91   /// function, which execute all the commands.
    92   ///
    93   /// \code
    94   /// reader.run();
    95   /// \endcode
    96   ///
    97   /// \see DefaultReaderTraits
    98   /// \see QuotedStringReader
    99   /// \see \ref GraphWriter
   100   /// \see \ref graph-io-page
   101   /// \author Balazs Dezso
   102   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   103   class GraphReader {
   104   public:
   105     
   106     typedef _Graph Graph;
   107     typedef typename Graph::Node Node;
   108     typedef typename Graph::Edge Edge;
   109 
   110     typedef _ReaderTraits ReaderTraits;
   111     typedef typename ReaderTraits::Skipper DefaultSkipper;
   112 
   113     /// \brief Construct a new GraphReader.
   114     ///
   115     /// Construct a new GraphReader. It reads into the given graph
   116     /// and it use the given reader as the default skipper.
   117     GraphReader(std::istream& _is, Graph& _graph, 
   118 		const DefaultSkipper& _skipper = DefaultSkipper()) 
   119       : reader(new LemonReader(_is)), own_reader(true), 
   120 	graph(_graph), skipper(_skipper),
   121 	nodeset_reader(*reader, graph, std::string(), skipper),
   122 	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
   123 	node_reader(*reader, nodeset_reader, std::string()),
   124 	edge_reader(*reader, edgeset_reader, std::string()),
   125 	attribute_reader(*reader, std::string()) {}
   126 
   127     /// \brief Construct a new GraphReader.
   128     ///
   129     /// Construct a new GraphReader. It reads into the given graph
   130     /// and it use the given reader as the default skipper.
   131     GraphReader(const std::string& _filename, Graph& _graph, 
   132 		const DefaultSkipper& _skipper = DefaultSkipper()) 
   133       : reader(new LemonReader(_filename)), own_reader(true), 
   134 	graph(_graph), skipper(_skipper),
   135 	nodeset_reader(*reader, graph, std::string(), skipper),
   136 	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
   137 	node_reader(*reader, nodeset_reader, std::string()),
   138 	edge_reader(*reader, edgeset_reader, std::string()),
   139 	attribute_reader(*reader, std::string()) {}
   140 
   141     /// \brief Construct a new GraphReader.
   142     ///
   143     /// Construct a new GraphReader. It reads into the given graph
   144     /// and it use the given reader as the default skipper.
   145     GraphReader(LemonReader& _reader, Graph& _graph, 
   146 		const DefaultSkipper& _skipper = DefaultSkipper()) 
   147       : reader(_reader), own_reader(false), 
   148 	graph(_graph), skipper(_skipper),
   149 	nodeset_reader(*reader, graph, std::string(), skipper),
   150 	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
   151 	node_reader(*reader, nodeset_reader, std::string()),
   152 	edge_reader(*reader, edgeset_reader, std::string()),
   153 	attribute_reader(*reader, std::string()) {}
   154 
   155     /// \brief Destruct the graph reader.
   156     ///
   157     /// Destruct the graph reader.
   158     ~GraphReader() {
   159       if (own_reader) 
   160 	delete reader;
   161     }
   162 
   163     /// \brief Add a new node map reader command for the reader.
   164     ///
   165     /// Add a new node map reader command for the reader.
   166     template <typename Map>
   167     GraphReader& readNodeMap(std::string name, Map& map) {
   168       nodeset_reader.readMap(name, map);
   169       return *this;
   170     }
   171 
   172     /// \brief Add a new node map reader command for the reader.
   173     ///
   174     /// Add a new node map reader command for the reader.
   175     template <typename Reader, typename Map>
   176     GraphReader& readNodeMap(std::string name, Map& map, 
   177 			     const Reader& reader = Reader()) {
   178       nodeset_reader.readMap(name, map, reader);
   179       return *this;
   180     }
   181 
   182     /// \brief Add a new node map skipper command for the reader.
   183     ///
   184     /// Add a new node map skipper command for the reader.
   185     template <typename Reader>
   186     GraphReader& skipNodeMap(std::string name, 
   187 			     const Reader& reader = Reader()) {
   188       nodeset_reader.skipMap(name, reader);
   189       return *this;
   190     }
   191 
   192     /// \brief Add a new edge map reader command for the reader.
   193     ///
   194     /// Add a new edge map reader command for the reader.
   195     template <typename Map>
   196     GraphReader& readEdgeMap(std::string name, Map& map) { 
   197       edgeset_reader.readMap(name, map);
   198       return *this;
   199     }
   200 
   201 
   202     /// \brief Add a new edge map reader command for the reader.
   203     ///
   204     /// Add a new edge map reader command for the reader.
   205     template <typename Reader, typename Map>
   206     GraphReader& readEdgeMap(std::string name, Map& map,
   207 			     const Reader& reader = Reader()) {
   208       edgeset_reader.readMap(name, map, reader);
   209       return *this;
   210     }
   211 
   212     /// \brief Add a new edge map skipper command for the reader.
   213     ///
   214     /// Add a new edge map skipper command for the reader.
   215     template <typename Reader>
   216     GraphReader& skipEdgeMap(std::string name,
   217 			     const Reader& reader = Reader()) {
   218 
   219       edgeset_reader.skipMap(name, reader);
   220       return *this;
   221     }
   222 
   223     /// \brief Add a new labeled node reader for the reader.
   224     ///
   225     /// Add a new labeled node reader for the reader.
   226     GraphReader& readNode(std::string name, Node& node) {
   227       node_reader.readNode(name, node);
   228       return *this;
   229     }
   230 
   231     /// \brief Add a new labeled edge reader for the reader.
   232     ///
   233     /// Add a new labeled edge reader for the reader.
   234     GraphReader& readEdge(std::string name, Edge& edge) {
   235       edge_reader.readEdge(name, edge);
   236     }
   237 
   238     /// \brief Add a new attribute reader command.
   239     ///
   240     ///  Add a new attribute reader command.
   241     template <typename Value>
   242     GraphReader& readAttribute(std::string name, Value& value) {
   243       attribute_reader.readAttribute(name, value);
   244       return *this;
   245     }
   246     
   247     /// \brief Add a new attribute reader command.
   248     ///
   249     ///  Add a new attribute reader command.
   250     template <typename Reader, typename Value>
   251     GraphReader& readAttribute(std::string name, Value& value, 
   252 			       const Reader& reader) {
   253       attribute_reader.readAttribute<Reader>(name, value, reader);
   254       return *this;
   255     }
   256 
   257     /// \brief Conversion operator to LemonReader.
   258     ///
   259     /// Conversion operator to LemonReader. It make possible
   260     /// to access the encapsulated \e LemonReader, this way
   261     /// you can attach to this reader new instances of 
   262     /// \e LemonReader::SectionReader.
   263     operator LemonReader&() {
   264       return *reader;
   265     }
   266 
   267     /// \brief Executes the reader commands.
   268     ///
   269     /// Executes the reader commands.
   270     void run() {
   271       reader->run();
   272     }
   273 
   274   private:
   275 
   276     LemonReader* reader;
   277     bool own_reader;
   278 
   279     Graph& graph;
   280 
   281     DefaultSkipper skipper;
   282 
   283     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   284     EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
   285 
   286     NodeReader<Graph> node_reader;
   287     EdgeReader<Graph> edge_reader;
   288     
   289     AttributeReader<ReaderTraits> attribute_reader;
   290   };
   291 
   292   /// \brief Read a graph from the input.
   293   ///
   294   /// Read a graph from the input.
   295   /// \param is The input stream.
   296   /// \param g The graph.
   297   /// \param capacity The capacity map.
   298   /// \param s The source node.
   299   /// \param t The target node.
   300   /// \param cost The cost map.
   301   template<typename Graph, typename CapacityMap, typename CostMap>
   302   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   303 		  typename Graph::Node &s, typename Graph::Node &t, 
   304 		  CostMap& cost) {
   305     GraphReader<Graph> reader(is, g);
   306     reader.readEdgeMap("capacity", capacity);
   307     reader.readEdgeMap("cost", cost);
   308     reader.readNode("source", s);
   309     reader.readNode("target", t);
   310     reader.run();
   311   }
   312 
   313   /// \brief Read a graph from the input.
   314   ///
   315   /// Read a graph from the input.
   316   /// \param is The input stream.
   317   /// \param g The graph.
   318   /// \param capacity The capacity map.
   319   /// \param s The source node.
   320   /// \param t The target node.
   321   template<typename Graph, typename CapacityMap>
   322   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   323 		  typename Graph::Node &s, typename Graph::Node &t) {
   324     GraphReader<Graph> reader(is, g);
   325     reader.readEdgeMap("capacity", capacity);
   326     reader.readNode("source", s);
   327     reader.readNode("target", t);
   328     reader.run();
   329   }
   330 
   331   /// \brief Read a graph from the input.
   332   ///
   333   /// Read a graph from the input.
   334   /// \param is The input stream.
   335   /// \param g The graph.
   336   /// \param capacity The capacity map.
   337   /// \param s The source node.
   338   template<typename Graph, typename CapacityMap>
   339   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
   340 		  typename Graph::Node &s) {
   341     GraphReader<Graph> reader(is, g);
   342     reader.readEdgeMap("capacity", capacity);
   343     reader.readNode("source", s);
   344     reader.run();
   345   }
   346 
   347   /// \brief Read a graph from the input.
   348   ///
   349   /// Read a graph from the input.
   350   /// \param is The input stream.
   351   /// \param g The graph.
   352   /// \param capacity The capacity map.
   353   template<typename Graph, typename CapacityMap>
   354   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
   355     GraphReader<Graph> reader(is, g);
   356     reader.readEdgeMap("capacity", capacity);
   357     reader.run();
   358   }
   359 
   360   /// \brief Read a graph from the input.
   361   ///
   362   /// Read a graph from the input.
   363   /// \param is The input stream.
   364   /// \param g The graph.
   365   template<typename Graph>
   366   void readGraph(std::istream& is, Graph &g) {
   367     GraphReader<Graph> reader(is, g);
   368     reader.run();
   369   }
   370 
   371   /// @}
   372 }
   373 
   374 #endif