COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/graph_reader.h @ 1396:56f9a4ba9149

Last change on this file since 1396:56f9a4ba9149 was 1396:56f9a4ba9149, checked in by Balazs Dezso, 19 years ago

GUI section handling.

File size: 23.6 KB
Line 
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#include <sstream>
26
27#include <map>
28#include <vector>
29
30#include <memory>
31
32#include <lemon/error.h>
33
34
35namespace lemon {
36
37  /// \addtogroup io_group
38  /// @{
39
40  /// \brief Standard ReaderTraits for the GraphReader class.
41  ///
42  /// Standard ReaderTraits for the GraphReader class.
43  /// It defines standard reading method for all type of value.
44  /// \author Balazs Dezso
45  struct DefaultReaderTraits {
46
47    /// \brief Template class for reading an value.
48    ///
49    /// Template class for reading an value.
50    /// \author Balazs Dezso
51    template <typename _Value>
52    struct Reader {
53      /// The value type.
54      typedef _Value Value;
55      /// \brief Reads a value from the given stream.
56      ///
57      /// Reads a value from the given stream.
58      void read(std::istream& is, Value& value) {
59        if (!(is >> value))
60          throw DataFormatError("Default reader format exception");
61      }
62    };
63
64    /// \brief Returns wheter this name is an ID map name.
65    ///
66    /// Returns wheter this name is an ID map name.
67    static bool idMapName(const std::string& name) {
68      return name == "id";
69    }
70
71    /// The reader class for the not needed maps.
72    typedef Reader<std::string> DefaultReader;
73
74  };
75
76  /// \brief Reader class for quoted strings.
77  ///
78  /// Reader class for quoted strings. It can process the escape
79  /// sequences in the string.
80  /// \author Balazs Dezso
81  class QuotedStringReader {
82  public:
83    typedef std::string Value;
84   
85    /// \brief Constructor for the reader.
86    ///
87    /// Constructor for the reader. If the given parameter is true
88    /// the reader processes the escape sequences.
89    QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
90   
91    /// \brief Reads a quoted string from the given stream.
92    ///
93    /// Reads a quoted string from the given stream.
94    void read(std::istream& is, std::string& value) {
95      char c;
96      value.clear();
97      is >> std::ws;
98      if (!is.get(c) || c != '\"')
99        throw DataFormatError("Quoted string format error");
100      while (is.get(c) && c != '\"') {
101        if (escaped && c == '\\') {
102          value += readEscape(is);
103        } else {
104          value += c;
105        }
106      }
107      if (!is) throw DataFormatError("Quoted string format error");
108    }
109
110  private:
111   
112    static char readEscape(std::istream& is) {
113      char c;
114      switch (is.get(c), c) {
115      case '\\':
116        return '\\';
117      case '\"':
118        return '\"';
119      case '\'':
120        return '\'';
121      case '\?':
122        return '\?';
123      case 'a':
124        return '\a';
125      case 'b':
126        return '\b';
127      case 'f':
128        return '\f';
129      case 'n':
130        return '\n';
131      case 'r':
132        return '\r';
133      case 't':
134        return '\t';
135      case 'v':
136        return '\v';
137      case 'x':
138        {
139          int code;
140          if (!is.get(c) || !isHex(c))
141            throw DataFormatError("Escape format error");
142          else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
143          else code = code * 16 + valueHex(c);
144          return code;
145        }
146      default:
147        {
148          int code;
149          if (!isOct(c))
150            throw DataFormatError("Escape format error");
151          else if (code = valueOct(c), !is.get(c) || !isOct(c))
152            is.putback(c);
153          else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
154            is.putback(c);
155          else code = code * 8 + valueOct(c);
156          return code;
157        }             
158      }
159    }
160
161    static bool isOct(char c) {
162      return '0' <= c && c <='7';
163    }
164   
165    static int valueOct(char c) {
166      return c - '0';
167    }
168
169   static bool isHex(char c) {
170      return ('0' <= c && c <= '9') ||
171        ('a' <= c && c <= 'z') ||
172        ('A' <= c && c <= 'Z');
173    }
174   
175    static int valueHex(char c) {
176      if ('0' <= c && c <= '9') return c - '0';
177      if ('a' <= c && c <= 'z') return c - 'a' + 10;
178      return c - 'A' + 10;
179    }
180
181    bool escaped;
182  };
183
184  class GUIReader {
185  public:
186    virtual void read(std::istream& is) = 0;
187  };
188
189  /// \brief The graph reader class.
190  ///
191  ///
192  /// The given file format may contain several maps and labeled nodes or
193  /// edges.
194  ///
195  /// If you read a graph you need not read all the maps and items just those
196  /// that you need. The interface of the \c GraphReader is very similar to
197  /// the GraphWriter but the reading method does not depend on the order the
198  /// given commands.
199  ///
200  /// The reader object suppose that each not readed value does not contain
201  /// whitespaces, therefore it has some extra possibilities to control how
202  /// it should skip the values when the string representation contains spaces.
203  ///
204  /// \code
205  /// GraphReader<ListGraph> reader(std::cin, graph);
206  /// \endcode
207  ///
208  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
209  /// If there is a map that you do not want to read from the file and there is
210  /// whitespace in the string represenation of the values then you should
211  /// call the \c skipNodeMap() template member function with proper
212  /// parameters.
213  ///
214  /// \code
215  /// reader.readNodeMap("x-coord", xCoordMap);
216  /// reader.readNodeMap("y-coord", yCoordMap);
217  ///
218  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
219  /// reader.skipNodeMap<QuotedStringReader>("description");
220  ///
221  /// reader.readNodeMap("color", colorMap);
222  /// \endcode
223  ///
224  /// With the \c readEdgeMap() member function you can give an edge map
225  /// reading command similar to the NodeMaps.
226  ///
227  /// \code
228  /// reader.readEdgeMap("weight", weightMap);
229  /// reader.readEdgeMap("label", labelMap);
230  /// \endcode
231  ///
232  /// With \c readNode() and \c readEdge() functions you can read labeled Nodes
233  /// and Edges.
234  ///
235  /// \code
236  /// reader.readNode("source", sourceNode);
237  /// reader.readNode("target", targetNode);
238  ///
239  /// reader.readEdge("observed", edge);
240  /// \endcode
241  ///
242  /// After you give all read commands you must call the \c run() member
243  /// function, which execute all the commands.
244  ///
245  /// \code
246  /// reader.run();
247  /// \endcode
248  ///
249  /// \see DefaultReaderTraits
250  /// \see QuotedStringReader
251  /// \see \ref GraphWriter
252  /// \see \ref graph-io-page
253  /// \author Balazs Dezso
254  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
255  class GraphReader {
256  public:
257   
258    typedef _Graph Graph;
259    typedef typename Graph::Node Node;
260    typedef typename Graph::Edge Edge;
261
262    typedef _ReaderTraits ReaderTraits;
263    typedef typename ReaderTraits::DefaultReader DefaultReader;
264
265    /// \brief Construct a new GraphReader.
266    ///
267    /// Construct a new GraphReader. It reads into the given graph
268    /// and it use the given reader as the default skipper.
269    GraphReader(std::istream& _is, Graph& _graph,
270                const DefaultReader& _reader = DefaultReader())
271      : gui_reader(0), is(_is), graph(_graph),
272        nodeSkipper(_reader), edgeSkipper(_reader) {}
273
274    /// \brief Destruct the graph reader.
275    ///
276    /// Destruct the graph reader.
277    ~GraphReader() {
278      for (typename NodeMapReaders::iterator it = node_map_readers.begin();
279           it != node_map_readers.end(); ++it) {
280        delete it->second;
281      }
282
283      for (typename EdgeMapReaders::iterator it = edge_map_readers.begin();
284           it != edge_map_readers.end(); ++it) {
285        delete it->second;
286      }
287
288    }
289
290    /// \brief Add a new node map reader command for the reader.
291    ///
292    /// Add a new node map reader command for the reader.
293    template <typename Map>
294    GraphReader& readNodeMap(std::string name, Map& map) {
295      return readNodeMap<typename ReaderTraits::template
296        Reader<typename Map::Value>, Map>(name, map);
297    }
298
299    /// \brief Add a new node map reader command for the reader.
300    ///
301    /// Add a new node map reader command for the reader.
302    template <typename Reader, typename Map>
303    GraphReader& readNodeMap(std::string name, Map& map,
304                             const Reader& reader = Reader()) {
305      if (node_map_readers.find(name) != node_map_readers.end()) {
306        ErrorMessage msg;
307        msg << "Multiple read rule for node map: " << name;
308        throw IOParameterError(msg.message());
309      }
310      node_map_readers.insert(
311        make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
312      return *this;
313    }
314
315    /// \brief Add a new node map skipper command for the reader.
316    ///
317    /// Add a new node map skipper command for the reader.
318    template <typename Reader>
319    GraphReader& skipNodeMap(std::string name,
320                             const Reader& reader = Reader()) {
321      if (node_map_readers.find(name) != node_map_readers.end()) {
322        ErrorMessage msg;
323        msg << "Multiple read rule for node map: " << name;
324        throw IOParameterError(msg.message());
325      }
326      node_map_readers.insert(
327        make_pair(name, new SkipReader<Node, Reader>(reader)));
328      return *this;
329    }
330
331    /// \brief Add a new edge map reader command for the reader.
332    ///
333    /// Add a new edge map reader command for the reader.
334    template <typename Map>
335    GraphReader& readEdgeMap(std::string name, Map& map) {
336      return readEdgeMap<typename ReaderTraits::template
337        Reader<typename Map::Value>, Map>(name, map);
338    }
339
340
341    /// \brief Add a new edge map reader command for the reader.
342    ///
343    /// Add a new edge map reader command for the reader.
344    template <typename Reader, typename Map>
345    GraphReader& readEdgeMap(std::string name, Map& map,
346                             const Reader& reader = Reader()) {
347      if (edge_map_readers.find(name) != edge_map_readers.end()) {
348        ErrorMessage msg;
349        msg << "Multiple read rule for edge map: " << name;
350        throw IOParameterError(msg.message());
351      }
352      edge_map_readers.insert(
353        make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
354      return *this;
355    }
356
357    /// \brief Add a new edge map skipper command for the reader.
358    ///
359    /// Add a new edge map skipper command for the reader.
360    template <typename Reader>
361    GraphReader& skipEdgeMap(std::string name,
362                             const Reader& reader = Reader()) {
363      if (edge_map_readers.find(name) != edge_map_readers.end()) {
364        ErrorMessage msg;
365        msg << "Multiple read rule for edge map: " << name;
366        throw IOParameterError(msg.message());
367      }
368      edge_map_readers.insert(
369        make_pair(name, new SkipReader<Edge, Reader>(reader)));
370      return *this;
371    }
372
373    /// \brief Add a new labeled node reader for the reader.
374    ///
375    /// Add a new labeled node reader for the reader.
376    GraphReader& readNode(std::string name, Node& node) {
377      if (node_readers.find(name) != node_readers.end()) {
378        ErrorMessage msg;
379        msg << "Multiple read rule for node: " << name;
380        throw IOParameterError(msg.message());
381      }
382      node_readers.insert(make_pair(name, &node));
383      return *this;
384    }
385
386    /// \brief Add a new labeled edge reader for the reader.
387    ///
388    /// Add a new labeled edge reader for the reader.
389    GraphReader& readEdge(std::string name, Edge& edge) {
390      if (edge_readers.find(name) != edge_readers.end()) {
391        ErrorMessage msg;
392        msg << "Multiple read rule for edge: " << name;
393        throw IOParameterError(msg.message());
394      }
395      edge_readers.insert(make_pair(name, &edge));
396      return *this;
397    }
398
399    /// \brief Executes the reader commands.
400    ///
401    /// Executes the reader commands.
402    void run() {
403      int line_num = 0;
404      std::auto_ptr<InverterBase<Node> > nodeInverter;
405      std::auto_ptr<InverterBase<Edge> > edgeInverter;
406      try {
407        std::string line = readNotEmptyLine(is, line_num);
408        if (line.find("@nodeset") == 0) {
409          line = readNodeSet(line_num, nodeInverter);
410        }
411        if (line.find("@edgeset") == 0) {
412          line = readEdgeSet(line_num, edgeInverter, nodeInverter);
413        }
414        if (line.find("@nodes") == 0) {
415          line = readNodes(line_num, nodeInverter);
416        }
417        if (line.find("@edges") == 0) {
418          line = readEdges(line_num, edgeInverter);
419        }
420        if (line.find("@gui") == 0) {
421          line = readGUI(line_num);
422        }
423        if (line.find("@end") != 0) {
424          throw DataFormatError("Invalid control sequence error");
425        }
426      } catch (DataFormatError e) {
427        e.line(line_num);
428        throw e;
429      }
430    }
431
432    GraphReader& readGUI(GUIReader& reader) {
433      gui_reader = &reader;
434      return *this;
435    }
436
437  private:
438
439    template <typename Item> class InverterBase;
440
441    std::string readNodeSet(int& line_num,
442                            std::auto_ptr<InverterBase<Node> >& nodeInverter) {
443      std::vector<ReaderBase<Node>* > index;
444      {
445        std::string line = readNotEmptyLine(is, line_num);   
446        std::string id;
447        std::istringstream ls(line);   
448        while (ls >> id) {
449          typename NodeMapReaders::iterator it = node_map_readers.find(id);
450          if (it != node_map_readers.end()) {
451            index.push_back(it->second);
452            node_map_readers.erase(it);
453          } else {
454            index.push_back(&nodeSkipper);
455          }
456          if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) {
457            nodeInverter.reset(index.back()->getInverter());
458            index.back() = nodeInverter.get();
459          }
460        }
461      }
462
463//       if (index.size() == 0) {
464//      throw DataFormatError("Cannot find node id map");
465//       }
466
467//       nodeInverter =
468//      std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
469      std::string line;
470      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
471        Node node = graph.addNode();
472        std::istringstream ls(line);
473        for (int i = 0; i < (int)index.size(); ++i) {
474          index[i]->read(ls, node);
475        }
476      }
477      return line;
478    }
479
480    std::string readEdgeSet(int& line_num,
481                            std::auto_ptr<InverterBase<Edge> >& edgeInverter,
482                            std::auto_ptr<InverterBase<Node> >& nodeInverter) {
483      std::vector<ReaderBase<Edge>*> index;
484      {
485        std::string line = readNotEmptyLine(is, line_num);   
486        std::string id;
487        std::istringstream ls(line);   
488        while (ls >> id) {
489          typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
490          if (it != edge_map_readers.end()) {
491            index.push_back(it->second);
492            edge_map_readers.erase(it);
493          } else {
494            index.push_back(&edgeSkipper);
495          }
496          if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) {
497            edgeInverter.reset(index.back()->getInverter());
498            index.back() = edgeInverter.get();
499          }
500        }
501      }
502     
503      if (nodeInverter.get() == 0) {
504        throw DataFormatError("Cannot find node id map");
505      }
506//       if (index.size() == 0) {
507//      throw DataFormatError("Cannot find edge id map");
508//       }
509
510//       edgeInverter =
511//      std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
512      std::string line;
513      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {   
514        std::istringstream ls(line);
515        Node source = nodeInverter->read(ls);
516        Node target = nodeInverter->read(ls);
517        Edge edge = graph.addEdge(source, target);
518        for (int i = 0; i < (int)index.size(); ++i) {
519          index[i]->read(ls, edge);
520        }
521      }     
522      return line;
523    }
524
525    std::string readNodes(int& line_num,
526                          std::auto_ptr<InverterBase<Node> >& nodeInverter) {
527      std::string line;
528      if (nodeInverter.get() == 0) {
529        throw DataFormatError("Cannot find node id map");
530      }
531      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
532        std::istringstream ls(line);
533        std::string name;
534        ls >> name;
535        typename NodeReaders::iterator it = node_readers.find(name);
536        if (it != node_readers.end()) {
537          *(it -> second) = nodeInverter->read(ls);
538        }
539      }       
540      return line;
541    }
542
543    std::string readEdges(int& line_num,
544                          std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
545      std::string line;
546      if (edgeInverter.get() == 0) {
547        throw DataFormatError("Cannot find edge id map");
548      }
549      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
550        std::istringstream ls(line);
551        std::string name;
552        ls >> name;
553        typename EdgeReaders::iterator it = edge_readers.find(name);
554        if (it != edge_readers.end()) {
555          *(it -> second) = edgeInverter->read(ls);
556        }
557      }       
558      return line;   
559    }
560
561    std::string readGUI(int& line_num) {
562      std::stringstream section;
563      std::string line;
564      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
565        section << line << std::endl;
566      }
567      if (gui_reader != 0) {
568        gui_reader->read(section);
569      }
570      return line;
571    }
572
573    std::string readNotEmptyLine(std::istream& is, int& line_num) {
574      std::string line;
575      while (++line_num, getline(is, line)) {   
576        int vi = line.find('#');
577        if (vi != (int)::std::string::npos) {
578          line = line.substr(0, vi);
579        }
580        vi = line.find_first_not_of(" \t");
581        if (vi != (int)std::string::npos) {
582          return line.substr(vi);
583        }
584      }
585      throw DataFormatError("End of stream error");
586    }
587   
588    template <typename _Item>
589    class ReaderBase;
590   
591    template <typename _Item>
592    class InverterBase : public ReaderBase<_Item> {
593    public:
594      typedef _Item Item;
595      virtual void read(std::istream&, const Item&) = 0;
596      virtual Item read(std::istream&) = 0;
597
598      virtual InverterBase<_Item>* getInverter() {
599        return this;
600      }
601    };
602
603    template <typename _Item, typename _Map, typename _Reader>
604    class MapReaderInverter : public InverterBase<_Item> {
605    public:
606      typedef _Item Item;
607      typedef _Reader Reader;
608      typedef typename Reader::Value Value;
609      typedef _Map Map;
610      typedef std::map<Value, Item> Inverse;
611
612      Map& map;
613      Reader reader;
614      Inverse inverse;
615
616      MapReaderInverter(Map& _map, const Reader& _reader)
617        : map(_map), reader(_reader) {}
618
619      virtual ~MapReaderInverter() {}
620
621      virtual void read(std::istream& is, const Item& item) {
622        Value value;
623        reader.read(is, value);
624        map.set(item, value);
625        typename Inverse::iterator it = inverse.find(value);
626        if (it == inverse.end()) {
627          inverse.insert(std::make_pair(value, item));
628        } else {
629          throw DataFormatError("Multiple ID occurence");
630        }
631      }
632
633      virtual Item read(std::istream& is) {
634        Value value;
635        reader.read(is, value);
636        typename Inverse::const_iterator it = inverse.find(value);
637        if (it != inverse.end()) {
638          return it->second;
639        } else {
640          throw DataFormatError("Invalid ID error");
641        }
642      }     
643    };
644
645    template <typename _Item, typename _Reader>
646    class SkipReaderInverter : public InverterBase<_Item> {
647    public:
648      typedef _Item Item;
649      typedef _Reader Reader;
650      typedef typename Reader::Value Value;
651      typedef std::map<Value, Item> Inverse;
652
653      Reader reader;
654
655      SkipReaderInverter(const Reader& _reader)
656        : reader(_reader) {}
657
658      virtual ~SkipReaderInverter() {}
659
660      virtual void read(std::istream& is, const Item& item) {
661        Value value;
662        reader.read(is, value);
663        typename Inverse::iterator it = inverse.find(value);
664        if (it == inverse.end()) {
665          inverse.insert(std::make_pair(value, item));
666        } else {
667          throw DataFormatError("Multiple ID occurence error");
668        }
669      }
670
671      virtual Item read(std::istream& is) {
672        Value value;
673        reader.read(is, value);
674        typename Inverse::const_iterator it = inverse.find(value);
675        if (it != inverse.end()) {
676          return it->second;
677        } else {
678          throw DataFormatError("Invalid ID error");
679        }
680      }     
681    private:
682      Inverse inverse;
683    };
684
685    // Readers
686
687    template <typename _Item>   
688    class ReaderBase {
689    public:
690      typedef _Item Item;
691
692      //      virtual ~ReaderBase() {}
693
694      virtual void read(std::istream& is, const Item& item) = 0;
695      virtual InverterBase<_Item>* getInverter() = 0;
696    };
697
698    template <typename _Item, typename _Map, typename _Reader>
699    class MapReader : public ReaderBase<_Item> {
700    public:
701      typedef _Map Map;
702      typedef _Reader Reader;
703      typedef typename Reader::Value Value;
704      typedef _Item Item;
705     
706      Map& map;
707      Reader reader;
708
709      MapReader(Map& _map, const Reader& _reader)
710        : map(_map), reader(_reader) {}
711
712      virtual ~MapReader() {}
713
714      virtual void read(std::istream& is, const Item& item) {
715        Value value;
716        reader.read(is, value);
717        map.set(item, value);
718      }
719
720      virtual InverterBase<_Item>* getInverter() {
721        return new MapReaderInverter<Item, Map, Reader>(map, reader);
722      }
723    };
724
725
726    template <typename _Item, typename _Reader>
727    class SkipReader : public ReaderBase<_Item> {
728    public:
729      typedef _Reader Reader;
730      typedef typename Reader::Value Value;
731      typedef _Item Item;
732
733      Reader reader;
734      SkipReader(const Reader& _reader) : reader(_reader) {}
735
736      virtual ~SkipReader() {}
737
738      virtual void read(std::istream& is, const Item&) {
739        Value value;
740        reader.read(is, value);
741      }     
742
743      virtual InverterBase<Item>* getInverter() {
744        return new SkipReaderInverter<Item, Reader>(reader);
745      }
746    };
747
748
749    typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
750    NodeMapReaders node_map_readers;
751
752    typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
753    EdgeMapReaders edge_map_readers;
754
755    typedef std::map<std::string, Node*> NodeReaders;
756    NodeReaders node_readers;
757
758    typedef std::map<std::string, Edge*> EdgeReaders;
759    EdgeReaders edge_readers;
760
761    GUIReader* gui_reader;
762
763    std::istream& is;
764    Graph& graph;
765
766    SkipReader<Node, DefaultReader> nodeSkipper;
767    SkipReader<Edge, DefaultReader> edgeSkipper;
768
769  };
770
771  /// \brief Read a graph from the input.
772  ///
773  /// Read a graph from the input.
774  /// \param is The input stream.
775  /// \param g The graph.
776  /// \param capacity The capacity map.
777  /// \param s The source node.
778  /// \param t The target node.
779  /// \param cost The cost map.
780  template<typename Graph, typename CapacityMap, typename CostMap>
781  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
782                  typename Graph::Node &s, typename Graph::Node &t,
783                  CostMap& cost) {
784    GraphReader<Graph> reader(is, g);
785    reader.readEdgeMap("capacity", capacity);
786    reader.readEdgeMap("cost", cost);
787    reader.readNode("source", s);
788    reader.readNode("target", t);
789    reader.run();
790  }
791
792  /// \brief Read a graph from the input.
793  ///
794  /// Read a graph from the input.
795  /// \param is The input stream.
796  /// \param g The graph.
797  /// \param capacity The capacity map.
798  /// \param s The source node.
799  /// \param t The target node.
800  template<typename Graph, typename CapacityMap>
801  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
802                  typename Graph::Node &s, typename Graph::Node &t) {
803    GraphReader<Graph> reader(is, g);
804    reader.readEdgeMap("capacity", capacity);
805    reader.readNode("source", s);
806    reader.readNode("target", t);
807    reader.run();
808  }
809
810  /// \brief Read a graph from the input.
811  ///
812  /// Read a graph from the input.
813  /// \param is The input stream.
814  /// \param g The graph.
815  /// \param capacity The capacity map.
816  /// \param s The source node.
817  template<typename Graph, typename CapacityMap>
818  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
819                  typename Graph::Node &s) {
820    GraphReader<Graph> reader(is, g);
821    reader.readEdgeMap("capacity", capacity);
822    reader.readNode("source", s);
823    reader.run();
824  }
825
826  /// \brief Read a graph from the input.
827  ///
828  /// Read a graph from the input.
829  /// \param is The input stream.
830  /// \param g The graph.
831  /// \param capacity The capacity map.
832  template<typename Graph, typename CapacityMap>
833  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
834    GraphReader<Graph> reader(is, g);
835    reader.readEdgeMap("capacity", capacity);
836    reader.run();
837  }
838
839  /// \brief Read a graph from the input.
840  ///
841  /// Read a graph from the input.
842  /// \param is The input stream.
843  /// \param g The graph.
844  template<typename Graph>
845  void readGraph(std::istream& is, Graph &g) {
846    GraphReader<Graph> reader(is, g);
847    reader.run();
848  }
849
850  /// @}
851}
852
853#endif
Note: See TracBrowser for help on using the repository browser.