diff --git a/lemon/lgf_reader.h b/lemon/lgf_reader.h --- a/lemon/lgf_reader.h +++ b/lemon/lgf_reader.h @@ -2,7 +2,7 @@ * * This file is a part of LEMON, a generic C++ optimization library. * - * Copyright (C) 2003-2008 + * Copyright (C) 2003-2009 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Research Group on Combinatorial Optimization, EGRES). * @@ -101,23 +101,23 @@ } }; - template > - class GraphArcMapStorage : public MapStorageBase { + class GraphArcMapStorage : public MapStorageBase { public: typedef _Map Map; typedef _Converter Converter; - typedef _Graph Graph; - typedef typename Graph::Edge Item; + typedef _GR GR; + typedef typename GR::Edge Item; static const bool dir = _dir; private: - const Graph& _graph; + const GR& _graph; Map& _map; Converter _converter; public: - GraphArcMapStorage(const Graph& graph, Map& map, + GraphArcMapStorage(const GR& graph, Map& map, const Converter& converter = Converter()) : _graph(graph), _map(map), _converter(converter) {} virtual ~GraphArcMapStorage() {} @@ -173,21 +173,21 @@ } }; - template + template struct GraphArcLookUpConverter { - const Graph& _graph; - const std::map& _map; - - GraphArcLookUpConverter(const Graph& graph, + const GR& _graph; + const std::map& _map; + + GraphArcLookUpConverter(const GR& graph, const std::map& map) + typename GR::Edge>& map) : _graph(graph), _map(map) {} - typename Graph::Arc operator()(const std::string& str) { + typename GR::Arc operator()(const std::string& str) { if (str.empty() || (str[0] != '+' && str[0] != '-')) { throw FormatError("Item must start with '+' or '-'"); } - typename std::map + typename std::map ::const_iterator it = _map.find(str.substr(1)); if (it == _map.end()) { throw FormatError("Item not found"); @@ -387,16 +387,15 @@ } - template + template class DigraphReader; - template - DigraphReader digraphReader(Digraph& digraph, - std::istream& is = std::cin); - template - DigraphReader digraphReader(Digraph& digraph, const std::string& fn); - template - DigraphReader digraphReader(Digraph& digraph, const char *fn); + template + DigraphReader digraphReader(TDGR& digraph, std::istream& is = std::cin); + template + DigraphReader digraphReader(TDGR& digraph, const std::string& fn); + template + DigraphReader digraphReader(TDGR& digraph, const char *fn); /// \ingroup lemon_io /// @@ -419,7 +418,7 @@ /// rules. /// ///\code - /// DigraphReader(digraph, std::cin). + /// DigraphReader(digraph, std::cin). /// nodeMap("coordinates", coord_map). /// arcMap("capacity", cap_map). /// node("source", src). @@ -448,21 +447,21 @@ /// It is impossible to read this in /// a single pass, because the arcs are not constructed when the node /// maps are read. - template + template class DigraphReader { public: - typedef _Digraph Digraph; - TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + typedef DGR Digraph; private: + TEMPLATE_DIGRAPH_TYPEDEFS(DGR); std::istream* _is; bool local_is; std::string _filename; - Digraph& _digraph; + DGR& _digraph; std::string _nodes_caption; std::string _arcs_caption; @@ -500,7 +499,7 @@ /// /// Construct a directed graph reader, which reads from the given /// input stream. - DigraphReader(Digraph& digraph, std::istream& is = std::cin) + DigraphReader(DGR& digraph, std::istream& is = std::cin) : _is(&is), local_is(false), _digraph(digraph), _use_nodes(false), _use_arcs(false), _skip_nodes(false), _skip_arcs(false) {} @@ -509,7 +508,7 @@ /// /// Construct a directed graph reader, which reads from the given /// file. - DigraphReader(Digraph& digraph, const std::string& fn) + DigraphReader(DGR& digraph, const std::string& fn) : _is(new std::ifstream(fn.c_str())), local_is(true), _filename(fn), _digraph(digraph), _use_nodes(false), _use_arcs(false), @@ -524,7 +523,7 @@ /// /// Construct a directed graph reader, which reads from the given /// file. - DigraphReader(Digraph& digraph, const char* fn) + DigraphReader(DGR& digraph, const char* fn) : _is(new std::ifstream(fn)), local_is(true), _filename(fn), _digraph(digraph), _use_nodes(false), _use_arcs(false), @@ -560,13 +559,13 @@ private: - template - friend DigraphReader digraphReader(DGR& digraph, std::istream& is); - template - friend DigraphReader digraphReader(DGR& digraph, - const std::string& fn); - template - friend DigraphReader digraphReader(DGR& digraph, const char *fn); + template + friend DigraphReader digraphReader(TDGR& digraph, std::istream& is); + template + friend DigraphReader digraphReader(TDGR& digraph, + const std::string& fn); + template + friend DigraphReader digraphReader(TDGR& digraph, const char *fn); DigraphReader(DigraphReader& other) : _is(other._is), local_is(other.local_is), _digraph(other._digraph), @@ -593,7 +592,7 @@ public: - /// \name Reading rules + /// \name Reading Rules /// @{ /// \brief Node map reading rule @@ -698,7 +697,7 @@ /// @} - /// \name Select section by name + /// \name Select Section by Name /// @{ /// \brief Set \c \@nodes section to be read @@ -727,7 +726,7 @@ /// @} - /// \name Using previously constructed node or arc set + /// \name Using Previously Constructed Node or Arc Set /// @{ /// \brief Use previously constructed node set @@ -847,7 +846,9 @@ while (readSuccess() && line >> c && c != '@') { readLine(); } - line.putback(c); + if (readSuccess()) { + line.putback(c); + } } void readNodes() { @@ -1114,7 +1115,7 @@ public: - /// \name Execution of the reader + /// \name Execution of the Reader /// @{ /// \brief Start the batch processing @@ -1186,14 +1187,52 @@ /// @} }; + + /// \ingroup lemon_io + /// + /// \brief Return a \ref DigraphReader class + /// + /// This function just returns a \ref DigraphReader class. + /// + /// With this function a digraph can be read from an + /// \ref lgf-format "LGF" file or input stream with several maps and + /// attributes. For example, there is network flow problem on a + /// digraph, i.e. a digraph with a \e capacity map on the arcs and + /// \e source and \e target nodes. This digraph can be read with the + /// following code: + /// + ///\code + ///ListDigraph digraph; + ///ListDigraph::ArcMap cm(digraph); + ///ListDigraph::Node src, trg; + ///digraphReader(digraph, std::cin). + /// arcMap("capacity", cap). + /// node("source", src). + /// node("target", trg). + /// run(); + ///\endcode + /// + /// For a complete documentation, please see the \ref DigraphReader + /// class documentation. + /// \warning Don't forget to put the \ref DigraphReader::run() "run()" + /// to the end of the parameter list. + /// \relates DigraphReader + /// \sa digraphReader(TDGR& digraph, const std::string& fn) + /// \sa digraphReader(TDGR& digraph, const char* fn) + template + DigraphReader digraphReader(TDGR& digraph, std::istream& is) { + DigraphReader tmp(digraph, is); + return tmp; + } /// \brief Return a \ref DigraphReader class /// /// This function just returns a \ref DigraphReader class. /// \relates DigraphReader - template - DigraphReader digraphReader(Digraph& digraph, std::istream& is) { - DigraphReader tmp(digraph, is); + /// \sa digraphReader(TDGR& digraph, std::istream& is) + template + DigraphReader digraphReader(TDGR& digraph, const std::string& fn) { + DigraphReader tmp(digraph, fn); return tmp; } @@ -1201,33 +1240,22 @@ /// /// This function just returns a \ref DigraphReader class. /// \relates DigraphReader - template - DigraphReader digraphReader(Digraph& digraph, - const std::string& fn) { - DigraphReader tmp(digraph, fn); + /// \sa digraphReader(TDGR& digraph, std::istream& is) + template + DigraphReader digraphReader(TDGR& digraph, const char* fn) { + DigraphReader tmp(digraph, fn); return tmp; } - /// \brief Return a \ref DigraphReader class - /// - /// This function just returns a \ref DigraphReader class. - /// \relates DigraphReader - template - DigraphReader digraphReader(Digraph& digraph, const char* fn) { - DigraphReader tmp(digraph, fn); - return tmp; - } - - template + template class GraphReader; - template - GraphReader graphReader(Graph& graph, - std::istream& is = std::cin); - template - GraphReader graphReader(Graph& graph, const std::string& fn); - template - GraphReader graphReader(Graph& graph, const char *fn); + template + GraphReader graphReader(TGR& graph, std::istream& is = std::cin); + template + GraphReader graphReader(TGR& graph, const std::string& fn); + template + GraphReader graphReader(TGR& graph, const char *fn); /// \ingroup lemon_io /// @@ -1244,20 +1272,21 @@ /// prefixed with \c '+' and \c '-', then these can be read into an /// arc map. Similarly, an attribute can be read into an arc, if /// it's value is an edge label prefixed with \c '+' or \c '-'. - template + template class GraphReader { public: - typedef _Graph Graph; - TEMPLATE_GRAPH_TYPEDEFS(Graph); + typedef GR Graph; private: + TEMPLATE_GRAPH_TYPEDEFS(GR); + std::istream* _is; bool local_is; std::string _filename; - Graph& _graph; + GR& _graph; std::string _nodes_caption; std::string _edges_caption; @@ -1295,7 +1324,7 @@ /// /// Construct an undirected graph reader, which reads from the given /// input stream. - GraphReader(Graph& graph, std::istream& is = std::cin) + GraphReader(GR& graph, std::istream& is = std::cin) : _is(&is), local_is(false), _graph(graph), _use_nodes(false), _use_edges(false), _skip_nodes(false), _skip_edges(false) {} @@ -1304,7 +1333,7 @@ /// /// Construct an undirected graph reader, which reads from the given /// file. - GraphReader(Graph& graph, const std::string& fn) + GraphReader(GR& graph, const std::string& fn) : _is(new std::ifstream(fn.c_str())), local_is(true), _filename(fn), _graph(graph), _use_nodes(false), _use_edges(false), @@ -1319,7 +1348,7 @@ /// /// Construct an undirected graph reader, which reads from the given /// file. - GraphReader(Graph& graph, const char* fn) + GraphReader(GR& graph, const char* fn) : _is(new std::ifstream(fn)), local_is(true), _filename(fn), _graph(graph), _use_nodes(false), _use_edges(false), @@ -1354,12 +1383,12 @@ } private: - template - friend GraphReader graphReader(GR& graph, std::istream& is); - template - friend GraphReader graphReader(GR& graph, const std::string& fn); - template - friend GraphReader graphReader(GR& graph, const char *fn); + template + friend GraphReader graphReader(TGR& graph, std::istream& is); + template + friend GraphReader graphReader(TGR& graph, const std::string& fn); + template + friend GraphReader graphReader(TGR& graph, const char *fn); GraphReader(GraphReader& other) : _is(other._is), local_is(other.local_is), _graph(other._graph), @@ -1386,7 +1415,7 @@ public: - /// \name Reading rules + /// \name Reading Rules /// @{ /// \brief Node map reading rule @@ -1451,7 +1480,7 @@ new _reader_bits::GraphArcMapStorage(_graph, map); _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); _reader_bits::MapStorageBase* backward_storage = - new _reader_bits::GraphArcMapStorage(_graph, map); + new _reader_bits::GraphArcMapStorage(_graph, map); _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); return *this; } @@ -1465,11 +1494,11 @@ const Converter& converter = Converter()) { checkConcept, Map>(); _reader_bits::MapStorageBase* forward_storage = - new _reader_bits::GraphArcMapStorage + new _reader_bits::GraphArcMapStorage (_graph, map, converter); _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); _reader_bits::MapStorageBase* backward_storage = - new _reader_bits::GraphArcMapStorage + new _reader_bits::GraphArcMapStorage (_graph, map, converter); _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); return *this; @@ -1527,7 +1556,7 @@ /// /// Add an arc reading rule to reader. GraphReader& arc(const std::string& caption, Arc& arc) { - typedef _reader_bits::GraphArcLookUpConverter Converter; + typedef _reader_bits::GraphArcLookUpConverter Converter; Converter converter(_graph, _edge_index); _reader_bits::ValueStorageBase* storage = new _reader_bits::ValueStorage(arc, converter); @@ -1537,7 +1566,7 @@ /// @} - /// \name Select section by name + /// \name Select Section by Name /// @{ /// \brief Set \c \@nodes section to be read @@ -1566,7 +1595,7 @@ /// @} - /// \name Using previously constructed node or edge set + /// \name Using Previously Constructed Node or Edge Set /// @{ /// \brief Use previously constructed node set @@ -1687,7 +1716,9 @@ while (readSuccess() && line >> c && c != '@') { readLine(); } - line.putback(c); + if (readSuccess()) { + line.putback(c); + } } void readNodes() { @@ -1954,7 +1985,7 @@ public: - /// \name Execution of the reader + /// \name Execution of the Reader /// @{ /// \brief Start the batch processing @@ -2028,13 +2059,47 @@ }; + /// \ingroup lemon_io + /// + /// \brief Return a \ref GraphReader class + /// + /// This function just returns a \ref GraphReader class. + /// + /// With this function a graph can be read from an + /// \ref lgf-format "LGF" file or input stream with several maps and + /// attributes. For example, there is weighted matching problem on a + /// graph, i.e. a graph with a \e weight map on the edges. This + /// graph can be read with the following code: + /// + ///\code + ///ListGraph graph; + ///ListGraph::EdgeMap weight(graph); + ///graphReader(graph, std::cin). + /// edgeMap("weight", weight). + /// run(); + ///\endcode + /// + /// For a complete documentation, please see the \ref GraphReader + /// class documentation. + /// \warning Don't forget to put the \ref GraphReader::run() "run()" + /// to the end of the parameter list. + /// \relates GraphReader + /// \sa graphReader(TGR& graph, const std::string& fn) + /// \sa graphReader(TGR& graph, const char* fn) + template + GraphReader graphReader(TGR& graph, std::istream& is) { + GraphReader tmp(graph, is); + return tmp; + } + /// \brief Return a \ref GraphReader class /// /// This function just returns a \ref GraphReader class. /// \relates GraphReader - template - GraphReader graphReader(Graph& graph, std::istream& is) { - GraphReader tmp(graph, is); + /// \sa graphReader(TGR& graph, std::istream& is) + template + GraphReader graphReader(TGR& graph, const std::string& fn) { + GraphReader tmp(graph, fn); return tmp; } @@ -2042,19 +2107,10 @@ /// /// This function just returns a \ref GraphReader class. /// \relates GraphReader - template - GraphReader graphReader(Graph& graph, const std::string& fn) { - GraphReader tmp(graph, fn); - return tmp; - } - - /// \brief Return a \ref GraphReader class - /// - /// This function just returns a \ref GraphReader class. - /// \relates GraphReader - template - GraphReader graphReader(Graph& graph, const char* fn) { - GraphReader tmp(graph, fn); + /// \sa graphReader(TGR& graph, std::istream& is) + template + GraphReader graphReader(TGR& graph, const char* fn) { + GraphReader tmp(graph, fn); return tmp; } @@ -2153,7 +2209,7 @@ public: - /// \name Section readers + /// \name Section Readers /// @{ /// \brief Add a section processor with line oriented reading @@ -2244,13 +2300,15 @@ while (readSuccess() && line >> c && c != '@') { readLine(); } - line.putback(c); + if (readSuccess()) { + line.putback(c); + } } public: - /// \name Execution of the reader + /// \name Execution of the Reader /// @{ /// \brief Start the batch processing @@ -2309,12 +2367,30 @@ }; + /// \ingroup lemon_io + /// + /// \brief Return a \ref SectionReader class + /// + /// This function just returns a \ref SectionReader class. + /// + /// Please see SectionReader documentation about the custom section + /// input. + /// + /// \relates SectionReader + /// \sa sectionReader(const std::string& fn) + /// \sa sectionReader(const char *fn) + inline SectionReader sectionReader(std::istream& is) { + SectionReader tmp(is); + return tmp; + } + /// \brief Return a \ref SectionReader class /// /// This function just returns a \ref SectionReader class. /// \relates SectionReader - inline SectionReader sectionReader(std::istream& is) { - SectionReader tmp(is); + /// \sa sectionReader(std::istream& is) + inline SectionReader sectionReader(const std::string& fn) { + SectionReader tmp(fn); return tmp; } @@ -2322,15 +2398,7 @@ /// /// This function just returns a \ref SectionReader class. /// \relates SectionReader - inline SectionReader sectionReader(const std::string& fn) { - SectionReader tmp(fn); - return tmp; - } - - /// \brief Return a \ref SectionReader class - /// - /// This function just returns a \ref SectionReader class. - /// \relates SectionReader + /// \sa sectionReader(std::istream& is) inline SectionReader sectionReader(const char* fn) { SectionReader tmp(fn); return tmp; @@ -2432,7 +2500,7 @@ public: - /// \name Node sections + /// \name Node Sections /// @{ /// \brief Gives back the number of node sections in the file. @@ -2458,7 +2526,7 @@ /// @} - /// \name Arc/Edge sections + /// \name Arc/Edge Sections /// @{ /// \brief Gives back the number of arc/edge sections in the file. @@ -2516,7 +2584,7 @@ /// @} - /// \name Attribute sections + /// \name Attribute Sections /// @{ /// \brief Gives back the number of attribute sections in the file. @@ -2542,7 +2610,7 @@ /// @} - /// \name Extra sections + /// \name Extra Sections /// @{ /// \brief Gives back the number of extra sections in the file. @@ -2585,7 +2653,9 @@ while (readSuccess() && line >> c && c != '@') { readLine(); } - line.putback(c); + if (readSuccess()) { + line.putback(c); + } } void readMaps(std::vector& maps) { @@ -2616,7 +2686,7 @@ public: - /// \name Execution of the contents reader + /// \name Execution of the Contents Reader /// @{ /// \brief Starts the reading