1.1 --- a/lemon/bits/path_dump.h Tue Aug 28 13:58:54 2007 +0000
1.2 +++ b/lemon/bits/path_dump.h Tue Aug 28 14:00:42 2007 +0000
1.3 @@ -54,7 +54,9 @@
1.4 RevEdgeIt() {}
1.5 RevEdgeIt(Invalid) : path(0), current(INVALID) {}
1.6 RevEdgeIt(const PredMapPath& _path)
1.7 - : path(&_path), current(_path.target) {}
1.8 + : path(&_path), current(_path.target) {
1.9 + if (path->predMap[current] == INVALID) current = INVALID;
1.10 + }
1.11
1.12 operator const typename Graph::Edge() const {
1.13 return path->predMap[current];
1.14 @@ -126,7 +128,10 @@
1.15 RevEdgeIt() {}
1.16 RevEdgeIt(Invalid) : path(0), current(INVALID) {}
1.17 RevEdgeIt(const PredMatrixMapPath& _path)
1.18 - : path(&_path), current(_path.target) {}
1.19 + : path(&_path), current(_path.target) {
1.20 + if (path->predMatrixMap(path->source, current) == INVALID)
1.21 + current = INVALID;
1.22 + }
1.23
1.24 operator const typename Graph::Edge() const {
1.25 return path->predMatrixMap(path->source, current);
2.1 --- a/lemon/graph_reader.h Tue Aug 28 13:58:54 2007 +0000
2.2 +++ b/lemon/graph_reader.h Tue Aug 28 14:00:42 2007 +0000
2.3 @@ -324,7 +324,7 @@
2.4 /// It reads an label from the stream and gives back which edge belongs to
2.5 /// it. It is possible only if there was read a "label" named edge map.
2.6 void readLabel(std::istream& is, Edge& edge) const {
2.7 - return edgeset_reader.readLabel(is, edge);
2.8 + edgeset_reader.readLabel(is, edge);
2.9 }
2.10
2.11 private:
2.12 @@ -443,10 +443,10 @@
2.13 const DefaultSkipper& _skipper = DefaultSkipper())
2.14 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
2.15 nodeset_reader(*reader, _graph, std::string(), skipper),
2.16 - u_edgeset_reader(*reader, _graph, nodeset_reader,
2.17 + uedgeset_reader(*reader, _graph, nodeset_reader,
2.18 std::string(), skipper),
2.19 node_reader(*reader, nodeset_reader, std::string()),
2.20 - u_edge_reader(*reader, u_edgeset_reader, std::string()),
2.21 + uedge_reader(*reader, uedgeset_reader, std::string()),
2.22 attribute_reader(*reader, std::string()) {}
2.23
2.24 /// \brief Construct a new UGraphReader.
2.25 @@ -458,10 +458,10 @@
2.26 : reader(new LemonReader(_filename)), own_reader(true),
2.27 skipper(_skipper),
2.28 nodeset_reader(*reader, _graph, std::string(), skipper),
2.29 - u_edgeset_reader(*reader, _graph, nodeset_reader,
2.30 + uedgeset_reader(*reader, _graph, nodeset_reader,
2.31 std::string(), skipper),
2.32 node_reader(*reader, nodeset_reader, std::string()),
2.33 - u_edge_reader(*reader, u_edgeset_reader, std::string()),
2.34 + uedge_reader(*reader, uedgeset_reader, std::string()),
2.35 attribute_reader(*reader, std::string()) {}
2.36
2.37 /// \brief Construct a new UGraphReader.
2.38 @@ -472,10 +472,10 @@
2.39 const DefaultSkipper& _skipper = DefaultSkipper())
2.40 : reader(_reader), own_reader(false), skipper(_skipper),
2.41 nodeset_reader(*reader, _graph, std::string(), skipper),
2.42 - u_edgeset_reader(*reader, _graph, nodeset_reader,
2.43 + uedgeset_reader(*reader, _graph, nodeset_reader,
2.44 std::string(), skipper),
2.45 node_reader(*reader, nodeset_reader, std::string()),
2.46 - u_edge_reader(*reader, u_edgeset_reader, std::string()),
2.47 + uedge_reader(*reader, uedgeset_reader, std::string()),
2.48 attribute_reader(*reader, std::string()) {}
2.49
2.50 /// \brief Destruct the graph reader.
2.51 @@ -533,13 +533,13 @@
2.52 /// Give a new undirected edge map reading command to the reader.
2.53 template <typename Map>
2.54 UGraphReader& readUEdgeMap(std::string name, Map& map) {
2.55 - u_edgeset_reader.readUEdgeMap(name, map);
2.56 + uedgeset_reader.readUEdgeMap(name, map);
2.57 return *this;
2.58 }
2.59
2.60 template <typename Map>
2.61 UGraphReader& readUEdgeMap(std::string name, const Map& map) {
2.62 - u_edgeset_reader.readUEdgeMap(name, map);
2.63 + uedgeset_reader.readUEdgeMap(name, map);
2.64 return *this;
2.65 }
2.66
2.67 @@ -550,14 +550,14 @@
2.68 template <typename ItemReader, typename Map>
2.69 UGraphReader& readUEdgeMap(std::string name, Map& map,
2.70 const ItemReader& ir = ItemReader()) {
2.71 - u_edgeset_reader.readUEdgeMap(name, map, ir);
2.72 + uedgeset_reader.readUEdgeMap(name, map, ir);
2.73 return *this;
2.74 }
2.75
2.76 template <typename ItemReader, typename Map>
2.77 UGraphReader& readUEdgeMap(std::string name, const Map& map,
2.78 const ItemReader& ir = ItemReader()) {
2.79 - u_edgeset_reader.readUEdgeMap(name, map, ir);
2.80 + uedgeset_reader.readUEdgeMap(name, map, ir);
2.81 return *this;
2.82 }
2.83
2.84 @@ -567,7 +567,7 @@
2.85 template <typename ItemReader>
2.86 UGraphReader& skipUEdgeMap(std::string name,
2.87 const ItemReader& ir = ItemReader()) {
2.88 - u_edgeset_reader.skipUMap(name, ir);
2.89 + uedgeset_reader.skipUMap(name, ir);
2.90 return *this;
2.91 }
2.92
2.93 @@ -577,13 +577,13 @@
2.94 /// Give a new edge map reading command to the reader.
2.95 template <typename Map>
2.96 UGraphReader& readEdgeMap(std::string name, Map& map) {
2.97 - u_edgeset_reader.readEdgeMap(name, map);
2.98 + uedgeset_reader.readEdgeMap(name, map);
2.99 return *this;
2.100 }
2.101
2.102 template <typename Map>
2.103 UGraphReader& readEdgeMap(std::string name, const Map& map) {
2.104 - u_edgeset_reader.readEdgeMap(name, map);
2.105 + uedgeset_reader.readEdgeMap(name, map);
2.106 return *this;
2.107 }
2.108
2.109 @@ -594,14 +594,14 @@
2.110 template <typename ItemReader, typename Map>
2.111 UGraphReader& readEdgeMap(std::string name, Map& map,
2.112 const ItemReader& ir = ItemReader()) {
2.113 - u_edgeset_reader.readEdgeMap(name, map, ir);
2.114 + uedgeset_reader.readEdgeMap(name, map, ir);
2.115 return *this;
2.116 }
2.117
2.118 template <typename ItemReader, typename Map>
2.119 UGraphReader& readEdgeMap(std::string name, const Map& map,
2.120 const ItemReader& ir = ItemReader()) {
2.121 - u_edgeset_reader.readEdgeMap(name, map, ir);
2.122 + uedgeset_reader.readEdgeMap(name, map, ir);
2.123 return *this;
2.124 }
2.125
2.126 @@ -611,7 +611,7 @@
2.127 template <typename ItemReader>
2.128 UGraphReader& skipEdgeMap(std::string name,
2.129 const ItemReader& ir = ItemReader()) {
2.130 - u_edgeset_reader.skipEdgeMap(name, ir);
2.131 + uedgeset_reader.skipEdgeMap(name, ir);
2.132 return *this;
2.133 }
2.134
2.135 @@ -627,7 +627,7 @@
2.136 ///
2.137 /// Give a new labeled edge reading command to the reader.
2.138 UGraphReader& readEdge(std::string name, Edge& edge) {
2.139 - u_edge_reader.readEdge(name, edge);
2.140 + uedge_reader.readEdge(name, edge);
2.141 }
2.142
2.143 /// \brief Give a new labeled undirected edge reading command to the
2.144 @@ -635,7 +635,7 @@
2.145 ///
2.146 /// Give a new labeled undirected edge reading command to the reader.
2.147 UGraphReader& readUEdge(std::string name, UEdge& edge) {
2.148 - u_edge_reader.readUEdge(name, edge);
2.149 + uedge_reader.readUEdge(name, edge);
2.150 }
2.151
2.152 /// \brief Give a new attribute reading command.
2.153 @@ -677,10 +677,10 @@
2.154
2.155 /// \brief Returns true if the reader can give back the items by its label.
2.156 ///
2.157 - /// \brief Returns true if the reader can give back the items by its label.
2.158 + /// Returns true if the reader can give back the items by its label.
2.159 bool isLabelReader() const {
2.160 return nodeset_reader.isLabelReader() &&
2.161 - u_edgeset_reader.isLabelReader();
2.162 + uedgeset_reader.isLabelReader();
2.163 }
2.164
2.165 /// \brief Gives back the node by its label.
2.166 @@ -696,7 +696,7 @@
2.167 /// It reads an label from the stream and gives back which edge belongs to
2.168 /// it. It is possible only if there was read a "label" named edge map.
2.169 void readLabel(std::istream& is, Edge& edge) const {
2.170 - return u_edgeset_reader.readLabel(is, edge);
2.171 + return uedgeset_reader.readLabel(is, edge);
2.172 }
2.173
2.174 /// \brief Gives back the undirected edge by its label.
2.175 @@ -705,7 +705,7 @@
2.176 /// belongs to it. It is possible only if there was read a "label" named
2.177 /// edge map.
2.178 void readLabel(std::istream& is, UEdge& uedge) const {
2.179 - return u_edgeset_reader.readLabel(is, uedge);
2.180 + return uedgeset_reader.readLabel(is, uedge);
2.181 }
2.182
2.183
2.184 @@ -717,10 +717,10 @@
2.185 DefaultSkipper skipper;
2.186
2.187 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
2.188 - UEdgeSetReader<Graph, ReaderTraits> u_edgeset_reader;
2.189 + UEdgeSetReader<Graph, ReaderTraits> uedgeset_reader;
2.190
2.191 NodeReader<Graph> node_reader;
2.192 - UEdgeReader<Graph> u_edge_reader;
2.193 + UEdgeReader<Graph> uedge_reader;
2.194
2.195 AttributeReader<ReaderTraits> attribute_reader;
2.196 };
3.1 --- a/lemon/graph_writer.h Tue Aug 28 13:58:54 2007 +0000
3.2 +++ b/lemon/graph_writer.h Tue Aug 28 14:00:42 2007 +0000
3.3 @@ -251,9 +251,17 @@
3.4 writer->run();
3.5 }
3.6
3.7 + /// \brief Returns true if the writer can give back the labels by the items.
3.8 + ///
3.9 + /// Returns true if the writer can give back the the labels by the items.
3.10 + bool isLabelWriter() const {
3.11 + return nodeset_writer.isLabelWriter() &&
3.12 + edgeset_writer.isLabelWriter();
3.13 + }
3.14 +
3.15 /// \brief Write the label of the given node.
3.16 ///
3.17 - /// It writes the label of the given node. If there was written an "label"
3.18 + /// It writes the label of the given node. If there was written a "label"
3.19 /// named node map then it will write the map value belonging to the node.
3.20 void writeLabel(std::ostream& os, const Node& item) const {
3.21 nodeset_writer.writeLabel(os, item);
3.22 @@ -261,12 +269,32 @@
3.23
3.24 /// \brief Write the label of the given edge.
3.25 ///
3.26 - /// It writes the label of the given edge. If there was written an "label"
3.27 + /// It writes the label of the given edge. If there was written a "label"
3.28 /// named edge map then it will write the map value belonging to the edge.
3.29 void writeLabel(std::ostream& os, const Edge& item) const {
3.30 edgeset_writer.writeLabel(os, item);
3.31 }
3.32
3.33 + /// \brief Sorts the given node vector by label.
3.34 + ///
3.35 + /// Sorts the given node vector by label. If there was written an
3.36 + /// "label" named map then the vector will be sorted by the values
3.37 + /// of this map. Otherwise if the \c forceLabel parameter was true
3.38 + /// it will be sorted by its id in the graph.
3.39 + void sortByLabel(std::vector<Node>& nodes) const {
3.40 + nodeset_writer.sortByLabel(nodes);
3.41 + }
3.42 +
3.43 + /// \brief Sorts the given edge vector by label.
3.44 + ///
3.45 + /// Sorts the given edge vector by label. If there was written an
3.46 + /// "label" named map then the vector will be sorted by the values
3.47 + /// of this map. Otherwise if the \c forceLabel parameter was true
3.48 + /// it will be sorted by its id in the graph.
3.49 + void sortByLabel(std::vector<Edge>& edges) const {
3.50 + edgeset_writer.sortByLabel(edges);
3.51 + }
3.52 +
3.53 private:
3.54
3.55 LemonWriter* writer;
3.56 @@ -370,9 +398,9 @@
3.57 UGraphWriter(std::ostream& _os, const Graph& _graph)
3.58 : writer(new LemonWriter(_os)), own_writer(true),
3.59 nodeset_writer(*writer, _graph, std::string()),
3.60 - u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.61 + uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.62 node_writer(*writer, nodeset_writer, std::string()),
3.63 - u_edge_writer(*writer, u_edgeset_writer, std::string()),
3.64 + uedge_writer(*writer, uedgeset_writer, std::string()),
3.65 attribute_writer(*writer, std::string()) {}
3.66
3.67 /// \brief Construct a new UGraphWriter.
3.68 @@ -382,21 +410,21 @@
3.69 UGraphWriter(const std::string& _filename, const Graph& _graph)
3.70 : writer(new LemonWriter(_filename)), own_writer(true),
3.71 nodeset_writer(*writer, _graph, std::string()),
3.72 - u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.73 + uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.74 node_writer(*writer, nodeset_writer, std::string()),
3.75 - u_edge_writer(*writer, u_edgeset_writer, std::string()),
3.76 + uedge_writer(*writer, uedgeset_writer, std::string()),
3.77 attribute_writer(*writer, std::string()) {}
3.78
3.79 /// \brief Construct a new UGraphWriter.
3.80 ///
3.81 /// Construct a new UGraphWriter. It writes the given graph
3.82 - /// to given LemonReader.
3.83 + /// to given LemonWriter.
3.84 UGraphWriter(LemonWriter& _writer, const Graph& _graph)
3.85 : writer(_writer), own_writer(false),
3.86 nodeset_writer(*writer, _graph, std::string()),
3.87 - u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.88 + uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.89 node_writer(*writer, nodeset_writer, std::string()),
3.90 - u_edge_writer(*writer, u_edgeset_writer, std::string()),
3.91 + uedge_writer(*writer, uedgeset_writer, std::string()),
3.92 attribute_writer(*writer, std::string()) {}
3.93
3.94 /// \brief Destruct the graph writer.
3.95 @@ -434,7 +462,7 @@
3.96 /// the writer.
3.97 template <typename Map>
3.98 UGraphWriter& writeEdgeMap(std::string label, const Map& map) {
3.99 - u_edgeset_writer.writeEdgeMap(label, map);
3.100 + uedgeset_writer.writeEdgeMap(label, map);
3.101 return *this;
3.102 }
3.103
3.104 @@ -445,7 +473,7 @@
3.105 template <typename ItemWriter, typename Map>
3.106 UGraphWriter& writeEdgeMap(std::string label, const Map& map,
3.107 const ItemWriter& iw = ItemWriter()) {
3.108 - u_edgeset_writer.writeEdgeMap(label, map, iw);
3.109 + uedgeset_writer.writeEdgeMap(label, map, iw);
3.110 return *this;
3.111 }
3.112
3.113 @@ -455,7 +483,7 @@
3.114 /// command</i> to the writer.
3.115 template <typename Map>
3.116 UGraphWriter& writeUEdgeMap(std::string label, const Map& map) {
3.117 - u_edgeset_writer.writeUEdgeMap(label, map);
3.118 + uedgeset_writer.writeUEdgeMap(label, map);
3.119 return *this;
3.120 }
3.121
3.122 @@ -466,7 +494,7 @@
3.123 template <typename ItemWriter, typename Map>
3.124 UGraphWriter& writeUEdgeMap(std::string label, const Map& map,
3.125 const ItemWriter& iw = ItemWriter()) {
3.126 - u_edgeset_writer.writeUEdgeMap(label, map, iw);
3.127 + uedgeset_writer.writeUEdgeMap(label, map, iw);
3.128 return *this;
3.129 }
3.130
3.131 @@ -484,7 +512,7 @@
3.132 /// This function issues a new <i> labeled edge writing
3.133 /// command</i> to the writer.
3.134 UGraphWriter& writeEdge(std::string label, const Edge& edge) {
3.135 - u_edge_writer.writeEdge(label, edge);
3.136 + uedge_writer.writeEdge(label, edge);
3.137 }
3.138
3.139 /// \brief Issue a new labeled undirected edge writing command to
3.140 @@ -493,7 +521,7 @@
3.141 /// Issue a new <i>labeled undirected edge writing command</i> to
3.142 /// the writer.
3.143 UGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
3.144 - u_edge_writer.writeUEdge(label, edge);
3.145 + uedge_writer.writeUEdge(label, edge);
3.146 }
3.147
3.148 /// \brief Issue a new attribute writing command.
3.149 @@ -534,9 +562,17 @@
3.150 writer->run();
3.151 }
3.152
3.153 + /// \brief Returns true if the writer can give back the labels by the items.
3.154 + ///
3.155 + /// Returns true if the writer can give back the the labels by the items.
3.156 + bool isLabelWriter() const {
3.157 + return nodeset_writer.isLabelWriter() &&
3.158 + uedgeset_writer.isLabelWriter();
3.159 + }
3.160 +
3.161 /// \brief Write the label of the given node.
3.162 ///
3.163 - /// It writes the label of the given node. If there was written an "label"
3.164 + /// It writes the label of the given node. If there was written a "label"
3.165 /// named node map then it will write the map value belonging to the node.
3.166 void writeLabel(std::ostream& os, const Node& item) const {
3.167 nodeset_writer.writeLabel(os, item);
3.168 @@ -544,21 +580,50 @@
3.169
3.170 /// \brief Write the label of the given edge.
3.171 ///
3.172 - /// It writes the label of the given edge. If there was written an "label"
3.173 + /// It writes the label of the given edge. If there was written a "label"
3.174 /// named edge map then it will write the map value belonging to the edge.
3.175 void writeLabel(std::ostream& os, const Edge& item) const {
3.176 - u_edgeset_writer.writeLabel(os, item);
3.177 + uedgeset_writer.writeLabel(os, item);
3.178 }
3.179
3.180 /// \brief Write the label of the given undirected edge.
3.181 ///
3.182 /// It writes the label of the given undirected edge. If there was
3.183 - /// written an "label" named edge map then it will write the map
3.184 + /// written a "label" named edge map then it will write the map
3.185 /// value belonging to the edge.
3.186 void writeLabel(std::ostream& os, const UEdge& item) const {
3.187 - u_edgeset_writer.writeLabel(os, item);
3.188 + uedgeset_writer.writeLabel(os, item);
3.189 }
3.190
3.191 + /// \brief Sorts the given node vector by label.
3.192 + ///
3.193 + /// Sorts the given node vector by label. If there was written an
3.194 + /// "label" named map then the vector will be sorted by the values
3.195 + /// of this map. Otherwise if the \c forceLabel parameter was true
3.196 + /// it will be sorted by its id in the graph.
3.197 + void sortByLabel(std::vector<Node>& nodes) const {
3.198 + nodeset_writer.sortByLabel(nodes);
3.199 + }
3.200 +
3.201 + /// \brief Sorts the given edge vector by label.
3.202 + ///
3.203 + /// Sorts the given edge vector by label. If there was written an
3.204 + /// "label" named map then the vector will be sorted by the values
3.205 + /// of this map. Otherwise if the \c forceLabel parameter was true
3.206 + /// it will be sorted by its id in the graph.
3.207 + void sortByLabel(std::vector<Edge>& edges) const {
3.208 + uedgeset_writer.sortByLabel(edges);
3.209 + }
3.210 +
3.211 + /// \brief Sorts the given undirected edge vector by label.
3.212 + ///
3.213 + /// Sorts the given undirected edge vector by label. If there was
3.214 + /// written an "label" named map then the vector will be sorted by
3.215 + /// the values of this map. Otherwise if the \c forceLabel
3.216 + /// parameter was true it will be sorted by its id in the graph.
3.217 + void sortByLabel(std::vector<UEdge>& uedges) const {
3.218 + uedgeset_writer.sortByLabel(uedges);
3.219 + }
3.220
3.221 private:
3.222
3.223 @@ -566,10 +631,10 @@
3.224 bool own_writer;
3.225
3.226 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
3.227 - UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
3.228 + UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
3.229
3.230 NodeWriter<Graph> node_writer;
3.231 - UEdgeWriter<Graph> u_edge_writer;
3.232 + UEdgeWriter<Graph> uedge_writer;
3.233
3.234 AttributeWriter<WriterTraits> attribute_writer;
3.235 };
4.1 --- a/lemon/lemon_reader.h Tue Aug 28 13:58:54 2007 +0000
4.2 +++ b/lemon/lemon_reader.h Tue Aug 28 14:00:42 2007 +0000
4.3 @@ -58,7 +58,7 @@
4.4 return p < q;
4.5 }
4.6 };
4.7 -
4.8 +
4.9 template <typename Item>
4.10 class ItemLabelReader {
4.11 public:
4.12 @@ -255,7 +255,7 @@
4.13 return it->second;
4.14 } else {
4.15 ErrorMessage msg;
4.16 - msg << "Invalid label error: " << value;
4.17 + msg << "Invalid label error";
4.18 throw DataFormatError(msg.message());
4.19 }
4.20 }
4.21 @@ -289,7 +289,7 @@
4.22
4.23 virtual Item read(std::istream& is) const {
4.24 Value value;
4.25 - reader.read(is, value);
4.26 + reader.read(is, value);
4.27 typename Inverse::const_iterator it = inverse.find(value);
4.28 if (it != inverse.end()) {
4.29 return it->second;
4.30 @@ -382,6 +382,7 @@
4.31 virtual ~LabelReaderBase() {}
4.32 virtual Item read(std::istream& is) const = 0;
4.33 virtual bool isLabelReader() const = 0;
4.34 + virtual LabelReaderBase<_Item>* clone() const = 0;
4.35 };
4.36
4.37 template <typename _Item, typename _BoxedLabelReader>
4.38 @@ -390,19 +391,23 @@
4.39 typedef _Item Item;
4.40 typedef _BoxedLabelReader BoxedLabelReader;
4.41
4.42 - const BoxedLabelReader& boxedLabelReader;
4.43 -
4.44 - LabelReader(const BoxedLabelReader& _boxedLabelReader)
4.45 - : boxedLabelReader(_boxedLabelReader) {}
4.46 + const BoxedLabelReader& labelReader;
4.47 +
4.48 + LabelReader(const BoxedLabelReader& _labelReader)
4.49 + : labelReader(_labelReader) {}
4.50
4.51 virtual Item read(std::istream& is) const {
4.52 Item item;
4.53 - boxedLabelReader.readLabel(is, item);
4.54 + labelReader.readLabel(is, item);
4.55 return item;
4.56 }
4.57
4.58 virtual bool isLabelReader() const {
4.59 - return boxedLabelReader.isLabelReader();
4.60 + return labelReader.isLabelReader();
4.61 + }
4.62 +
4.63 + LabelReader<Item, BoxedLabelReader>* clone() const {
4.64 + return new LabelReader<Item, BoxedLabelReader>(labelReader);
4.65 }
4.66 };
4.67
4.68 @@ -723,7 +728,6 @@
4.69 it->second = true;
4.70 char buf[2048];
4.71 FilterStreamBuf buffer(*is, line_num);
4.72 -
4.73 try {
4.74 buffer.pubsetbuf(buf, sizeof(buf));
4.75 std::istream ss(&buffer);
4.76 @@ -1511,8 +1515,8 @@
4.77 ///
4.78 /// It reads an id from the stream and gives back which undirected edge
4.79 /// belongs to it. It is possible only if there was read an "label" named map.
4.80 - void readLabel(std::istream& is, UEdge& uEdge) const {
4.81 - uEdge = inverter->read(is);
4.82 + void readLabel(std::istream& is, UEdge& uedge) const {
4.83 + uedge = inverter->read(is);
4.84 }
4.85
4.86 /// \brief Gives back the directed edge by its label.
4.87 @@ -1524,11 +1528,11 @@
4.88 void readLabel(std::istream& is, Edge& edge) const {
4.89 char c;
4.90 is >> c;
4.91 - UEdge uEdge = inverter->read(is);
4.92 + UEdge uedge = inverter->read(is);
4.93 if (c == '+') {
4.94 - edge = graph.direct(uEdge, true);
4.95 + edge = graph.direct(uedge, true);
4.96 } else if (c == '-') {
4.97 - edge = graph.direct(uEdge, false);
4.98 + edge = graph.direct(uedge, false);
4.99 } else {
4.100 throw DataFormatError("Wrong id format for edge "
4.101 "in undirected edgeset");
4.102 @@ -1807,10 +1811,10 @@
4.103 : Parent(_reader), name(_name) {
4.104 checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
4.105 checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
4.106 - uEdgeLabelReader.reset(new _reader_bits::
4.107 - LabelReader<UEdge, _LabelReader>(_labelReader));
4.108 + uedgeLabelReader.reset(new _reader_bits::
4.109 + LabelReader<UEdge, _LabelReader>(_labelReader));
4.110 edgeLabelReader.reset(new _reader_bits::
4.111 - LabelReader<Edge, _LabelReader>(_labelReader));
4.112 + LabelReader<Edge, _LabelReader>(_labelReader));
4.113 }
4.114
4.115 /// \brief Destructor.
4.116 @@ -1827,12 +1831,12 @@
4.117 ///
4.118 /// Add an undirected edge reader command for the UEdgeReader.
4.119 void readUEdge(std::string label, UEdge& item) {
4.120 - if (uEdgeReaders.find(label) != uEdgeReaders.end()) {
4.121 + if (uedgeReaders.find(label) != uedgeReaders.end()) {
4.122 ErrorMessage msg;
4.123 msg << "Multiple read rule for undirected edge: " << label;
4.124 throw IoParameterError(msg.message());
4.125 }
4.126 - uEdgeReaders.insert(make_pair(label, _reader_bits::
4.127 + uedgeReaders.insert(make_pair(label, _reader_bits::
4.128 ItemStore<UEdge>(item)));
4.129 }
4.130
4.131 @@ -1870,7 +1874,7 @@
4.132 if (!edgeLabelReader->isLabelReader()) {
4.133 throw DataFormatError("Cannot find undirected edgeset or label map");
4.134 }
4.135 - if (!uEdgeLabelReader->isLabelReader()) {
4.136 + if (!uedgeLabelReader->isLabelReader()) {
4.137 throw DataFormatError("Cannot find undirected edgeset or label map");
4.138 }
4.139 std::string line;
4.140 @@ -1879,9 +1883,9 @@
4.141 std::string id;
4.142 ls >> id;
4.143 {
4.144 - typename UEdgeReaders::iterator it = uEdgeReaders.find(id);
4.145 - if (it != uEdgeReaders.end()) {
4.146 - it->second.read(uEdgeLabelReader->read(ls));
4.147 + typename UEdgeReaders::iterator it = uedgeReaders.find(id);
4.148 + if (it != uedgeReaders.end()) {
4.149 + it->second.read(uedgeLabelReader->read(ls));
4.150 it->second.touch();
4.151 continue;
4.152 }
4.153 @@ -1902,8 +1906,8 @@
4.154 throw IoParameterError(msg.message());
4.155 }
4.156 }
4.157 - for (typename UEdgeReaders::iterator it = uEdgeReaders.begin();
4.158 - it != uEdgeReaders.end(); ++it) {
4.159 + for (typename UEdgeReaders::iterator it = uedgeReaders.begin();
4.160 + it != uedgeReaders.end(); ++it) {
4.161 if (!it->second.touched()) {
4.162 ErrorMessage msg;
4.163 msg << "UEdge not found in file: " << it->first;
4.164 @@ -1913,7 +1917,7 @@
4.165 }
4.166
4.167 virtual void missing() {
4.168 - if (edgeReaders.empty() && uEdgeReaders.empty()) return;
4.169 + if (edgeReaders.empty() && uedgeReaders.empty()) return;
4.170 ErrorMessage msg;
4.171 msg << "UEdges section not found in file: @uedges " << name;
4.172 throw IoParameterError(msg.message());
4.173 @@ -1925,8 +1929,8 @@
4.174
4.175 typedef std::map<std::string,
4.176 _reader_bits::ItemStore<UEdge> > UEdgeReaders;
4.177 - UEdgeReaders uEdgeReaders;
4.178 - std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uEdgeLabelReader;
4.179 + UEdgeReaders uedgeReaders;
4.180 + std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uedgeLabelReader;
4.181
4.182 typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
4.183 EdgeReaders edgeReaders;
4.184 @@ -2054,6 +2058,671 @@
4.185 };
4.186
4.187 /// \ingroup section_io
4.188 + /// \brief SectionReader for reading extra node maps.
4.189 + ///
4.190 + /// The lemon format can store maps in the nodeset sections. This
4.191 + /// class let you make distinict section to store maps. The main
4.192 + /// purpose of this class is a logical separation of some maps. The
4.193 + /// other useful application could be to store paths in node maps.
4.194 + ///
4.195 + /// The first line of the section contains the names of the maps
4.196 + /// separated with white spaces. Each next line describes an item
4.197 + /// in the itemset, and contains in the first column the label of
4.198 + /// the item and then the mapped values for each map.
4.199 + ///
4.200 + /// \relates LemonReader
4.201 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
4.202 + class NodeMapReader : public LemonReader::SectionReader {
4.203 + typedef LemonReader::SectionReader Parent;
4.204 + public:
4.205 +
4.206 + typedef _Graph Graph;
4.207 + typedef typename Graph::Node Node;
4.208 + typedef _Traits Traits;
4.209 + typedef typename Traits::Skipper DefaultSkipper;
4.210 +
4.211 + /// \brief Constructor.
4.212 + ///
4.213 + /// Constructor for NodeMapReader. It creates the NodeMapReader and
4.214 + /// attach it into the given LemonReader. The reader will read
4.215 + /// the section when the \c section_name and the \c _name are the same.
4.216 + template <typename _LabelReader>
4.217 + NodeMapReader(LemonReader& _reader,
4.218 + const Graph& _graph,
4.219 + const _LabelReader& _labelReader,
4.220 + const std::string& _name = std::string(),
4.221 + const DefaultSkipper& _skipper = DefaultSkipper())
4.222 + : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
4.223 + labelReader.reset(new _reader_bits::
4.224 + LabelReader<Node, _LabelReader>(_labelReader));
4.225 + }
4.226 +
4.227 +
4.228 + /// \brief Destructor.
4.229 + ///
4.230 + /// Destructor for NodeMapReader.
4.231 + virtual ~NodeMapReader() {
4.232 + for (typename MapReaders::iterator it = readers.begin();
4.233 + it != readers.end(); ++it) {
4.234 + delete it->second;
4.235 + }
4.236 + }
4.237 +
4.238 + private:
4.239 + NodeMapReader(const NodeMapReader&);
4.240 + void operator=(const NodeMapReader&);
4.241 +
4.242 + public:
4.243 +
4.244 + /// \brief Add a new node map reader command for the reader.
4.245 + ///
4.246 + /// Add a new node map reader command for the reader.
4.247 + template <typename Map>
4.248 + NodeMapReader& readNodeMap(std::string label, Map& map) {
4.249 + return _readMap<
4.250 + typename Traits::template Reader<typename Map::Value>, Map,
4.251 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.252 + }
4.253 +
4.254 + template <typename Map>
4.255 + NodeMapReader& readNodeMap(std::string label, const Map& map) {
4.256 + return _readMap<
4.257 + typename Traits::template Reader<typename Map::Value>, Map,
4.258 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.259 + }
4.260 +
4.261 + /// \brief Add a new node map reader command for the reader.
4.262 + ///
4.263 + /// Add a new node map reader command for the reader.
4.264 + template <typename ItemReader, typename Map>
4.265 + NodeMapReader& readNodeMap(std::string label, Map& map,
4.266 + const ItemReader& ir = ItemReader()) {
4.267 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.268 + (label, map, ir);
4.269 + }
4.270 +
4.271 + template <typename ItemReader, typename Map>
4.272 + NodeMapReader& readNodeMap(std::string label, const Map& map,
4.273 + const ItemReader& ir = ItemReader()) {
4.274 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.275 + (label, map, ir);
4.276 + }
4.277 +
4.278 + private:
4.279 +
4.280 + template <typename ItemReader, typename Map, typename MapParameter>
4.281 + NodeMapReader& _readMap(std::string label, MapParameter map,
4.282 + const ItemReader& ir = ItemReader()) {
4.283 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
4.284 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
4.285 + if (readers.find(label) != readers.end()) {
4.286 + ErrorMessage msg;
4.287 + msg << "Multiple read rule for map: " << label;
4.288 + throw IoParameterError(msg.message());
4.289 + }
4.290 + readers.insert(
4.291 + make_pair(label, new _reader_bits::
4.292 + MapReader<Node, Map, ItemReader>(map, ir)));
4.293 + return *this;
4.294 + }
4.295 +
4.296 + public:
4.297 +
4.298 + /// \brief Add a new node map skipper command for the reader.
4.299 + ///
4.300 + /// Add a new node map skipper command for the reader.
4.301 + template <typename ItemReader>
4.302 + NodeMapReader& skipNodeMap(std::string label,
4.303 + const ItemReader& ir = ItemReader()) {
4.304 + if (readers.find(label) != readers.end()) {
4.305 + ErrorMessage msg;
4.306 + msg << "Multiple read rule for map: " << label;
4.307 + throw IoParameterError(msg.message());
4.308 + }
4.309 + readers.insert(make_pair(label, new _reader_bits::
4.310 + SkipReader<Node, ItemReader>(ir)));
4.311 + return *this;
4.312 + }
4.313 +
4.314 + protected:
4.315 +
4.316 + /// \brief Gives back true when the SectionReader can process
4.317 + /// the section with the given header line.
4.318 + ///
4.319 + /// It gives back true when the header line starts with \c \@mapset,
4.320 + /// and the header line's name and the mapset's name are the same.
4.321 + virtual bool header(const std::string& line) {
4.322 + std::istringstream ls(line);
4.323 + std::string command;
4.324 + std::string id;
4.325 + ls >> command >> id;
4.326 + return command == "@nodemaps" && name == id;
4.327 + }
4.328 +
4.329 + /// \brief Reader function of the section.
4.330 + ///
4.331 + /// It reads the content of the section.
4.332 + virtual void read(std::istream& is) {
4.333 + std::vector<_reader_bits::MapReaderBase<Node>* > index;
4.334 + std::string line;
4.335 +
4.336 + {
4.337 + getline(is, line);
4.338 + std::istringstream ls(line);
4.339 + std::string id;
4.340 + while (ls >> id) {
4.341 + typename MapReaders::iterator it = readers.find(id);
4.342 + if (it != readers.end()) {
4.343 + it->second->touch();
4.344 + index.push_back(it->second);
4.345 + } else {
4.346 + index.push_back(&skipper);
4.347 + }
4.348 + }
4.349 + }
4.350 + for (typename MapReaders::iterator it = readers.begin();
4.351 + it != readers.end(); ++it) {
4.352 + if (!it->second->touched()) {
4.353 + ErrorMessage msg;
4.354 + msg << "Map not found in file: " << it->first;
4.355 + throw IoParameterError(msg.message());
4.356 + }
4.357 + }
4.358 + while (getline(is, line)) {
4.359 + std::istringstream ls(line);
4.360 + Node node = labelReader->read(ls);
4.361 + for (int i = 0; i < int(index.size()); ++i) {
4.362 + index[i]->read(ls, node);
4.363 + }
4.364 + }
4.365 + }
4.366 +
4.367 + virtual void missing() {
4.368 + if (readers.empty()) return;
4.369 + ErrorMessage msg;
4.370 + msg << "NodeMap section not found in file: @nodemaps " << name;
4.371 + throw IoParameterError(msg.message());
4.372 + }
4.373 +
4.374 + private:
4.375 +
4.376 + typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
4.377 + MapReaders readers;
4.378 +
4.379 + const Graph& graph;
4.380 + std::string name;
4.381 + _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
4.382 + std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader;
4.383 +
4.384 + };
4.385 +
4.386 + /// \ingroup section_io
4.387 + /// \brief SectionReader for reading extra edge maps.
4.388 + ///
4.389 + /// The lemon format can store maps in the edgeset sections. This
4.390 + /// class let you make distinict section to store maps. The main
4.391 + /// purpose of this class is a logical separation of some maps. The
4.392 + /// other useful application could be to store paths in edge maps.
4.393 + ///
4.394 + /// The first line of the section contains the names of the maps
4.395 + /// separated with white spaces. Each next line describes an item
4.396 + /// in the itemset, and contains in the first column the label of
4.397 + /// the item and then the mapped values for each map.
4.398 + ///
4.399 + /// \relates LemonReader
4.400 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
4.401 + class EdgeMapReader : public LemonReader::SectionReader {
4.402 + typedef LemonReader::SectionReader Parent;
4.403 + public:
4.404 +
4.405 + typedef _Graph Graph;
4.406 + typedef typename Graph::Edge Edge;
4.407 + typedef _Traits Traits;
4.408 + typedef typename Traits::Skipper DefaultSkipper;
4.409 +
4.410 + /// \brief Constructor.
4.411 + ///
4.412 + /// Constructor for EdgeMapReader. It creates the EdgeMapReader and
4.413 + /// attach it into the given LemonReader. The reader will read
4.414 + /// the section when the \c section_name and the \c _name are the same.
4.415 + template <typename _LabelReader>
4.416 + EdgeMapReader(LemonReader& _reader,
4.417 + const Graph& _graph,
4.418 + const _LabelReader& _labelReader,
4.419 + const std::string& _name = std::string(),
4.420 + const DefaultSkipper& _skipper = DefaultSkipper())
4.421 + : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
4.422 + labelReader.reset(new _reader_bits::
4.423 + LabelReader<Edge, _LabelReader>(_labelReader));
4.424 + }
4.425 +
4.426 +
4.427 + /// \brief Destructor.
4.428 + ///
4.429 + /// Destructor for EdgeMapReader.
4.430 + virtual ~EdgeMapReader() {
4.431 + for (typename MapReaders::iterator it = readers.begin();
4.432 + it != readers.end(); ++it) {
4.433 + delete it->second;
4.434 + }
4.435 + }
4.436 +
4.437 + private:
4.438 + EdgeMapReader(const EdgeMapReader&);
4.439 + void operator=(const EdgeMapReader&);
4.440 +
4.441 + public:
4.442 +
4.443 + /// \brief Add a new edge map reader command for the reader.
4.444 + ///
4.445 + /// Add a new edge map reader command for the reader.
4.446 + template <typename Map>
4.447 + EdgeMapReader& readEdgeMap(std::string label, Map& map) {
4.448 + return _readMap<
4.449 + typename Traits::template Reader<typename Map::Value>, Map,
4.450 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.451 + }
4.452 +
4.453 + template <typename Map>
4.454 + EdgeMapReader& readEdgeMap(std::string label, const Map& map) {
4.455 + return _readMap<
4.456 + typename Traits::template Reader<typename Map::Value>, Map,
4.457 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.458 + }
4.459 +
4.460 + /// \brief Add a new edge map reader command for the reader.
4.461 + ///
4.462 + /// Add a new edge map reader command for the reader.
4.463 + template <typename ItemReader, typename Map>
4.464 + EdgeMapReader& readEdgeMap(std::string label, Map& map,
4.465 + const ItemReader& ir = ItemReader()) {
4.466 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.467 + (label, map, ir);
4.468 + }
4.469 +
4.470 + template <typename ItemReader, typename Map>
4.471 + EdgeMapReader& readEdgeMap(std::string label, const Map& map,
4.472 + const ItemReader& ir = ItemReader()) {
4.473 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.474 + (label, map, ir);
4.475 + }
4.476 +
4.477 + private:
4.478 +
4.479 + template <typename ItemReader, typename Map, typename MapParameter>
4.480 + EdgeMapReader& _readMap(std::string label, MapParameter map,
4.481 + const ItemReader& ir = ItemReader()) {
4.482 + checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
4.483 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
4.484 + if (readers.find(label) != readers.end()) {
4.485 + ErrorMessage msg;
4.486 + msg << "Multiple read rule for map: " << label;
4.487 + throw IoParameterError(msg.message());
4.488 + }
4.489 + readers.insert(
4.490 + make_pair(label, new _reader_bits::
4.491 + MapReader<Edge, Map, ItemReader>(map, ir)));
4.492 + return *this;
4.493 + }
4.494 +
4.495 + public:
4.496 +
4.497 + /// \brief Add a new edge map skipper command for the reader.
4.498 + ///
4.499 + /// Add a new edge map skipper command for the reader.
4.500 + template <typename ItemReader>
4.501 + EdgeMapReader& skipEdgeMap(std::string label,
4.502 + const ItemReader& ir = ItemReader()) {
4.503 + if (readers.find(label) != readers.end()) {
4.504 + ErrorMessage msg;
4.505 + msg << "Multiple read rule for map: " << label;
4.506 + throw IoParameterError(msg.message());
4.507 + }
4.508 + readers.insert(make_pair(label, new _reader_bits::
4.509 + SkipReader<Edge, ItemReader>(ir)));
4.510 + return *this;
4.511 + }
4.512 +
4.513 + protected:
4.514 +
4.515 + /// \brief Gives back true when the SectionReader can process
4.516 + /// the section with the given header line.
4.517 + ///
4.518 + /// It gives back true when the header line starts with \c \@mapset,
4.519 + /// and the header line's name and the mapset's name are the same.
4.520 + virtual bool header(const std::string& line) {
4.521 + std::istringstream ls(line);
4.522 + std::string command;
4.523 + std::string id;
4.524 + ls >> command >> id;
4.525 + return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
4.526 + }
4.527 +
4.528 + /// \brief Reader function of the section.
4.529 + ///
4.530 + /// It reads the content of the section.
4.531 + virtual void read(std::istream& is) {
4.532 + std::vector<_reader_bits::MapReaderBase<Edge>* > index;
4.533 + std::string line;
4.534 +
4.535 + {
4.536 + getline(is, line);
4.537 + std::istringstream ls(line);
4.538 + std::string id;
4.539 + while (ls >> id) {
4.540 + typename MapReaders::iterator it = readers.find(id);
4.541 + if (it != readers.end()) {
4.542 + it->second->touch();
4.543 + index.push_back(it->second);
4.544 + } else {
4.545 + index.push_back(&skipper);
4.546 + }
4.547 + }
4.548 + }
4.549 + for (typename MapReaders::iterator it = readers.begin();
4.550 + it != readers.end(); ++it) {
4.551 + if (!it->second->touched()) {
4.552 + ErrorMessage msg;
4.553 + msg << "Map not found in file: " << it->first;
4.554 + throw IoParameterError(msg.message());
4.555 + }
4.556 + }
4.557 + while (getline(is, line)) {
4.558 + std::istringstream ls(line);
4.559 + Edge edge = labelReader->read(ls);
4.560 + for (int i = 0; i < int(index.size()); ++i) {
4.561 + index[i]->read(ls, edge);
4.562 + }
4.563 + }
4.564 + }
4.565 +
4.566 + virtual void missing() {
4.567 + if (readers.empty()) return;
4.568 + ErrorMessage msg;
4.569 + msg << "EdgeMap section not found in file: @edgemaps " << name;
4.570 + throw IoParameterError(msg.message());
4.571 + }
4.572 +
4.573 + private:
4.574 +
4.575 + typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
4.576 + MapReaders readers;
4.577 +
4.578 + const Graph& graph;
4.579 + std::string name;
4.580 + _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
4.581 + std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader;
4.582 +
4.583 + };
4.584 +
4.585 + /// \ingroup section_io
4.586 + /// \brief SectionReader for reading extra undirected edge maps.
4.587 + ///
4.588 + /// The lemon format can store maps in the uedgeset sections. This
4.589 + /// class let you make distinict section to store maps. The main
4.590 + /// purpose of this class is a logical separation of some maps. The
4.591 + /// other useful application could be to store paths in undirected
4.592 + /// edge maps.
4.593 + ///
4.594 + /// The first line of the section contains the names of the maps
4.595 + /// separated with white spaces. Each next line describes an item
4.596 + /// in the itemset, and contains in the first column the label of
4.597 + /// the item and then the mapped values for each map.
4.598 + ///
4.599 + /// \relates LemonReader
4.600 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
4.601 + class UEdgeMapReader : public LemonReader::SectionReader {
4.602 + typedef LemonReader::SectionReader Parent;
4.603 + public:
4.604 +
4.605 + typedef _Graph Graph;
4.606 + typedef typename Graph::Edge Edge;
4.607 + typedef typename Graph::UEdge UEdge;
4.608 + typedef _Traits Traits;
4.609 + typedef typename Traits::Skipper DefaultSkipper;
4.610 +
4.611 + /// \brief Constructor.
4.612 + ///
4.613 + /// Constructor for UEdgeMapReader. It creates the UEdgeMapReader and
4.614 + /// attach it into the given LemonReader. The reader will read
4.615 + /// the section when the \c section_name and the \c _name are the same.
4.616 + template <typename _LabelReader>
4.617 + UEdgeMapReader(LemonReader& _reader, const Graph& _graph,
4.618 + const _LabelReader& _labelReader,
4.619 + const std::string& _name = std::string(),
4.620 + const DefaultSkipper& _skipper = DefaultSkipper())
4.621 + : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
4.622 + labelReader.reset(new _reader_bits::
4.623 + LabelReader<UEdge, _LabelReader>(_labelReader));
4.624 + }
4.625 +
4.626 +
4.627 + /// \brief Destructor.
4.628 + ///
4.629 + /// Destructor for UEdgeMapReader.
4.630 + virtual ~UEdgeMapReader() {
4.631 + for (typename MapReaders::iterator it = readers.begin();
4.632 + it != readers.end(); ++it) {
4.633 + delete it->second;
4.634 + }
4.635 + }
4.636 +
4.637 + private:
4.638 + UEdgeMapReader(const UEdgeMapReader&);
4.639 + void operator=(const UEdgeMapReader&);
4.640 +
4.641 + public:
4.642 +
4.643 + /// \brief Add a new undirected edge map reader command for the
4.644 + /// reader.
4.645 + ///
4.646 + /// Add a new undirected edge map reader command for the reader.
4.647 + template <typename Map>
4.648 + UEdgeMapReader& readUEdgeMap(std::string label, Map& map) {
4.649 + return _readMap<
4.650 + typename Traits::template Reader<typename Map::Value>, Map,
4.651 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.652 + }
4.653 +
4.654 + template <typename Map>
4.655 + UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) {
4.656 + return _readMap<
4.657 + typename Traits::template Reader<typename Map::Value>, Map,
4.658 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.659 + }
4.660 +
4.661 + /// \brief Add a new undirected edge map reader command for the
4.662 + /// reader.
4.663 + ///
4.664 + /// Add a new undirected edge map reader command for the reader.
4.665 + template <typename ItemReader, typename Map>
4.666 + UEdgeMapReader& readUEdgeMap(std::string label, Map& map,
4.667 + const ItemReader& ir = ItemReader()) {
4.668 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.669 + (label, map, ir);
4.670 + }
4.671 +
4.672 + template <typename ItemReader, typename Map>
4.673 + UEdgeMapReader& readUEdgeMap(std::string label, const Map& map,
4.674 + const ItemReader& ir = ItemReader()) {
4.675 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.676 + (label, map, ir);
4.677 + }
4.678 +
4.679 + private:
4.680 +
4.681 + template <typename ItemReader, typename Map, typename MapParameter>
4.682 + UEdgeMapReader& _readMap(std::string label, MapParameter map,
4.683 + const ItemReader& ir = ItemReader()) {
4.684 + checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
4.685 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
4.686 + if (readers.find(label) != readers.end()) {
4.687 + ErrorMessage msg;
4.688 + msg << "Multiple read rule for map: " << label;
4.689 + throw IoParameterError(msg.message());
4.690 + }
4.691 + readers.insert(
4.692 + make_pair(label, new _reader_bits::
4.693 + MapReader<UEdge, Map, ItemReader>(map, ir)));
4.694 + return *this;
4.695 + }
4.696 +
4.697 + public:
4.698 +
4.699 + /// \brief Add a new undirected edge map skipper command for the
4.700 + /// reader.
4.701 + ///
4.702 + /// Add a new undirected edge map skipper command for the reader.
4.703 + template <typename ItemReader>
4.704 + UEdgeMapReader& skipUEdgeMap(std::string label,
4.705 + const ItemReader& ir = ItemReader()) {
4.706 + if (readers.find(label) != readers.end()) {
4.707 + ErrorMessage msg;
4.708 + msg << "Multiple read rule for map: " << label;
4.709 + throw IoParameterError(msg.message());
4.710 + }
4.711 + readers.insert(make_pair(label, new _reader_bits::
4.712 + SkipReader<Edge, ItemReader>(ir)));
4.713 + return *this;
4.714 + }
4.715 +
4.716 + /// \brief Add a new directed edge map reader command for the reader.
4.717 + ///
4.718 + /// Add a new directed edge map reader command for the reader.
4.719 + template <typename Map>
4.720 + UEdgeMapReader& readEdgeMap(std::string label, Map& map) {
4.721 + return _readDirMap<
4.722 + typename Traits::template Reader<typename Map::Value>, Map,
4.723 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.724 + }
4.725 +
4.726 + template <typename Map>
4.727 + UEdgeMapReader& readEdgeMap(std::string label, const Map& map) {
4.728 + return _readDirMap<
4.729 + typename Traits::template Reader<typename Map::Value>, Map,
4.730 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.731 + }
4.732 +
4.733 + /// \brief Add a new directed edge map reader command for the reader.
4.734 + ///
4.735 + /// Add a new directed edge map reader command for the reader.
4.736 + template <typename ItemReader, typename Map>
4.737 + UEdgeMapReader& readEdgeMap(std::string label, Map& map,
4.738 + const ItemReader& ir = ItemReader()) {
4.739 + return _readDirMap<ItemReader, Map,
4.740 + typename _reader_bits::Arg<Map>::Type>(label, map, ir);
4.741 + }
4.742 +
4.743 + template <typename ItemReader, typename Map>
4.744 + UEdgeMapReader& readEdgeMap(std::string label, const Map& map,
4.745 + const ItemReader& ir = ItemReader()) {
4.746 + return _readDirMap<ItemReader, Map,
4.747 + typename _reader_bits::Arg<Map>::Type>(label, map, ir);
4.748 + }
4.749 +
4.750 + private:
4.751 +
4.752 + template <typename ItemReader, typename Map, typename MapParameter>
4.753 + UEdgeMapReader& _readDirMap(std::string label, MapParameter map,
4.754 + const ItemReader& ir = ItemReader()) {
4.755 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
4.756 + checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
4.757 + readUEdgeMap("+" + label,
4.758 + _reader_bits::forwardComposeMap(graph, map), ir);
4.759 + readUEdgeMap("-" + label,
4.760 + _reader_bits::backwardComposeMap(graph, map), ir);
4.761 + return *this;
4.762 + }
4.763 +
4.764 + public:
4.765 +
4.766 + /// \brief Add a new directed edge map skipper command for the reader.
4.767 + ///
4.768 + /// Add a new directed edge map skipper command for the reader.
4.769 + template <typename ItemReader>
4.770 + UEdgeMapReader& skipEdgeMap(std::string label,
4.771 + const ItemReader& ir = ItemReader()) {
4.772 + skipUEdgeMap("+" + label, ir);
4.773 + skipUEdgeMap("-" + label, ir);
4.774 + return *this;
4.775 + }
4.776 +
4.777 + protected:
4.778 +
4.779 + /// \brief Gives back true when the SectionReader can process
4.780 + /// the section with the given header line.
4.781 + ///
4.782 + /// It gives back true when the header line starts with \c \@mapset,
4.783 + /// and the header line's name and the mapset's name are the same.
4.784 + virtual bool header(const std::string& line) {
4.785 + std::istringstream ls(line);
4.786 + std::string command;
4.787 + std::string id;
4.788 + ls >> command >> id;
4.789 + return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
4.790 + }
4.791 +
4.792 + /// \brief Reader function of the section.
4.793 + ///
4.794 + /// It reads the content of the section.
4.795 + virtual void read(std::istream& is) {
4.796 + std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
4.797 + std::string line;
4.798 +
4.799 + {
4.800 + getline(is, line);
4.801 + std::istringstream ls(line);
4.802 + std::string id;
4.803 + while (ls >> id) {
4.804 + typename MapReaders::iterator it = readers.find(id);
4.805 + if (it != readers.end()) {
4.806 + it->second->touch();
4.807 + index.push_back(it->second);
4.808 + } else {
4.809 + index.push_back(&skipper);
4.810 + }
4.811 + }
4.812 + }
4.813 + for (typename MapReaders::iterator it = readers.begin();
4.814 + it != readers.end(); ++it) {
4.815 + if (!it->second->touched()) {
4.816 + ErrorMessage msg;
4.817 + msg << "Map not found in file: " << it->first;
4.818 + throw IoParameterError(msg.message());
4.819 + }
4.820 + }
4.821 + while (getline(is, line)) {
4.822 + std::istringstream ls(line);
4.823 + UEdge uedge = labelReader->read(ls);
4.824 + for (int i = 0; i < int(index.size()); ++i) {
4.825 + index[i]->read(ls, uedge);
4.826 + }
4.827 + }
4.828 + }
4.829 +
4.830 + virtual void missing() {
4.831 + if (readers.empty()) return;
4.832 + ErrorMessage msg;
4.833 + msg << "UEdgeMap section not found in file: @uedgemaps " << name;
4.834 + throw IoParameterError(msg.message());
4.835 + }
4.836 +
4.837 + private:
4.838 +
4.839 + const Graph& graph;
4.840 + std::string name;
4.841 +
4.842 + typedef std::map<std::string,
4.843 + _reader_bits::MapReaderBase<UEdge>*> MapReaders;
4.844 +
4.845 + MapReaders readers;
4.846 + _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
4.847 +
4.848 + std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader;
4.849 +
4.850 + };
4.851 +
4.852 + /// \ingroup section_io
4.853 /// \brief SectionReader for retrieve what is in the file.
4.854 ///
4.855 /// SectionReader for retrieve what is in the file. If you want
5.1 --- a/lemon/lemon_writer.h Tue Aug 28 13:58:54 2007 +0000
5.2 +++ b/lemon/lemon_writer.h Tue Aug 28 14:00:42 2007 +0000
5.3 @@ -71,6 +71,22 @@
5.4 Less<typename Map::Value> less;
5.5 };
5.6
5.7 + template <typename UGraph, typename Map>
5.8 + struct UEdgeComposeLess {
5.9 + UEdgeComposeLess(const UGraph& _ugraph, const Map& _map)
5.10 + : ugraph(_ugraph), map(_map), less() {}
5.11 +
5.12 + bool operator()(const typename UGraph::Edge& p,
5.13 + const typename UGraph::Edge& q) const {
5.14 + return p != q ? less(map[p], map[q]) :
5.15 + (!ugraph.direction(p) && ugraph.direction(q));
5.16 + }
5.17 +
5.18 + const UGraph& ugraph;
5.19 + const Map& map;
5.20 + Less<typename Map::Value> less;
5.21 + };
5.22 +
5.23 template <typename Item>
5.24 class ItemLabelWriter {
5.25 public:
5.26 @@ -123,8 +139,8 @@
5.27 ForwardComposeMap(const Graph& _graph, const Map& _map)
5.28 : graph(_graph), map(_map) {}
5.29
5.30 - Value operator[](const Key& key) {
5.31 - return map[graph.direct(key, false)];
5.32 + Value operator[](const Key& key) const {
5.33 + return map[graph.direct(key, true)];
5.34 }
5.35
5.36 private:
5.37 @@ -147,7 +163,7 @@
5.38 BackwardComposeMap(const Graph& _graph, const Map& _map)
5.39 : graph(_graph), map(_map) {}
5.40
5.41 - Value operator[](const Key& key) {
5.42 + Value operator[](const Key& key) const {
5.43 return map[graph.direct(key, false)];
5.44 }
5.45
5.46 @@ -199,7 +215,7 @@
5.47 virtual ~MapWriterBase() {}
5.48
5.49 virtual void write(std::ostream& os, const Item& item) const = 0;
5.50 - virtual void sortByMap(std::vector<Item>&) const = 0;
5.51 + virtual void sort(std::vector<Item>&) const = 0;
5.52 };
5.53
5.54
5.55 @@ -224,7 +240,59 @@
5.56 writer.write(os, value);
5.57 }
5.58
5.59 - virtual void sortByMap(std::vector<Item>& items) const {
5.60 + virtual void sort(std::vector<Item>& items) const {
5.61 + ComposeLess<Map> less(map);
5.62 + std::sort(items.begin(), items.end(), less);
5.63 + }
5.64 +
5.65 + };
5.66 +
5.67 + template <typename _UGraph>
5.68 + class UEdgeMapWriterBase {
5.69 + public:
5.70 + typedef typename _UGraph::Edge Edge;
5.71 + typedef typename _UGraph::UEdge UEdge;
5.72 +
5.73 + typedef UEdge Item;
5.74 +
5.75 + virtual ~UEdgeMapWriterBase() {}
5.76 +
5.77 + virtual void write(std::ostream& os, const Item& item) const = 0;
5.78 + virtual void sort(const _UGraph&, std::vector<Edge>&) const = 0;
5.79 + virtual void sort(std::vector<UEdge>&) const = 0;
5.80 + };
5.81 +
5.82 +
5.83 + template <typename _UGraph, typename _Map, typename _Writer>
5.84 + class UEdgeMapWriter : public UEdgeMapWriterBase<_UGraph> {
5.85 + public:
5.86 + typedef _Map Map;
5.87 + typedef _Writer Writer;
5.88 + typedef typename Writer::Value Value;
5.89 +
5.90 + typedef typename _UGraph::Edge Edge;
5.91 + typedef typename _UGraph::UEdge UEdge;
5.92 + typedef UEdge Item;
5.93 +
5.94 + typename _writer_bits::Ref<Map>::Type map;
5.95 + Writer writer;
5.96 +
5.97 + UEdgeMapWriter(const Map& _map, const Writer& _writer)
5.98 + : map(_map), writer(_writer) {}
5.99 +
5.100 + virtual ~UEdgeMapWriter() {}
5.101 +
5.102 + virtual void write(std::ostream& os, const Item& item) const {
5.103 + Value value = map[item];
5.104 + writer.write(os, value);
5.105 + }
5.106 +
5.107 + virtual void sort(const _UGraph& ugraph, std::vector<Edge>& items) const {
5.108 + UEdgeComposeLess<_UGraph, Map> less(ugraph, map);
5.109 + std::sort(items.begin(), items.end(), less);
5.110 + }
5.111 +
5.112 + virtual void sort(std::vector<UEdge>& items) const {
5.113 ComposeLess<Map> less(map);
5.114 std::sort(items.begin(), items.end(), less);
5.115 }
5.116 @@ -262,7 +330,9 @@
5.117 typedef _Item Item;
5.118 virtual ~LabelWriterBase() {}
5.119 virtual void write(std::ostream&, const Item&) const = 0;
5.120 + virtual void sort(std::vector<Item>&) const = 0;
5.121 virtual bool isLabelWriter() const = 0;
5.122 + virtual LabelWriterBase* clone() const = 0;
5.123 };
5.124
5.125 template <typename _Item, typename _BoxedLabelWriter>
5.126 @@ -279,10 +349,17 @@
5.127 virtual void write(std::ostream& os, const Item& item) const {
5.128 labelWriter.writeLabel(os, item);
5.129 }
5.130 + virtual void sort(std::vector<Item>& items) const {
5.131 + labelWriter.sortByLabel(items);
5.132 + }
5.133
5.134 virtual bool isLabelWriter() const {
5.135 return labelWriter.isLabelWriter();
5.136 }
5.137 +
5.138 + virtual LabelWriter* clone() const {
5.139 + return new LabelWriter(labelWriter);
5.140 + }
5.141 };
5.142
5.143 }
5.144 @@ -425,7 +502,7 @@
5.145 /// \c writeLabel() member will be called with a node it will write it's
5.146 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
5.147 /// then the label map will be the id in the graph. In addition if the
5.148 - /// the \c _sortByLabel is true then the writer will write the edges
5.149 + /// the \c _forceSort is true then the writer will write the edges
5.150 /// sorted by the labels.
5.151 ///
5.152 /// \relates LemonWriter
5.153 @@ -444,13 +521,13 @@
5.154 /// attach it into the given LemonWriter. If the \c _forceLabelMap
5.155 /// parameter is true then the writer will write own label map when
5.156 /// the user does not give "label" named map. In addition if the
5.157 - /// the \c _sortByLabel is true then the writer will write the edges
5.158 + /// the \c _forceSort is true then the writer will write the edges
5.159 /// sorted by the labels.
5.160 NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
5.161 const std::string& _name = std::string(),
5.162 - bool _forceLabelMap = true, bool _sortByLabel = true)
5.163 + bool _forceLabelMap = true, bool _forceSort = true)
5.164 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
5.165 - sortByLabel(_sortByLabel), graph(_graph), name(_name) {}
5.166 + forceSort(_forceSort), graph(_graph), name(_name) {}
5.167
5.168 /// \brief Destructor.
5.169 ///
5.170 @@ -515,9 +592,9 @@
5.171 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
5.172 items.push_back(it);
5.173 }
5.174 - if (sortByLabel) {
5.175 + if (forceSort) {
5.176 if (labelMap) {
5.177 - labelMap->sortByMap(items);
5.178 + labelMap->sort(items);
5.179 } else {
5.180 typedef IdMap<Graph, Node> Map;
5.181 Map map(graph);
5.182 @@ -550,7 +627,7 @@
5.183 /// \brief Returns true if the nodeset can write the labels of the nodes.
5.184 ///
5.185 /// Returns true if the nodeset can write the labels of the nodes.
5.186 - /// It is possible only if an "label" named map was written or the
5.187 + /// It is possible only if a "label" named map was written or the
5.188 /// \c _forceLabelMap constructor parameter was true.
5.189 bool isLabelWriter() const {
5.190 return labelMap != 0 || forceLabelMap;
5.191 @@ -558,7 +635,7 @@
5.192
5.193 /// \brief Write the label of the given node.
5.194 ///
5.195 - /// It writes the label of the given node. If there was written an "label"
5.196 + /// It writes the label of the given node. If there was written a "label"
5.197 /// named map then it will write the map value belongs to the node.
5.198 /// Otherwise if the \c forceLabel parameter was true it will write
5.199 /// its label in the graph.
5.200 @@ -570,6 +647,23 @@
5.201 }
5.202 }
5.203
5.204 + /// \brief Sorts the given node vector by label.
5.205 + ///
5.206 + /// Sorts the given node vector by label. If there was written an
5.207 + /// "label" named map then the vector will be sorted by the values
5.208 + /// of this map. Otherwise if the \c forceLabel parameter was true
5.209 + /// it will be sorted by its id in the graph.
5.210 + void sortByLabel(std::vector<Node>& nodes) const {
5.211 + if (labelMap) {
5.212 + labelMap->sort(nodes);
5.213 + } else {
5.214 + typedef IdMap<Graph, Node> Map;
5.215 + Map map(graph);
5.216 + _writer_bits::ComposeLess<Map> less(map);
5.217 + std::sort(nodes.begin(), nodes.end(), less);
5.218 + }
5.219 + }
5.220 +
5.221 private:
5.222
5.223 typedef std::vector<std::pair<std::string, _writer_bits::
5.224 @@ -578,7 +672,7 @@
5.225
5.226 _writer_bits::MapWriterBase<Node>* labelMap;
5.227 bool forceLabelMap;
5.228 - bool sortByLabel;
5.229 + bool forceSort;
5.230
5.231 const Graph& graph;
5.232 std::string name;
5.233 @@ -602,7 +696,7 @@
5.234 /// \c writeLabel() member will be called with an edge it will write it's
5.235 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
5.236 /// then the label map will be the id in the graph. In addition if the
5.237 - /// the \c _sortByLabel is true then the writer will write the edges
5.238 + /// the \c _forceSort is true then the writer will write the edges
5.239 /// sorted by the labels.
5.240 ///
5.241 /// The edgeset writer needs a node label writer to identify which nodes
5.242 @@ -627,15 +721,15 @@
5.243 /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
5.244 /// parameter is true then the writer will write own label map if
5.245 /// the user does not give "label" named map. In addition if the
5.246 - /// the \c _sortByLabel is true then the writer will write the
5.247 + /// the \c _forceSort is true then the writer will write the
5.248 /// edges sorted by the labels.
5.249 template <typename NodeLabelWriter>
5.250 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
5.251 const NodeLabelWriter& _nodeLabelWriter,
5.252 const std::string& _name = std::string(),
5.253 - bool _forceLabelMap = true, bool _sortByLabel = true)
5.254 + bool _forceLabelMap = true, bool _forceSort = true)
5.255 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
5.256 - sortByLabel(_sortByLabel), graph(_graph), name(_name) {
5.257 + forceSort(_forceSort), graph(_graph), name(_name) {
5.258 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
5.259 nodeLabelWriter.reset(new _writer_bits::
5.260 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
5.261 @@ -707,9 +801,9 @@
5.262 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
5.263 items.push_back(it);
5.264 }
5.265 - if (sortByLabel) {
5.266 + if (forceSort) {
5.267 if (labelMap) {
5.268 - labelMap->sortByMap(items);
5.269 + labelMap->sort(items);
5.270 } else {
5.271 typedef IdMap<Graph, Edge> Map;
5.272 Map map(graph);
5.273 @@ -747,7 +841,7 @@
5.274 /// \brief Returns true if the edgeset can write the labels of the edges.
5.275 ///
5.276 /// Returns true if the edgeset can write the labels of the edges.
5.277 - /// It is possible only if an "label" named map was written or the
5.278 + /// It is possible only if a "label" named map was written or the
5.279 /// \c _forceLabelMap constructor parameter was true.
5.280 bool isLabelWriter() const {
5.281 return forceLabelMap || labelMap != 0;
5.282 @@ -755,7 +849,7 @@
5.283
5.284 /// \brief Write the label of the given edge.
5.285 ///
5.286 - /// It writes the label of the given edge. If there was written an "label"
5.287 + /// It writes the label of the given edge. If there was written a "label"
5.288 /// named map then it will write the map value belongs to the edge.
5.289 /// Otherwise if the \c forceLabel parameter was true it will write
5.290 /// its label in the graph.
5.291 @@ -767,6 +861,23 @@
5.292 }
5.293 }
5.294
5.295 + /// \brief Sorts the given edge vector by label.
5.296 + ///
5.297 + /// Sorts the given edge vector by label. If there was written an
5.298 + /// "label" named map then the vector will be sorted by the values
5.299 + /// of this map. Otherwise if the \c forceLabel parameter was true
5.300 + /// it will be sorted by its id in the graph.
5.301 + void sortByLabel(std::vector<Edge>& edges) const {
5.302 + if (labelMap) {
5.303 + labelMap->sort(edges);
5.304 + } else {
5.305 + typedef IdMap<Graph, Edge> Map;
5.306 + Map map(graph);
5.307 + _writer_bits::ComposeLess<Map> less(map);
5.308 + std::sort(edges.begin(), edges.end(), less);
5.309 + }
5.310 + }
5.311 +
5.312 private:
5.313
5.314 typedef std::vector<std::pair<std::string, _writer_bits::
5.315 @@ -775,7 +886,7 @@
5.316
5.317 _writer_bits::MapWriterBase<Edge>* labelMap;
5.318 bool forceLabelMap;
5.319 - bool sortByLabel;
5.320 + bool forceSort;
5.321
5.322 const Graph& graph;
5.323 std::string name;
5.324 @@ -807,7 +918,7 @@
5.325 /// an undirected edge it will write it's label. Otherwise if the \c
5.326 /// _forceLabelMap constructor parameter is true then the label map
5.327 /// will be the id in the graph. In addition if the the \c
5.328 - /// _sortByLabel is true then the writer will write the edges sorted
5.329 + /// _forceSort is true then the writer will write the edges sorted
5.330 /// by the labels.
5.331 ///
5.332 /// The undirected edgeset writer needs a node label writer to identify
5.333 @@ -833,18 +944,18 @@
5.334 /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
5.335 /// parameter is true then the writer will write own label map if
5.336 /// the user does not give "label" named map. In addition if the
5.337 - /// the \c _sortByLabel is true then the writer will write the
5.338 + /// the \c _forceSort is true then the writer will write the
5.339 /// edges sorted by the labels.
5.340 template <typename NodeLabelWriter>
5.341 UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
5.342 const NodeLabelWriter& _nodeLabelWriter,
5.343 const std::string& _name = std::string(),
5.344 - bool _forceLabelMap = true, bool _sortByLabel = true)
5.345 + bool _forceLabelMap = true, bool _forceSort = true)
5.346 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
5.347 - sortByLabel(_sortByLabel), graph(_graph), name(_name) {
5.348 + forceSort(_forceSort), graph(_graph), name(_name) {
5.349 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
5.350 nodeLabelWriter.reset(new _writer_bits::
5.351 - LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
5.352 + LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
5.353 }
5.354
5.355 /// \brief Destructor.
5.356 @@ -882,7 +993,7 @@
5.357 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
5.358 writers.push_back(
5.359 make_pair(label, new _writer_bits::
5.360 - MapWriter<UEdge, Map, ItemWriter>(map, iw)));
5.361 + UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
5.362 return *this;
5.363 }
5.364
5.365 @@ -903,9 +1014,9 @@
5.366 const ItemWriter& iw = ItemWriter()) {
5.367 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
5.368 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
5.369 - writeUEdgeMap("+" + name,
5.370 + writeUEdgeMap("+" + label,
5.371 _writer_bits::forwardComposeMap(graph, map), iw);
5.372 - writeUEdgeMap("-" + name,
5.373 + writeUEdgeMap("-" + label,
5.374 _writer_bits::backwardComposeMap(graph, map), iw);
5.375 return *this;
5.376 }
5.377 @@ -937,9 +1048,9 @@
5.378 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
5.379 items.push_back(it);
5.380 }
5.381 - if (sortByLabel) {
5.382 + if (forceSort) {
5.383 if (labelMap) {
5.384 - labelMap->sortByMap(items);
5.385 + labelMap->sort(items);
5.386 } else {
5.387 typedef IdMap<Graph, UEdge> Map;
5.388 Map map(graph);
5.389 @@ -978,7 +1089,7 @@
5.390 /// the edges.
5.391 ///
5.392 /// Returns true if the undirected edgeset can write the labels of the
5.393 - /// undirected edges. It is possible only if an "label" named map was
5.394 + /// undirected edges. It is possible only if a "label" named map was
5.395 /// written or the \c _forceLabelMap constructor parameter was true.
5.396 bool isLabelWriter() const {
5.397 return forceLabelMap || labelMap != 0;
5.398 @@ -987,7 +1098,7 @@
5.399 /// \brief Write the label of the given undirected edge.
5.400 ///
5.401 /// It writes the label of the given undirected edge. If there was written
5.402 - /// an "label" named map then it will write the map value belongs to the
5.403 + /// a "label" named map then it will write the map value belongs to the
5.404 /// undirected edge. Otherwise if the \c forceLabel parameter was true it
5.405 /// will write its id in the graph.
5.406 void writeLabel(std::ostream& os, const UEdge& item) const {
5.407 @@ -1001,32 +1112,66 @@
5.408 /// \brief Write the label of the given edge.
5.409 ///
5.410 /// It writes the label of the given edge. If there was written
5.411 - /// an "label" named map then it will write the map value belongs to the
5.412 + /// a "label" named map then it will write the map value belongs to the
5.413 /// edge. Otherwise if the \c forceLabel parameter was true it
5.414 /// will write its id in the graph. If the edge is forward map
5.415 /// then its prefix character is \c '+' elsewhere \c '-'.
5.416 void writeLabel(std::ostream& os, const Edge& item) const {
5.417 if (graph.direction(item)) {
5.418 - os << "+ ";
5.419 + os << "+";
5.420 } else {
5.421 - os << "- ";
5.422 + os << "-";
5.423 }
5.424 if (forceLabelMap) {
5.425 - os << graph.id(item);
5.426 + os << graph.id(static_cast<const UEdge&>(item));
5.427 } else {
5.428 labelMap->write(os, item);
5.429 }
5.430 }
5.431
5.432 + /// \brief Sorts the given undirected edge vector by label.
5.433 + ///
5.434 + /// Sorts the given undirected edge vector by label. If there was
5.435 + /// written a "label" named map then the vector will be sorted by
5.436 + /// the values of this map. Otherwise if the \c forceLabel
5.437 + /// parameter was true it will be sorted by its id in the graph.
5.438 + void sortByLabel(std::vector<UEdge>& uedges) const {
5.439 + if (labelMap) {
5.440 + labelMap->sort(uedges);
5.441 + } else {
5.442 + typedef IdMap<Graph, UEdge> Map;
5.443 + Map map(graph);
5.444 + _writer_bits::ComposeLess<Map> less(map);
5.445 + std::sort(uedges.begin(), uedges.end(), less);
5.446 + }
5.447 + }
5.448 +
5.449 + /// \brief Sorts the given edge vector by label.
5.450 + ///
5.451 + /// Sorts the given edge vector by label. If there was written a
5.452 + /// "label" named map then the vector will be sorted by the values
5.453 + /// of this map. Otherwise if the \c forceLabel parameter was true
5.454 + /// it will be sorted by its id in the graph.
5.455 + void sortByLabel(std::vector<Edge>& edges) const {
5.456 + if (labelMap) {
5.457 + labelMap->sort(graph, edges);
5.458 + } else {
5.459 + typedef IdMap<Graph, Edge> Map;
5.460 + Map map(graph);
5.461 + _writer_bits::ComposeLess<Map> less(map);
5.462 + std::sort(edges.begin(), edges.end(), less);
5.463 + }
5.464 + }
5.465 +
5.466 private:
5.467
5.468 typedef std::vector<std::pair<std::string, _writer_bits::
5.469 - MapWriterBase<UEdge>*> > MapWriters;
5.470 + UEdgeMapWriterBase<Graph>*> > MapWriters;
5.471 MapWriters writers;
5.472
5.473 - _writer_bits::MapWriterBase<UEdge>* labelMap;
5.474 + _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
5.475 bool forceLabelMap;
5.476 - bool sortByLabel;
5.477 + bool forceSort;
5.478
5.479 const Graph& graph;
5.480 std::string name;
5.481 @@ -1206,6 +1351,7 @@
5.482 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
5.483 };
5.484
5.485 +
5.486 /// \ingroup section_io
5.487 /// \brief SectionWriter for writing named undirected edges.
5.488 ///
5.489 @@ -1321,6 +1467,429 @@
5.490 };
5.491
5.492 /// \ingroup section_io
5.493 + /// \brief SectionWriter for writing extra node maps.
5.494 + ///
5.495 + /// The lemon format can store maps in the nodeset. This class let
5.496 + /// you make distinict section to store maps. The main purpose of
5.497 + /// this class is a logical separation of some maps. The other
5.498 + /// useful application could be to store paths in node maps.
5.499 + ///
5.500 + /// The first line of the section contains the names of the maps
5.501 + /// separated with white spaces. Each next line describes an item
5.502 + /// in the itemset, and contains in the first column the label of
5.503 + /// the item and then the mapped values for each map.
5.504 + ///
5.505 + /// \relates LemonWriter
5.506 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
5.507 + class NodeMapWriter : public LemonWriter::SectionWriter {
5.508 + typedef LemonWriter::SectionWriter Parent;
5.509 + public:
5.510 +
5.511 + typedef _Graph Graph;
5.512 + typedef _Traits Traits;
5.513 + typedef typename Graph::Node Node;
5.514 +
5.515 + /// \brief Constructor.
5.516 + ///
5.517 + /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
5.518 + /// attach it into the given LemonWriter. If the the
5.519 + /// \c _forceSort is true then the writer will write the edges
5.520 + /// sorted by the labels.
5.521 + template <typename _LabelWriter>
5.522 + NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
5.523 + const _LabelWriter& _labelWriter,
5.524 + const std::string& _name = std::string(),
5.525 + bool _forceSort = true)
5.526 + : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
5.527 + checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
5.528 + labelWriter.reset(new _writer_bits::LabelWriter<Node,
5.529 + _LabelWriter>(_labelWriter));
5.530 + }
5.531 +
5.532 + /// \brief Destructor.
5.533 + ///
5.534 + /// Destructor for NodeMapWriter.
5.535 + virtual ~NodeMapWriter() {
5.536 + typename MapWriters::iterator it;
5.537 + for (it = writers.begin(); it != writers.end(); ++it) {
5.538 + delete it->second;
5.539 + }
5.540 + }
5.541 +
5.542 + private:
5.543 + NodeMapWriter(const NodeMapWriter&);
5.544 + void operator=(const NodeMapWriter&);
5.545 +
5.546 + public:
5.547 +
5.548 + /// \brief Add a new node map writer command for the writer.
5.549 + ///
5.550 + /// Add a new node map writer command for the writer.
5.551 + template <typename Map>
5.552 + NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
5.553 + return writeNodeMap<typename Traits::
5.554 + template Writer<typename Map::Value>, Map>(label, map);
5.555 + }
5.556 +
5.557 + /// \brief Add a new node map writer command for the writer.
5.558 + ///
5.559 + /// Add a new node map writer command for the writer.
5.560 + template <typename ItemWriter, typename Map>
5.561 + NodeMapWriter& writeNodeMap(std::string label, const Map& map,
5.562 + const ItemWriter& iw = ItemWriter()) {
5.563 + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
5.564 + checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
5.565 + writers.push_back(
5.566 + make_pair(label, new _writer_bits::
5.567 + MapWriter<Node, Map, ItemWriter>(map, iw)));
5.568 + return *this;
5.569 + }
5.570 +
5.571 + protected:
5.572 +
5.573 + /// \brief The header of the section.
5.574 + ///
5.575 + /// It gives back the header of the section.
5.576 + virtual std::string header() {
5.577 + return "@nodemaps " + name;
5.578 + }
5.579 +
5.580 + /// \brief Writer function of the section.
5.581 + ///
5.582 + /// Write the content of the section.
5.583 + virtual void write(std::ostream& os) {
5.584 + std::vector<Node> nodes;
5.585 + for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
5.586 + nodes.push_back(it);
5.587 + }
5.588 + if (forceSort) {
5.589 + labelWriter->sort(nodes);
5.590 + }
5.591 + os << '\t';
5.592 + for (int i = 0; i < int(writers.size()); ++i) {
5.593 + os << writers[i].first << '\t';
5.594 + }
5.595 + os << std::endl;
5.596 + for (typename std::vector<Node>::iterator it = nodes.begin();
5.597 + it != nodes.end(); ++it) {
5.598 +
5.599 + labelWriter->write(os, *it); os << '\t';
5.600 + for (int i = 0; i < int(writers.size()); ++i) {
5.601 + writers[i].second->write(os, *it);
5.602 + os << '\t';
5.603 + }
5.604 + os << std::endl;
5.605 + }
5.606 + }
5.607 +
5.608 +
5.609 + private:
5.610 +
5.611 + typedef std::vector<std::pair<std::string, _writer_bits::
5.612 + MapWriterBase<Node>*> > MapWriters;
5.613 + MapWriters writers;
5.614 +
5.615 + _writer_bits::MapWriterBase<Node>* labelMap;
5.616 +
5.617 + const Graph& graph;
5.618 + std::string name;
5.619 + bool forceSort;
5.620 +
5.621 + std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
5.622 + };
5.623 +
5.624 + /// \ingroup section_io
5.625 + /// \brief SectionWriter for writing extra edge maps.
5.626 + ///
5.627 + /// The lemon format can store maps in the edgeset. This class let
5.628 + /// you make distinict section to store maps. The main purpose of
5.629 + /// this class is a logical separation of some maps. The other
5.630 + /// useful application could be to store paths in edge maps.
5.631 + ///
5.632 + /// The first line of the section contains the names of the maps
5.633 + /// separated with white spaces. Each next line describes an item
5.634 + /// in the itemset, and contains in the first column the label of
5.635 + /// the item and then the mapped values for each map.
5.636 + ///
5.637 + /// \relates LemonWriter
5.638 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
5.639 + class EdgeMapWriter : public LemonWriter::SectionWriter {
5.640 + typedef LemonWriter::SectionWriter Parent;
5.641 + public:
5.642 +
5.643 + typedef _Graph Graph;
5.644 + typedef _Traits Traits;
5.645 + typedef typename Graph::Edge Edge;
5.646 +
5.647 + /// \brief Constructor.
5.648 + ///
5.649 + /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
5.650 + /// attach it into the given LemonWriter. If the the
5.651 + /// \c _forceSort is true then the writer will write the edges
5.652 + /// sorted by the labels.
5.653 + template <typename _LabelWriter>
5.654 + EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
5.655 + const _LabelWriter& _labelWriter,
5.656 + const std::string& _name = std::string(),
5.657 + bool _forceSort = true)
5.658 + : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
5.659 + checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
5.660 + labelWriter.reset(new _writer_bits::LabelWriter<Edge,
5.661 + _LabelWriter>(_labelWriter));
5.662 + }
5.663 +
5.664 + /// \brief Destructor.
5.665 + ///
5.666 + /// Destructor for EdgeMapWriter.
5.667 + virtual ~EdgeMapWriter() {
5.668 + typename MapWriters::iterator it;
5.669 + for (it = writers.begin(); it != writers.end(); ++it) {
5.670 + delete it->second;
5.671 + }
5.672 + }
5.673 +
5.674 + private:
5.675 + EdgeMapWriter(const EdgeMapWriter&);
5.676 + void operator=(const EdgeMapWriter&);
5.677 +
5.678 + public:
5.679 +
5.680 + /// \brief Add a new edge map writer command for the writer.
5.681 + ///
5.682 + /// Add a new edge map writer command for the writer.
5.683 + template <typename Map>
5.684 + EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
5.685 + return writeEdgeMap<typename Traits::
5.686 + template Writer<typename Map::Value>, Map>(label, map);
5.687 + }
5.688 +
5.689 + /// \brief Add a new edge map writer command for the writer.
5.690 + ///
5.691 + /// Add a new edge map writer command for the writer.
5.692 + template <typename ItemWriter, typename Map>
5.693 + EdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
5.694 + const ItemWriter& iw = ItemWriter()) {
5.695 + checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
5.696 + checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
5.697 + writers.push_back(
5.698 + make_pair(label, new _writer_bits::
5.699 + MapWriter<Edge, Map, ItemWriter>(map, iw)));
5.700 + return *this;
5.701 + }
5.702 +
5.703 + protected:
5.704 +
5.705 + /// \brief The header of the section.
5.706 + ///
5.707 + /// It gives back the header of the section.
5.708 + virtual std::string header() {
5.709 + return "@edgemaps " + name;
5.710 + }
5.711 +
5.712 + /// \brief Writer function of the section.
5.713 + ///
5.714 + /// Write the content of the section.
5.715 + virtual void write(std::ostream& os) {
5.716 + std::vector<Edge> edges;
5.717 + for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
5.718 + edges.push_back(it);
5.719 + }
5.720 + if (forceSort) {
5.721 + labelWriter->sort(edges);
5.722 + }
5.723 + os << '\t';
5.724 + for (int i = 0; i < int(writers.size()); ++i) {
5.725 + os << writers[i].first << '\t';
5.726 + }
5.727 + os << std::endl;
5.728 + for (typename std::vector<Edge>::iterator it = edges.begin();
5.729 + it != edges.end(); ++it) {
5.730 +
5.731 + labelWriter->write(os, *it); os << '\t';
5.732 + for (int i = 0; i < int(writers.size()); ++i) {
5.733 + writers[i].second->write(os, *it);
5.734 + os << '\t';
5.735 + }
5.736 + os << std::endl;
5.737 + }
5.738 + }
5.739 +
5.740 +
5.741 + private:
5.742 +
5.743 + typedef std::vector<std::pair<std::string, _writer_bits::
5.744 + MapWriterBase<Edge>*> > MapWriters;
5.745 + MapWriters writers;
5.746 +
5.747 + _writer_bits::MapWriterBase<Edge>* labelMap;
5.748 +
5.749 + const Graph& graph;
5.750 + std::string name;
5.751 + bool forceSort;
5.752 +
5.753 + std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
5.754 + };
5.755 +
5.756 + /// \ingroup section_io
5.757 + /// \brief SectionWriter for writing extra undirected edge maps.
5.758 + ///
5.759 + /// The lemon format can store maps in the uedgeset. This class let
5.760 + /// you make distinict section to store maps. The main purpose of
5.761 + /// this class is a logical separation of some maps. The other
5.762 + /// useful application could be to store paths in undirected edge
5.763 + /// maps.
5.764 + ///
5.765 + /// The first line of the section contains the names of the maps
5.766 + /// separated with white spaces. Each next line describes an item
5.767 + /// in the itemset, and contains in the first column the label of
5.768 + /// the item and then the mapped values for each map.
5.769 + ///
5.770 + /// \relates LemonWriter
5.771 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
5.772 + class UEdgeMapWriter : public LemonWriter::SectionWriter {
5.773 + typedef LemonWriter::SectionWriter Parent;
5.774 + public:
5.775 +
5.776 + typedef _Graph Graph;
5.777 + typedef _Traits Traits;
5.778 + typedef typename Graph::UEdge UEdge;
5.779 + typedef typename Graph::Edge Edge;
5.780 +
5.781 + /// \brief Constructor.
5.782 + ///
5.783 + /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
5.784 + /// attach it into the given LemonWriter. If the the
5.785 + /// \c _forceSort is true then the writer will write the uedges
5.786 + /// sorted by the labels.
5.787 + template <typename _LabelWriter>
5.788 + UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
5.789 + const _LabelWriter& _labelWriter,
5.790 + const std::string& _name = std::string(),
5.791 + bool _forceSort = true)
5.792 + : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
5.793 + checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
5.794 + labelWriter.reset(new _writer_bits::LabelWriter<UEdge,
5.795 + _LabelWriter>(_labelWriter));
5.796 + }
5.797 +
5.798 + /// \brief Destructor.
5.799 + ///
5.800 + /// Destructor for UEdgeMapWriter.
5.801 + virtual ~UEdgeMapWriter() {
5.802 + typename MapWriters::iterator it;
5.803 + for (it = writers.begin(); it != writers.end(); ++it) {
5.804 + delete it->second;
5.805 + }
5.806 + }
5.807 +
5.808 + private:
5.809 + UEdgeMapWriter(const UEdgeMapWriter&);
5.810 + void operator=(const UEdgeMapWriter&);
5.811 +
5.812 + public:
5.813 +
5.814 + /// \brief Add a new undirected edge map writer command for the writer.
5.815 + ///
5.816 + /// Add a new undirected edge map writer command for the writer.
5.817 + template <typename Map>
5.818 + UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
5.819 + return writeUEdgeMap<typename Traits::
5.820 + template Writer<typename Map::Value>, Map>(label, map);
5.821 + }
5.822 +
5.823 + /// \brief Add a new undirected edge map writer command for the writer.
5.824 + ///
5.825 + /// Add a new undirected edge map writer command for the writer.
5.826 + template <typename ItemWriter, typename Map>
5.827 + UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map,
5.828 + const ItemWriter& iw = ItemWriter()) {
5.829 + checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
5.830 + checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
5.831 + writers.push_back(
5.832 + make_pair(label, new _writer_bits::
5.833 + MapWriter<UEdge, Map, ItemWriter>(map, iw)));
5.834 + return *this;
5.835 + }
5.836 +
5.837 + /// \brief Add a new directed edge map writer command for the writer.
5.838 + ///
5.839 + /// Add a new directed map writer command for the writer.
5.840 + template <typename Map>
5.841 + UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
5.842 + return writeEdgeMap<typename Traits::
5.843 + template Writer<typename Map::Value>, Map>(label, map);
5.844 + }
5.845 +
5.846 + /// \brief Add a new directed map writer command for the writer.
5.847 + ///
5.848 + /// Add a new directed map writer command for the writer.
5.849 + template <typename ItemWriter, typename Map>
5.850 + UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
5.851 + const ItemWriter& iw = ItemWriter()) {
5.852 + checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
5.853 + checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
5.854 + writeUEdgeMap("+" + label,
5.855 + _writer_bits::forwardComposeMap(graph, map), iw);
5.856 + writeUEdgeMap("-" + label,
5.857 + _writer_bits::backwardComposeMap(graph, map), iw);
5.858 + return *this;
5.859 + }
5.860 +
5.861 + protected:
5.862 +
5.863 + /// \brief The header of the section.
5.864 + ///
5.865 + /// It gives back the header of the section.
5.866 + virtual std::string header() {
5.867 + return "@uedgemaps " + name;
5.868 + }
5.869 +
5.870 + /// \brief Writer function of the section.
5.871 + ///
5.872 + /// Write the content of the section.
5.873 + virtual void write(std::ostream& os) {
5.874 + std::vector<UEdge> uedges;
5.875 + for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
5.876 + uedges.push_back(it);
5.877 + }
5.878 + if (forceSort) {
5.879 + labelWriter->sort(uedges);
5.880 + }
5.881 + os << '\t';
5.882 + for (int i = 0; i < int(writers.size()); ++i) {
5.883 + os << writers[i].first << '\t';
5.884 + }
5.885 + os << std::endl;
5.886 + for (typename std::vector<UEdge>::iterator it = uedges.begin();
5.887 + it != uedges.end(); ++it) {
5.888 +
5.889 + labelWriter->write(os, *it); os << '\t';
5.890 + for (int i = 0; i < int(writers.size()); ++i) {
5.891 + writers[i].second->write(os, *it);
5.892 + os << '\t';
5.893 + }
5.894 + os << std::endl;
5.895 + }
5.896 + }
5.897 +
5.898 +
5.899 + private:
5.900 +
5.901 + typedef std::vector<std::pair<std::string, _writer_bits::
5.902 + MapWriterBase<UEdge>*> > MapWriters;
5.903 + MapWriters writers;
5.904 +
5.905 + _writer_bits::MapWriterBase<UEdge>* labelMap;
5.906 +
5.907 + const Graph& graph;
5.908 + std::string name;
5.909 + bool forceSort;
5.910 +
5.911 + std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
5.912 + };
5.913 +
5.914 +
5.915 + /// \ingroup section_io
5.916 /// \brief SectionWriter for attributes.
5.917 ///
5.918 /// The lemon format can store multiple attribute set. Each set has
6.1 --- a/lemon/path_utils.h Tue Aug 28 13:58:54 2007 +0000
6.2 +++ b/lemon/path_utils.h Tue Aug 28 14:00:42 2007 +0000
6.3 @@ -25,6 +25,8 @@
6.4 #define LEMON_PATH_UTILS_H
6.5
6.6 #include <lemon/concepts/path.h>
6.7 +#include <lemon/lemon_reader.h>
6.8 +#include <lemon/lemon_writer.h>
6.9
6.10 namespace lemon {
6.11
6.12 @@ -132,6 +134,261 @@
6.13 typename Graph::Node pathTarget(const Graph& graph, const Path& path) {
6.14 return graph.target(path.back());
6.15 }
6.16 +
6.17 + /// \brief Class which helps to iterate the nodes of a path
6.18 + ///
6.19 + /// In a sense, the path can be treated as a list of edges. The
6.20 + /// lemon path type stores just this list. As a consequence it
6.21 + /// cannot enumerate the nodes in the path and the zero length paths
6.22 + /// cannot store the node.
6.23 + ///
6.24 + /// This class implements the node iterator of a path structure. To
6.25 + /// provide this feature, the underlying graph should be given to
6.26 + /// the constructor of the iterator.
6.27 + template <typename Path>
6.28 + class PathNodeIt {
6.29 + private:
6.30 + const typename Path::Graph *_graph;
6.31 + typename Path::EdgeIt _it;
6.32 + typename Path::Graph::Node _nd;
6.33 +
6.34 + public:
6.35 +
6.36 + typedef typename Path::Graph Graph;
6.37 + typedef typename Graph::Node Node;
6.38 +
6.39 + /// Default constructor
6.40 + PathNodeIt() {}
6.41 + /// Invalid constructor
6.42 + PathNodeIt(Invalid)
6.43 + : _graph(0), _it(INVALID), _nd(INVALID) {}
6.44 + /// Constructor
6.45 + PathNodeIt(const Graph& graph, const Path& path)
6.46 + : _graph(&graph), _it(path) {
6.47 + _nd = (_it != INVALID ? _graph->source(_it) : INVALID);
6.48 + }
6.49 + /// Constructor
6.50 + PathNodeIt(const Graph& graph, const Path& path, const Node& src)
6.51 + : _graph(&graph), _it(path), _nd(src) {}
6.52 +
6.53 + ///Conversion to Graph::Node
6.54 + operator Node() const {
6.55 + return _nd;
6.56 + }
6.57 +
6.58 + /// Next node
6.59 + PathNodeIt& operator++() {
6.60 + if (_it == INVALID) _nd = INVALID;
6.61 + else {
6.62 + _nd = _graph->target(_it);
6.63 + ++_it;
6.64 + }
6.65 + return *this;
6.66 + }
6.67 +
6.68 + /// Comparison operator
6.69 + bool operator==(const PathNodeIt& n) const {
6.70 + return _it == n._it && _nd == n._nd;
6.71 + }
6.72 + /// Comparison operator
6.73 + bool operator!=(const PathNodeIt& n) const {
6.74 + return _it != n._it || _nd != n._nd;
6.75 + }
6.76 + /// Comparison operator
6.77 + bool operator<(const PathNodeIt& n) const {
6.78 + return (_it < n._it && _nd != INVALID);
6.79 + }
6.80 +
6.81 + };
6.82 +
6.83 + /// \brief Item writer for paths
6.84 + ///
6.85 + /// This class can write paths into files. You can store paths in
6.86 + /// distinict mapset or in attributes section.
6.87 + ///
6.88 + ///\code
6.89 + /// GraphWriter<SmartGraph> gw(std::cout, g);
6.90 + /// NodeMapWriter<SmartGraph> nmw(gw, g, gw);
6.91 + ///
6.92 + /// SmartGraph::NodeMap<Path<SmartGraph> > pnm(g);
6.93 + /// for (SmartGraph::NodeIt n(g); n != INVALID; ++n) {
6.94 + /// pnm[n] = bfs.path(n);
6.95 + /// }
6.96 + /// nmw.writeNodeMap("pnm", pnm, PathWriter<Path<SmartGraph> >(gw));
6.97 + ///
6.98 + /// gw.run();
6.99 + ///\endcode
6.100 + ///
6.101 + /// \warning Do not use this class to write node or edge map values
6.102 + /// into usual nodesets or edgesets. You will not be able to read
6.103 + /// back your paths. Rather use NodeMapWriter, EdgeSetWriter or
6.104 + /// UEdgeSetWriter to dump paths from maps to lemon file.
6.105 + template <typename Path>
6.106 + class PathWriter {
6.107 + private:
6.108 +
6.109 + typedef typename Path::Edge Edge;
6.110 + std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
6.111 +
6.112 + public:
6.113 +
6.114 + typedef Path Value;
6.115 +
6.116 + PathWriter(const PathWriter& pw) {
6.117 + edgeLabelWriter.reset(pw.edgeLabelWriter->clone());
6.118 + }
6.119 +
6.120 + /// \brief Constructor
6.121 + ///
6.122 + /// The paramter shold be an edge label writer which could
6.123 + /// be a GraphWriter or an EdgeSetWriter.
6.124 + template <typename EdgeLabelWriter>
6.125 + explicit PathWriter(const EdgeLabelWriter& _edgeLabelWriter) {
6.126 + edgeLabelWriter.reset(new _writer_bits::
6.127 + LabelWriter<Edge, EdgeLabelWriter>(_edgeLabelWriter));
6.128 + }
6.129 +
6.130 + /// \brief Writer function
6.131 + ///
6.132 + /// Writes the path to the current stream. The representation
6.133 + /// is the edge labels beetween parentheses.
6.134 + void write(std::ostream& os, const Value& value) const {
6.135 + if (!edgeLabelWriter->isLabelWriter()) {
6.136 + throw DataFormatError("Cannot find edgeset or label map");
6.137 + }
6.138 + os << '(' << ' ';
6.139 + for (typename Path::EdgeIt e(value); e != INVALID; ++e) {
6.140 + edgeLabelWriter->write(os, e);
6.141 + os << ' ';
6.142 + }
6.143 + os << ')';
6.144 + }
6.145 +
6.146 + };
6.147 +
6.148 + namespace _path_bits {
6.149 +
6.150 + template <typename _Graph>
6.151 + class PathProxy {
6.152 + public:
6.153 + typedef False RevPathTag;
6.154 +
6.155 + typedef _Graph Graph;
6.156 + typedef typename Graph::Edge Edge;
6.157 +
6.158 + PathProxy(const std::vector<Edge>& edges)
6.159 + : _edges(edges) {}
6.160 +
6.161 + int length() const {
6.162 + return _edges.size();
6.163 + }
6.164 +
6.165 + bool empty() const {
6.166 + return _edges.size() == 0;
6.167 + }
6.168 +
6.169 + class EdgeIt {
6.170 + public:
6.171 + EdgeIt() {}
6.172 + EdgeIt(const PathProxy& path)
6.173 + : _path(&path), _index(0) {}
6.174 +
6.175 + operator const Edge() const {
6.176 + return _path->_edges[_index];
6.177 + }
6.178 +
6.179 + EdgeIt& operator++() {
6.180 + ++_index;
6.181 + return *this;
6.182 + }
6.183 +
6.184 + bool operator==(Invalid) const {
6.185 + return int(_path->_edges.size()) == _index;
6.186 + }
6.187 + bool operator!=(Invalid) const {
6.188 + return int(_path->_edges.size()) != _index;
6.189 + }
6.190 +
6.191 + private:
6.192 + const PathProxy* _path;
6.193 + int _index;
6.194 + };
6.195 +
6.196 + private:
6.197 + const std::vector<Edge>& _edges;
6.198 +
6.199 + };
6.200 +
6.201 + }
6.202 +
6.203 + /// \brief Item reader for paths
6.204 + ///
6.205 + /// This class can read paths from files. You can store paths in
6.206 + /// distinict mapset or in attributes section.
6.207 + ///
6.208 + ///\code
6.209 + /// GraphReader<SmartGraph> gr(std::cout, g);
6.210 + /// NodeMapReader<SmartGraph> nmr(gr, g, gr);
6.211 + ///
6.212 + /// SmartGraph::NodeMap<Path<SmartGraph> > pnm(g);
6.213 + /// nmr.readNodeMap("pnm", pnm, PathReader<Path<SmartGraph> >(gr));
6.214 + ///
6.215 + /// gr.run();
6.216 + ///\endcode
6.217 + ///
6.218 + /// \warning Do not use this class to read node or edge map values
6.219 + /// from nodesets or edgesets. The edges are not surely constructed
6.220 + /// when the edge list should be read. Rather use NodeMapReader,
6.221 + /// EdgeSetReader or UEdgeSetReader to read distinict map sets from file.
6.222 + template <typename Path>
6.223 + class PathReader {
6.224 + private:
6.225 +
6.226 + typedef typename Path::Edge Edge;
6.227 + std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
6.228 +
6.229 + public:
6.230 +
6.231 + typedef Path Value;
6.232 +
6.233 + PathReader(const PathReader& pw) {
6.234 + edgeLabelReader.reset(pw.edgeLabelReader->clone());
6.235 + }
6.236 +
6.237 + /// \brief Constructor
6.238 + ///
6.239 + /// The paramter shold be an edge label reader which could
6.240 + /// be a GraphReader or an EdgeSetReader.
6.241 + template <typename EdgeLabelReader>
6.242 + explicit PathReader(const EdgeLabelReader& _edgeLabelReader) {
6.243 + edgeLabelReader.reset(new _reader_bits::
6.244 + LabelReader<Edge, EdgeLabelReader>(_edgeLabelReader));
6.245 + }
6.246 +
6.247 +
6.248 + /// \brief Reader function
6.249 + ///
6.250 + /// Reads the path from the current stream. The representation
6.251 + /// is the edge labels beetween parentheses.
6.252 + void read(std::istream& is, Value& value) const {
6.253 + if (!edgeLabelReader->isLabelReader()) {
6.254 + throw DataFormatError("Cannot find edgeset or label map");
6.255 + }
6.256 + char c;
6.257 + if (!(is >> c) || c != '(')
6.258 + throw DataFormatError("PathReader format error");
6.259 + std::vector<typename Path::Edge> v;
6.260 + while (is >> c && c != ')') {
6.261 + is.putback(c);
6.262 + Edge edge = edgeLabelReader->read(is);
6.263 + v.push_back(edge);
6.264 + }
6.265 + if (!is) throw DataFormatError("PathReader format error");
6.266 + copyPath(value, _path_bits::PathProxy<typename Path::Edge>(v));
6.267 + }
6.268 +
6.269 + };
6.270 +
6.271 }
6.272
6.273 #endif