1.1 --- a/doc/graph_io.dox Sat Oct 20 14:29:12 2007 +0000
1.2 +++ b/doc/graph_io.dox Wed Oct 24 16:31:49 2007 +0000
1.3 @@ -335,7 +335,7 @@
1.4
1.5 The specialization of writing is very similar to that of reading.
1.6
1.7 -\section u Undirected graphs
1.8 +\section undir Undirected and Bipartite graphs
1.9
1.10 In a file describing an undirected graph (ugraph, for short) you find an
1.11 \c uedgeset section instead of the \c edgeset section. The first line of
1.12 @@ -343,9 +343,9 @@
1.13 next lines describe one undirected edge with the the incident nodes and the
1.14 values of the map.
1.15
1.16 -The format handles directed edge maps as a syntactical sugar???, if there
1.17 -are two maps with names being the same with a \c '+' and a \c '-' prefix
1.18 -then this will be read as a directed map.
1.19 +The format could store directed edge maps, if there are two maps with
1.20 +names being the same with a \c '+' and a \c '-' prefix then this could
1.21 +be read as such a map.
1.22
1.23 \code
1.24 @uedgeset
1.25 @@ -386,6 +386,35 @@
1.26 reader.readEdge("edge", edge);
1.27 \endcode
1.28
1.29 +The undirected bipartite graphs could be read with the \c BpUGraph
1.30 +class and it has specialized nodeset section, which should be start
1.31 +with \c "@bpnodeset". This section is separated to two
1.32 +subsections. The header line of these sections start with "&anodeset"
1.33 +or "&bnodeset" and after that the line contains the names of the
1.34 +regular and A-node or B-node maps accordingly. The lines of each
1.35 +section contains the mapped values. The labels of the graph should be
1.36 +unique overall both subsections.
1.37 +
1.38 +\code
1.39 +@bpnodeset
1.40 +&anodeset label coords radius
1.41 + 0 (0, 0) 14.0
1.42 + 1 (0, 1) 12.0
1.43 +&bnodeset label coords
1.44 + 2 (1, 0)
1.45 + 3 (1, 1)
1.46 +\endcode
1.47 +
1.48 +The reading can be done with \ref lemon::BpUGraphReader::readANodeMap()
1.49 +"readANodeMap()", \ref lemon::BpUGraphReader::readBNodeMap()
1.50 +"readBNodeMap()" or \ref lemon::BpUGraphReader::readNodeMap()
1.51 +"readNodeMap()" members.
1.52 +
1.53 +\code
1.54 +reader.readNodeMap("coords", coords);
1.55 +reader.readAnodeMap("radius", radius);
1.56 +\endcode
1.57 +
1.58 \section advanced Advanced features
1.59
1.60 The graph reader and writer classes give an easy way to read and write
2.1 --- a/lemon/graph_reader.h Sat Oct 20 14:29:12 2007 +0000
2.2 +++ b/lemon/graph_reader.h Wed Oct 24 16:31:49 2007 +0000
2.3 @@ -725,6 +725,469 @@
2.4 AttributeReader<ReaderTraits> attribute_reader;
2.5 };
2.6
2.7 + /// \brief The bipartite graph reader class.
2.8 + ///
2.9 + /// The \c BpUGraphReader class provides the graph input.
2.10 + /// Before you read this documentation it might be useful to read the general
2.11 + /// description of \ref graph-io-page "Graph Input-Output".
2.12 + ///
2.13 + /// The given file format may contain several maps and labeled nodes or
2.14 + /// edges.
2.15 + ///
2.16 + /// If you read a graph you need not read all the maps and items just those
2.17 + /// that you need. The interface of the \c BpUGraphReader is very similar
2.18 + /// to the BpUGraphWriter but the reading method does not depend on the
2.19 + /// order of the given commands.
2.20 + ///
2.21 + /// The reader object suppose that each not read value does not contain
2.22 + /// whitespaces, therefore it has some extra possibilities to control how
2.23 + /// it should skip the values when the string representation contains spaces.
2.24 + ///
2.25 + ///\code
2.26 + /// BpUGraphReader<ListBpUGraph> reader(std::cin, graph);
2.27 + ///\endcode
2.28 + ///
2.29 + /// The \c readANodeMap() function reads a map from the A-part of
2.30 + /// the\c \@bpnodeset section, while the \c readBNodeMap() reads
2.31 + /// from the B-part of the section. If you use the \c readNodeMap()
2.32 + /// function, then the given map should appear in both part of the
2.33 + /// section. If there is a map that you do not want to read from the
2.34 + /// file and there is whitespace in the string represenation of the
2.35 + /// values then you should call the \c skipANodeMap(), \c
2.36 + /// skipBNodeMap() or \c skipNodeMap() template member function with
2.37 + /// proper parameters.
2.38 + ///
2.39 + ///\code
2.40 + /// reader.readNodeMap("coords", coords);
2.41 + /// reader.readANodeMap("range", range);
2.42 + /// reader.readANodeMap("benefit", benefit);
2.43 + ///
2.44 + /// reader.skipNodeMap("description", desc);
2.45 + ///
2.46 + /// reader.readNodeMap("color", colorMap);
2.47 + ///\endcode
2.48 + ///
2.49 + /// With the \c readUEdgeMap() member function you can give an
2.50 + /// uedge map reading command similar to the NodeMaps.
2.51 + ///
2.52 + ///\code
2.53 + /// reader.readUEdgeMap("capacity", capacityMap);
2.54 + /// reader.readEdgeMap("flow", flowMap);
2.55 + ///\endcode
2.56 + ///
2.57 + /// With \c readNode() and \c readUEdge() functions you can read
2.58 + /// labeled Nodes and UEdges.
2.59 + ///
2.60 + ///\code
2.61 + /// reader.readNode("source", sourceNode);
2.62 + /// reader.readNode("target", targetNode);
2.63 + ///
2.64 + /// reader.readUEdge("observed", uEdge);
2.65 + ///\endcode
2.66 + ///
2.67 + /// With the \c readAttribute() functions you can read an attribute
2.68 + /// in a variable. You can specify the reader for the attribute as
2.69 + /// the nodemaps.
2.70 + ///
2.71 + /// After you give all read commands you must call the \c run() member
2.72 + /// function, which execute all the commands.
2.73 + ///
2.74 + ///\code
2.75 + /// reader.run();
2.76 + ///\endcode
2.77 + ///
2.78 + /// \see GraphReader
2.79 + /// \see DefaultReaderTraits
2.80 + /// \see \ref UGraphWriter
2.81 + /// \see \ref graph-io-page
2.82 + ///
2.83 + /// \author Balazs Dezso
2.84 + template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
2.85 + class BpUGraphReader {
2.86 + public:
2.87 +
2.88 + typedef _Graph Graph;
2.89 + typedef typename Graph::Node Node;
2.90 + typedef typename Graph::Edge Edge;
2.91 + typedef typename Graph::UEdge UEdge;
2.92 +
2.93 + typedef _ReaderTraits ReaderTraits;
2.94 + typedef typename ReaderTraits::Skipper DefaultSkipper;
2.95 +
2.96 + /// \brief Construct a new BpUGraphReader.
2.97 + ///
2.98 + /// Construct a new BpUGraphReader. It reads into the given graph
2.99 + /// and it use the given reader as the default skipper.
2.100 + BpUGraphReader(std::istream& _is, Graph& _graph,
2.101 + const DefaultSkipper& _skipper = DefaultSkipper())
2.102 + : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
2.103 + nodeset_reader(*reader, _graph, std::string(), skipper),
2.104 + uedgeset_reader(*reader, _graph, nodeset_reader,
2.105 + std::string(), skipper),
2.106 + node_reader(*reader, nodeset_reader, std::string()),
2.107 + uedge_reader(*reader, uedgeset_reader, std::string()),
2.108 + attribute_reader(*reader, std::string()) {}
2.109 +
2.110 + /// \brief Construct a new BpUGraphReader.
2.111 + ///
2.112 + /// Construct a new BpUGraphReader. It reads into the given graph
2.113 + /// and it use the given reader as the default skipper.
2.114 + BpUGraphReader(const std::string& _filename, Graph& _graph,
2.115 + const DefaultSkipper& _skipper = DefaultSkipper())
2.116 + : reader(new LemonReader(_filename)), own_reader(true),
2.117 + skipper(_skipper),
2.118 + nodeset_reader(*reader, _graph, std::string(), skipper),
2.119 + uedgeset_reader(*reader, _graph, nodeset_reader,
2.120 + std::string(), skipper),
2.121 + node_reader(*reader, nodeset_reader, std::string()),
2.122 + uedge_reader(*reader, uedgeset_reader, std::string()),
2.123 + attribute_reader(*reader, std::string()) {}
2.124 +
2.125 + /// \brief Construct a new BpUGraphReader.
2.126 + ///
2.127 + /// Construct a new BpUGraphReader. It reads into the given graph
2.128 + /// and it use the given reader as the default skipper.
2.129 + BpUGraphReader(LemonReader& _reader, Graph& _graph,
2.130 + const DefaultSkipper& _skipper = DefaultSkipper())
2.131 + : reader(_reader), own_reader(false), skipper(_skipper),
2.132 + nodeset_reader(*reader, _graph, std::string(), skipper),
2.133 + uedgeset_reader(*reader, _graph, nodeset_reader,
2.134 + std::string(), skipper),
2.135 + node_reader(*reader, nodeset_reader, std::string()),
2.136 + uedge_reader(*reader, uedgeset_reader, std::string()),
2.137 + attribute_reader(*reader, std::string()) {}
2.138 +
2.139 + /// \brief Destruct the graph reader.
2.140 + ///
2.141 + /// Destruct the graph reader.
2.142 + ~BpUGraphReader() {
2.143 + if (own_reader)
2.144 + delete reader;
2.145 + }
2.146 +
2.147 + /// \brief Give a new node map reading command to the reader.
2.148 + ///
2.149 + /// Give a new node map reading command to the reader.
2.150 + template <typename Map>
2.151 + BpUGraphReader& readNodeMap(std::string name, Map& map) {
2.152 + nodeset_reader.readNodeMap(name, map);
2.153 + return *this;
2.154 + }
2.155 +
2.156 + template <typename Map>
2.157 + BpUGraphReader& readNodeMap(std::string name, const Map& map) {
2.158 + nodeset_reader.readNodeMap(name, map);
2.159 + return *this;
2.160 + }
2.161 +
2.162 + /// \brief Give a new node map reading command to the reader.
2.163 + ///
2.164 + /// Give a new node map reading command to the reader.
2.165 + template <typename ItemReader, typename Map>
2.166 + BpUGraphReader& readNodeMap(std::string name, Map& map,
2.167 + const ItemReader& ir = ItemReader()) {
2.168 + nodeset_reader.readNodeMap(name, map, ir);
2.169 + return *this;
2.170 + }
2.171 +
2.172 + template <typename ItemReader, typename Map>
2.173 + BpUGraphReader& readNodeMap(std::string name, const Map& map,
2.174 + const ItemReader& ir = ItemReader()) {
2.175 + nodeset_reader.readNodeMap(name, map, ir);
2.176 + return *this;
2.177 + }
2.178 +
2.179 + /// \brief Give a new node map skipping command to the reader.
2.180 + ///
2.181 + /// Give a new node map skipping command to the reader.
2.182 + template <typename ItemReader>
2.183 + BpUGraphReader& skipNodeMap(std::string name,
2.184 + const ItemReader& ir = ItemReader()) {
2.185 + nodeset_reader.skipNodeMap(name, ir);
2.186 + return *this;
2.187 + }
2.188 +
2.189 + /// \brief Give a new A-node map reading command to the reader.
2.190 + ///
2.191 + /// Give a new A-node map reading command to the reader.
2.192 + template <typename Map>
2.193 + BpUGraphReader& readANodeMap(std::string name, Map& map) {
2.194 + nodeset_reader.readANodeMap(name, map);
2.195 + return *this;
2.196 + }
2.197 +
2.198 + template <typename Map>
2.199 + BpUGraphReader& readANodeMap(std::string name, const Map& map) {
2.200 + nodeset_reader.readANodeMap(name, map);
2.201 + return *this;
2.202 + }
2.203 +
2.204 + /// \brief Give a new A-node map reading command to the reader.
2.205 + ///
2.206 + /// Give a new A-node map reading command to the reader.
2.207 + template <typename ItemReader, typename Map>
2.208 + BpUGraphReader& readANodeMap(std::string name, Map& map,
2.209 + const ItemReader& ir = ItemReader()) {
2.210 + nodeset_reader.readANodeMap(name, map, ir);
2.211 + return *this;
2.212 + }
2.213 +
2.214 + template <typename ItemReader, typename Map>
2.215 + BpUGraphReader& readANodeMap(std::string name, const Map& map,
2.216 + const ItemReader& ir = ItemReader()) {
2.217 + nodeset_reader.readNodeMap(name, map, ir);
2.218 + return *this;
2.219 + }
2.220 +
2.221 + /// \brief Give a new A-node map skipping command to the reader.
2.222 + ///
2.223 + /// Give a new A-node map skipping command to the reader.
2.224 + template <typename ItemReader>
2.225 + BpUGraphReader& skipANodeMap(std::string name,
2.226 + const ItemReader& ir = ItemReader()) {
2.227 + nodeset_reader.skipANodeMap(name, ir);
2.228 + return *this;
2.229 + }
2.230 +
2.231 + /// \brief Give a new B-node map reading command to the reader.
2.232 + ///
2.233 + /// Give a new B-node map reading command to the reader.
2.234 + template <typename Map>
2.235 + BpUGraphReader& readBNodeMap(std::string name, Map& map) {
2.236 + nodeset_reader.readBNodeMap(name, map);
2.237 + return *this;
2.238 + }
2.239 +
2.240 + template <typename Map>
2.241 + BpUGraphReader& readBNodeMap(std::string name, const Map& map) {
2.242 + nodeset_reader.readBNodeMap(name, map);
2.243 + return *this;
2.244 + }
2.245 +
2.246 + /// \brief Give a new B-node map reading command to the reader.
2.247 + ///
2.248 + /// Give a new B-node map reading command to the reader.
2.249 + template <typename ItemReader, typename Map>
2.250 + BpUGraphReader& readBNodeMap(std::string name, Map& map,
2.251 + const ItemReader& ir = ItemReader()) {
2.252 + nodeset_reader.readBNodeMap(name, map, ir);
2.253 + return *this;
2.254 + }
2.255 +
2.256 + template <typename ItemReader, typename Map>
2.257 + BpUGraphReader& readBNodeMap(std::string name, const Map& map,
2.258 + const ItemReader& ir = ItemReader()) {
2.259 + nodeset_reader.readNodeMap(name, map, ir);
2.260 + return *this;
2.261 + }
2.262 +
2.263 + /// \brief Give a new B-node map skipping command to the reader.
2.264 + ///
2.265 + /// Give a new B-node map skipping command to the reader.
2.266 + template <typename ItemReader>
2.267 + BpUGraphReader& skipBNodeMap(std::string name,
2.268 + const ItemReader& ir = ItemReader()) {
2.269 + nodeset_reader.skipBNodeMap(name, ir);
2.270 + return *this;
2.271 + }
2.272 +
2.273 + /// \brief Give a new undirected edge map reading command to the reader.
2.274 + ///
2.275 + /// Give a new undirected edge map reading command to the reader.
2.276 + template <typename Map>
2.277 + BpUGraphReader& readUEdgeMap(std::string name, Map& map) {
2.278 + uedgeset_reader.readUEdgeMap(name, map);
2.279 + return *this;
2.280 + }
2.281 +
2.282 + template <typename Map>
2.283 + BpUGraphReader& readUEdgeMap(std::string name, const Map& map) {
2.284 + uedgeset_reader.readUEdgeMap(name, map);
2.285 + return *this;
2.286 + }
2.287 +
2.288 +
2.289 + /// \brief Give a new undirected edge map reading command to the reader.
2.290 + ///
2.291 + /// Give a new undirected edge map reading command to the reader.
2.292 + template <typename ItemReader, typename Map>
2.293 + BpUGraphReader& readUEdgeMap(std::string name, Map& map,
2.294 + const ItemReader& ir = ItemReader()) {
2.295 + uedgeset_reader.readUEdgeMap(name, map, ir);
2.296 + return *this;
2.297 + }
2.298 +
2.299 + template <typename ItemReader, typename Map>
2.300 + BpUGraphReader& readUEdgeMap(std::string name, const Map& map,
2.301 + const ItemReader& ir = ItemReader()) {
2.302 + uedgeset_reader.readUEdgeMap(name, map, ir);
2.303 + return *this;
2.304 + }
2.305 +
2.306 + /// \brief Give a new undirected edge map skipping command to the reader.
2.307 + ///
2.308 + /// Give a new undirected edge map skipping command to the reader.
2.309 + template <typename ItemReader>
2.310 + BpUGraphReader& skipUEdgeMap(std::string name,
2.311 + const ItemReader& ir = ItemReader()) {
2.312 + uedgeset_reader.skipUMap(name, ir);
2.313 + return *this;
2.314 + }
2.315 +
2.316 +
2.317 + /// \brief Give a new edge map reading command to the reader.
2.318 + ///
2.319 + /// Give a new edge map reading command to the reader.
2.320 + template <typename Map>
2.321 + BpUGraphReader& readEdgeMap(std::string name, Map& map) {
2.322 + uedgeset_reader.readEdgeMap(name, map);
2.323 + return *this;
2.324 + }
2.325 +
2.326 + template <typename Map>
2.327 + BpUGraphReader& readEdgeMap(std::string name, const Map& map) {
2.328 + uedgeset_reader.readEdgeMap(name, map);
2.329 + return *this;
2.330 + }
2.331 +
2.332 +
2.333 + /// \brief Give a new edge map reading command to the reader.
2.334 + ///
2.335 + /// Give a new edge map reading command to the reader.
2.336 + template <typename ItemReader, typename Map>
2.337 + BpUGraphReader& readEdgeMap(std::string name, Map& map,
2.338 + const ItemReader& ir = ItemReader()) {
2.339 + uedgeset_reader.readEdgeMap(name, map, ir);
2.340 + return *this;
2.341 + }
2.342 +
2.343 + template <typename ItemReader, typename Map>
2.344 + BpUGraphReader& readEdgeMap(std::string name, const Map& map,
2.345 + const ItemReader& ir = ItemReader()) {
2.346 + uedgeset_reader.readEdgeMap(name, map, ir);
2.347 + return *this;
2.348 + }
2.349 +
2.350 + /// \brief Give a new edge map skipping command to the reader.
2.351 + ///
2.352 + /// Give a new edge map skipping command to the reader.
2.353 + template <typename ItemReader>
2.354 + BpUGraphReader& skipEdgeMap(std::string name,
2.355 + const ItemReader& ir = ItemReader()) {
2.356 + uedgeset_reader.skipEdgeMap(name, ir);
2.357 + return *this;
2.358 + }
2.359 +
2.360 + /// \brief Give a new labeled node reading command to the reader.
2.361 + ///
2.362 + /// Give a new labeled node reading command to the reader.
2.363 + BpUGraphReader& readNode(std::string name, Node& node) {
2.364 + node_reader.readNode(name, node);
2.365 + return *this;
2.366 + }
2.367 +
2.368 + /// \brief Give a new labeled edge reading command to the reader.
2.369 + ///
2.370 + /// Give a new labeled edge reading command to the reader.
2.371 + BpUGraphReader& readEdge(std::string name, Edge& edge) {
2.372 + uedge_reader.readEdge(name, edge);
2.373 + }
2.374 +
2.375 + /// \brief Give a new labeled undirected edge reading command to the
2.376 + /// reader.
2.377 + ///
2.378 + /// Give a new labeled undirected edge reading command to the reader.
2.379 + BpUGraphReader& readUEdge(std::string name, UEdge& edge) {
2.380 + uedge_reader.readUEdge(name, edge);
2.381 + }
2.382 +
2.383 + /// \brief Give a new attribute reading command.
2.384 + ///
2.385 + /// Give a new attribute reading command.
2.386 + template <typename Value>
2.387 + BpUGraphReader& readAttribute(std::string name, Value& value) {
2.388 + attribute_reader.readAttribute(name, value);
2.389 + return *this;
2.390 + }
2.391 +
2.392 + /// \brief Give a new attribute reading command.
2.393 + ///
2.394 + /// Give a new attribute reading command.
2.395 + template <typename ItemReader, typename Value>
2.396 + BpUGraphReader& readAttribute(std::string name, Value& value,
2.397 + const ItemReader& ir = ItemReader()) {
2.398 + attribute_reader.readAttribute(name, value, ir);
2.399 + return *this;
2.400 + }
2.401 +
2.402 + /// \brief Conversion operator to LemonReader.
2.403 + ///
2.404 + /// Conversion operator to LemonReader. It make possible
2.405 + /// to access the encapsulated \e LemonReader, this way
2.406 + /// you can attach to this reader new instances of
2.407 + /// \e LemonReader::SectionReader.
2.408 + operator LemonReader&() {
2.409 + return *reader;
2.410 + }
2.411 +
2.412 + /// \brief Executes the reading commands.
2.413 + ///
2.414 + /// Executes the reading commands.
2.415 + void run() {
2.416 + reader->run();
2.417 + }
2.418 +
2.419 +
2.420 + /// \brief Returns true if the reader can give back the items by its label.
2.421 + ///
2.422 + /// Returns true if the reader can give back the items by its label.
2.423 + bool isLabelReader() const {
2.424 + return nodeset_reader.isLabelReader() &&
2.425 + uedgeset_reader.isLabelReader();
2.426 + }
2.427 +
2.428 + /// \brief Gives back the node by its label.
2.429 + ///
2.430 + /// It reads an label from the stream and gives back which node belongs to
2.431 + /// it. It is possible only if there was read a "label" named node map.
2.432 + void readLabel(std::istream& is, Node& node) const {
2.433 + return nodeset_reader.readLabel(is, node);
2.434 + }
2.435 +
2.436 + /// \brief Gives back the edge by its label
2.437 + ///
2.438 + /// It reads an label from the stream and gives back which edge belongs to
2.439 + /// it. It is possible only if there was read a "label" named edge map.
2.440 + void readLabel(std::istream& is, Edge& edge) const {
2.441 + return uedgeset_reader.readLabel(is, edge);
2.442 + }
2.443 +
2.444 + /// \brief Gives back the undirected edge by its label.
2.445 + ///
2.446 + /// It reads an label from the stream and gives back which undirected edge
2.447 + /// belongs to it. It is possible only if there was read a "label" named
2.448 + /// edge map.
2.449 + void readLabel(std::istream& is, UEdge& uedge) const {
2.450 + return uedgeset_reader.readLabel(is, uedge);
2.451 + }
2.452 +
2.453 +
2.454 + private:
2.455 +
2.456 + LemonReader* reader;
2.457 + bool own_reader;
2.458 +
2.459 + DefaultSkipper skipper;
2.460 +
2.461 + BpNodeSetReader<Graph, ReaderTraits> nodeset_reader;
2.462 + UEdgeSetReader<Graph, ReaderTraits> uedgeset_reader;
2.463 +
2.464 + NodeReader<Graph> node_reader;
2.465 + UEdgeReader<Graph> uedge_reader;
2.466 +
2.467 + AttributeReader<ReaderTraits> attribute_reader;
2.468 + };
2.469 +
2.470
2.471 /// @}
2.472 }
3.1 --- a/lemon/graph_writer.h Sat Oct 20 14:29:12 2007 +0000
3.2 +++ b/lemon/graph_writer.h Wed Oct 24 16:31:49 2007 +0000
3.3 @@ -156,7 +156,7 @@
3.4
3.5 /// \brief Issue a new node map writing command for the writer.
3.6 ///
3.7 - /// This function issues a new <i> node map writing command</i> to the writer.
3.8 + /// This function issues a new <i> node map writing command</i> to the writer.
3.9 template <typename Map>
3.10 GraphWriter& writeNodeMap(std::string label, const Map& map) {
3.11 nodeset_writer.writeNodeMap(label, map);
3.12 @@ -166,7 +166,7 @@
3.13
3.14 /// \brief Issue a new node map writing command for the writer.
3.15 ///
3.16 - /// This function issues a new <i> node map writing command</i> to the writer.
3.17 + /// This function issues a new <i> node map writing command</i> to the writer.
3.18 template <typename ItemWriter, typename Map>
3.19 GraphWriter& writeNodeMap(std::string label, const Map& map,
3.20 const ItemWriter& iw = ItemWriter()) {
3.21 @@ -639,6 +639,376 @@
3.22 AttributeWriter<WriterTraits> attribute_writer;
3.23 };
3.24
3.25 + /// \brief The bipartite graph writer class.
3.26 + ///
3.27 + /// The \c BpUGraphWriter class provides the ugraph output. To write
3.28 + /// a graph you should first give writing commands to the writer. You can
3.29 + /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap
3.30 + /// writing and labeled Node, Edge or UEdge writing.
3.31 + ///
3.32 + ///\code
3.33 + /// BpUGraphWriter<ListUGraph> writer(std::cout, graph);
3.34 + ///\endcode
3.35 + ///
3.36 + /// The \c writeNodeMap() function declares a \c NodeMap writing
3.37 + /// command in the \c BpUGraphWriter. You should give as parameter
3.38 + /// the name of the map and the map object. The NodeMap writing
3.39 + /// command with name "label" should write a unique map because it
3.40 + /// is regarded as label map.
3.41 + ///
3.42 + ///\code
3.43 + /// IdMap<ListUGraph, Node> nodeLabelMap;
3.44 + /// writer.writeNodeMap("label", nodeLabelMap);
3.45 + ///
3.46 + /// writer.writeNodeMap("coords", coords);
3.47 + /// writer.writeNodeMap("color", colorMap);
3.48 + ///\endcode
3.49 + ///
3.50 + /// With the \c writeUEdgeMap() member function you can give an
3.51 + /// undirected edge map writing command similar to the NodeMaps.
3.52 + ///
3.53 + ///\code
3.54 + /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
3.55 + /// edgeDescMap(graph);
3.56 + /// writer.writeUEdgeMap("descriptor", edgeDescMap);
3.57 + ///
3.58 + /// writer.writeUEdgeMap("weight", weightMap);
3.59 + /// writer.writeUEdgeMap("label", labelMap);
3.60 + ///\endcode
3.61 + ///
3.62 + /// The EdgeMap handling is just a syntactical sugar. It writes
3.63 + /// two undirected edge map with '+' and '-' prefix in the name.
3.64 + ///
3.65 + ///\code
3.66 + /// writer.writeEdgeMap("capacity", capacityMap);
3.67 + ///\endcode
3.68 + ///
3.69 + ///
3.70 + /// With \c writeNode() and \c writeUEdge() functions you can
3.71 + /// designate nodes and undirected edges in the graph. For example, you can
3.72 + /// write out the source and target of the graph.
3.73 + ///
3.74 + ///\code
3.75 + /// writer.writeNode("source", sourceNode);
3.76 + /// writer.writeNode("target", targetNode);
3.77 + ///
3.78 + /// writer.writeUEdge("observed", uEdge);
3.79 + ///\endcode
3.80 + ///
3.81 + /// After you give all write commands you must call the \c run() member
3.82 + /// function, which executes all the writing commands.
3.83 + ///
3.84 + ///\code
3.85 + /// writer.run();
3.86 + ///\endcode
3.87 + ///
3.88 + /// \see DefaultWriterTraits
3.89 + /// \see QuotedStringWriter
3.90 + /// \see IdMap
3.91 + /// \see DescriptorMap
3.92 + /// \see \ref GraphWriter
3.93 + /// \see \ref graph-io-page
3.94 + /// \author Balazs Dezso
3.95 + template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
3.96 + class BpUGraphWriter {
3.97 + public:
3.98 +
3.99 + typedef _Graph Graph;
3.100 + typedef typename Graph::Node Node;
3.101 + typedef typename Graph::Edge Edge;
3.102 + typedef typename Graph::UEdge UEdge;
3.103 +
3.104 + typedef _WriterTraits WriterTraits;
3.105 +
3.106 + /// \brief Construct a new BpUGraphWriter.
3.107 + ///
3.108 + /// Construct a new BpUGraphWriter. It writes the given graph
3.109 + /// to the given stream.
3.110 + BpUGraphWriter(std::ostream& _os, const Graph& _graph)
3.111 + : writer(new LemonWriter(_os)), own_writer(true),
3.112 + nodeset_writer(*writer, _graph, std::string()),
3.113 + uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.114 + node_writer(*writer, nodeset_writer, std::string()),
3.115 + uedge_writer(*writer, uedgeset_writer, std::string()),
3.116 + attribute_writer(*writer, std::string()) {}
3.117 +
3.118 + /// \brief Construct a new BpUGraphWriter.
3.119 + ///
3.120 + /// Construct a new BpUGraphWriter. It writes the given graph
3.121 + /// to the given file.
3.122 + BpUGraphWriter(const std::string& _filename, const Graph& _graph)
3.123 + : writer(new LemonWriter(_filename)), own_writer(true),
3.124 + nodeset_writer(*writer, _graph, std::string()),
3.125 + uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.126 + node_writer(*writer, nodeset_writer, std::string()),
3.127 + uedge_writer(*writer, uedgeset_writer, std::string()),
3.128 + attribute_writer(*writer, std::string()) {}
3.129 +
3.130 + /// \brief Construct a new BpUGraphWriter.
3.131 + ///
3.132 + /// Construct a new BpUGraphWriter. It writes the given graph
3.133 + /// to given LemonWriter.
3.134 + BpUGraphWriter(LemonWriter& _writer, const Graph& _graph)
3.135 + : writer(_writer), own_writer(false),
3.136 + nodeset_writer(*writer, _graph, std::string()),
3.137 + uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
3.138 + node_writer(*writer, nodeset_writer, std::string()),
3.139 + uedge_writer(*writer, uedgeset_writer, std::string()),
3.140 + attribute_writer(*writer, std::string()) {}
3.141 +
3.142 + /// \brief Destruct the graph writer.
3.143 + ///
3.144 + /// Destruct the graph writer.
3.145 + ~BpUGraphWriter() {
3.146 + if (own_writer)
3.147 + delete writer;
3.148 + }
3.149 +
3.150 + /// \brief Issue a new node map writing command to the writer.
3.151 + ///
3.152 + /// This function issues a new <i> node map writing command</i> to
3.153 + /// the writer.
3.154 + template <typename Map>
3.155 + BpUGraphWriter& writeNodeMap(std::string label, const Map& map) {
3.156 + nodeset_writer.writeNodeMap(label, map);
3.157 + return *this;
3.158 + }
3.159 +
3.160 + /// \brief Issue a new node map writing command to the writer.
3.161 + ///
3.162 + /// This function issues a new <i> node map writing command</i> to
3.163 + /// the writer.
3.164 + template <typename ItemWriter, typename Map>
3.165 + BpUGraphWriter& writeNodeMap(std::string label, const Map& map,
3.166 + const ItemWriter& iw = ItemWriter()) {
3.167 + nodeset_writer.writeNodeMap(label, map, iw);
3.168 + return *this;
3.169 + }
3.170 +
3.171 + /// \brief Issue a new A-node map writing command to the writer.
3.172 + ///
3.173 + /// This function issues a new <i> A-node map writing command</i> to
3.174 + /// the writer.
3.175 + template <typename Map>
3.176 + BpUGraphWriter& writeANodeMap(std::string label, const Map& map) {
3.177 + nodeset_writer.writeANodeMap(label, map);
3.178 + return *this;
3.179 + }
3.180 +
3.181 + /// \brief Issue a new A-node map writing command to the writer.
3.182 + ///
3.183 + /// This function issues a new <i> A-node map writing command</i> to
3.184 + /// the writer.
3.185 + template <typename ItemWriter, typename Map>
3.186 + BpUGraphWriter& writeANodeMap(std::string label, const Map& map,
3.187 + const ItemWriter& iw = ItemWriter()) {
3.188 + nodeset_writer.writeANodeMap(label, map, iw);
3.189 + return *this;
3.190 + }
3.191 + /// \brief Issue a new B-node map writing command to the writer.
3.192 + ///
3.193 + /// This function issues a new <i> B-node map writing command</i> to
3.194 + /// the writer.
3.195 + template <typename Map>
3.196 + BpUGraphWriter& writeBNodeMap(std::string label, const Map& map) {
3.197 + nodeset_writer.writeBNodeMap(label, map);
3.198 + return *this;
3.199 + }
3.200 +
3.201 + /// \brief Issue a new B-node map writing command to the writer.
3.202 + ///
3.203 + /// This function issues a new <i> B-node map writing command</i> to
3.204 + /// the writer.
3.205 + template <typename ItemWriter, typename Map>
3.206 + BpUGraphWriter& writeBNodeMap(std::string label, const Map& map,
3.207 + const ItemWriter& iw = ItemWriter()) {
3.208 + nodeset_writer.writeBNodeMap(label, map, iw);
3.209 + return *this;
3.210 + }
3.211 +
3.212 + /// \brief Issue a new edge map writing command to the writer.
3.213 + ///
3.214 + /// This function issues a new <i> edge map writing command</i> to
3.215 + /// the writer.
3.216 + template <typename Map>
3.217 + BpUGraphWriter& writeEdgeMap(std::string label, const Map& map) {
3.218 + uedgeset_writer.writeEdgeMap(label, map);
3.219 + return *this;
3.220 + }
3.221 +
3.222 + /// \brief Issue a new edge map writing command to the writer.
3.223 + ///
3.224 + /// This function issues a new <i> edge map writing command</i> to
3.225 + /// the writer.
3.226 + template <typename ItemWriter, typename Map>
3.227 + BpUGraphWriter& writeEdgeMap(std::string label, const Map& map,
3.228 + const ItemWriter& iw = ItemWriter()) {
3.229 + uedgeset_writer.writeEdgeMap(label, map, iw);
3.230 + return *this;
3.231 + }
3.232 +
3.233 + /// \brief Issue a new undirected edge map writing command to the writer.
3.234 + ///
3.235 + /// This function issues a new <i> undirected edge map writing
3.236 + /// command</i> to the writer.
3.237 + template <typename Map>
3.238 + BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map) {
3.239 + uedgeset_writer.writeUEdgeMap(label, map);
3.240 + return *this;
3.241 + }
3.242 +
3.243 + /// \brief Issue a new undirected edge map writing command to the writer.
3.244 + ///
3.245 + /// This function issues a new <i> undirected edge map writing
3.246 + /// command</i> to the writer.
3.247 + template <typename ItemWriter, typename Map>
3.248 + BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map,
3.249 + const ItemWriter& iw = ItemWriter()) {
3.250 + uedgeset_writer.writeUEdgeMap(label, map, iw);
3.251 + return *this;
3.252 + }
3.253 +
3.254 + /// \brief Issue a new labeled node writer to the writer.
3.255 + ///
3.256 + /// This function issues a new <i> labeled node writing
3.257 + /// command</i> to the writer.
3.258 + BpUGraphWriter& writeNode(std::string label, const Node& node) {
3.259 + node_writer.writeNode(label, node);
3.260 + return *this;
3.261 + }
3.262 +
3.263 + /// \brief Issue a new labeled edge writer to the writer.
3.264 + ///
3.265 + /// This function issues a new <i> labeled edge writing
3.266 + /// command</i> to the writer.
3.267 + BpUGraphWriter& writeEdge(std::string label, const Edge& edge) {
3.268 + uedge_writer.writeEdge(label, edge);
3.269 + }
3.270 +
3.271 + /// \brief Issue a new labeled undirected edge writing command to
3.272 + /// the writer.
3.273 + ///
3.274 + /// Issue a new <i>labeled undirected edge writing command</i> to
3.275 + /// the writer.
3.276 + BpUGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
3.277 + uedge_writer.writeUEdge(label, edge);
3.278 + }
3.279 +
3.280 + /// \brief Issue a new attribute writing command.
3.281 + ///
3.282 + /// This function issues a new <i> attribute writing
3.283 + /// command</i> to the writer.
3.284 + template <typename Value>
3.285 + BpUGraphWriter& writeAttribute(std::string label, const Value& value) {
3.286 + attribute_writer.writeAttribute(label, value);
3.287 + return *this;
3.288 + }
3.289 +
3.290 + /// \brief Issue a new attribute writing command.
3.291 + ///
3.292 + /// This function issues a new <i> attribute writing
3.293 + /// command</i> to the writer.
3.294 + template <typename ItemWriter, typename Value>
3.295 + BpUGraphWriter& writeAttribute(std::string label, const Value& value,
3.296 + const ItemWriter& iw = ItemWriter()) {
3.297 + attribute_writer.writeAttribute(label, value, iw);
3.298 + return *this;
3.299 + }
3.300 +
3.301 + /// \brief Conversion operator to LemonWriter.
3.302 + ///
3.303 + /// Conversion operator to LemonWriter. It makes possible
3.304 + /// to access the encapsulated \e LemonWriter, this way
3.305 + /// you can attach to this writer new instances of
3.306 + /// \e LemonWriter::SectionWriter.
3.307 + operator LemonWriter&() {
3.308 + return *writer;
3.309 + }
3.310 +
3.311 + /// \brief Executes the writing commands.
3.312 + ///
3.313 + /// Executes the writing commands.
3.314 + void run() {
3.315 + writer->run();
3.316 + }
3.317 +
3.318 + /// \brief Returns true if the writer can give back the labels by the items.
3.319 + ///
3.320 + /// Returns true if the writer can give back the the labels by the items.
3.321 + bool isLabelWriter() const {
3.322 + return nodeset_writer.isLabelWriter() &&
3.323 + uedgeset_writer.isLabelWriter();
3.324 + }
3.325 +
3.326 + /// \brief Write the label of the given node.
3.327 + ///
3.328 + /// It writes the label of the given node. If there was written a "label"
3.329 + /// named node map then it will write the map value belonging to the node.
3.330 + void writeLabel(std::ostream& os, const Node& item) const {
3.331 + nodeset_writer.writeLabel(os, item);
3.332 + }
3.333 +
3.334 + /// \brief Write the label of the given edge.
3.335 + ///
3.336 + /// It writes the label of the given edge. If there was written a "label"
3.337 + /// named edge map then it will write the map value belonging to the edge.
3.338 + void writeLabel(std::ostream& os, const Edge& item) const {
3.339 + uedgeset_writer.writeLabel(os, item);
3.340 + }
3.341 +
3.342 + /// \brief Write the label of the given undirected edge.
3.343 + ///
3.344 + /// It writes the label of the given undirected edge. If there was
3.345 + /// written a "label" named edge map then it will write the map
3.346 + /// value belonging to the edge.
3.347 + void writeLabel(std::ostream& os, const UEdge& item) const {
3.348 + uedgeset_writer.writeLabel(os, item);
3.349 + }
3.350 +
3.351 + /// \brief Sorts the given node vector by label.
3.352 + ///
3.353 + /// Sorts the given node vector by label. If there was written an
3.354 + /// "label" named map then the vector will be sorted by the values
3.355 + /// of this map. Otherwise if the \c forceLabel parameter was true
3.356 + /// it will be sorted by its id in the graph.
3.357 + void sortByLabel(std::vector<Node>& nodes) const {
3.358 + nodeset_writer.sortByLabel(nodes);
3.359 + }
3.360 +
3.361 + /// \brief Sorts the given edge vector by label.
3.362 + ///
3.363 + /// Sorts the given edge vector by label. If there was written an
3.364 + /// "label" named map then the vector will be sorted by the values
3.365 + /// of this map. Otherwise if the \c forceLabel parameter was true
3.366 + /// it will be sorted by its id in the graph.
3.367 + void sortByLabel(std::vector<Edge>& edges) const {
3.368 + uedgeset_writer.sortByLabel(edges);
3.369 + }
3.370 +
3.371 + /// \brief Sorts the given undirected edge vector by label.
3.372 + ///
3.373 + /// Sorts the given undirected edge vector by label. If there was
3.374 + /// written an "label" named map then the vector will be sorted by
3.375 + /// the values of this map. Otherwise if the \c forceLabel
3.376 + /// parameter was true it will be sorted by its id in the graph.
3.377 + void sortByLabel(std::vector<UEdge>& uedges) const {
3.378 + uedgeset_writer.sortByLabel(uedges);
3.379 + }
3.380 +
3.381 + private:
3.382 +
3.383 + LemonWriter* writer;
3.384 + bool own_writer;
3.385 +
3.386 + BpNodeSetWriter<Graph, WriterTraits> nodeset_writer;
3.387 + UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
3.388 +
3.389 + NodeWriter<Graph> node_writer;
3.390 + UEdgeWriter<Graph> uedge_writer;
3.391 +
3.392 + AttributeWriter<WriterTraits> attribute_writer;
3.393 + };
3.394 +
3.395 /// @}
3.396
3.397 }
4.1 --- a/lemon/lemon_reader.h Sat Oct 20 14:29:12 2007 +0000
4.2 +++ b/lemon/lemon_reader.h Wed Oct 24 16:31:49 2007 +0000
4.3 @@ -311,7 +311,7 @@
4.4
4.5 MapReaderBase() { _touched = false; }
4.6
4.7 - void touch() { _touched = true; }
4.8 + void touch(bool value = true) { _touched = value; }
4.9 bool touched() const { return _touched; }
4.10
4.11 virtual ~MapReaderBase() {}
4.12 @@ -593,8 +593,7 @@
4.13
4.14 virtual int_type underflow() {
4.15 char c;
4.16 - if (_is.read(&c, 1)) {
4.17 - _is.putback(c);
4.18 + if ((c = _is.peek()) != EOF) {
4.19 if (c == '@') {
4.20 return EOF;
4.21 }
4.22 @@ -603,13 +602,13 @@
4.23 }
4.24 char_type *ptr;
4.25 for (ptr = base(); ptr != eptr(); ++ptr) {
4.26 - if (_is.read(&c, 1)) {
4.27 + if ((c = _is.get()) != EOF) {
4.28 if (c == '\n') ++_num;
4.29 if (put_char(c)) {
4.30 *ptr = c;
4.31 } else {
4.32 if (skip_state == after_endl && c == '@') {
4.33 - _is.putback('@');
4.34 + _is.putback(c);
4.35 break;
4.36 }
4.37 --ptr;
4.38 @@ -638,6 +637,36 @@
4.39
4.40 };
4.41
4.42 + static void skipPreSection(std::istream& is, int& line_num) {
4.43 + enum skip_state_type { skip, after_endl };
4.44 +
4.45 + skip_state_type skip_state = after_endl;
4.46 + char c;
4.47 +
4.48 + while ((c = is.get()) != EOF) {
4.49 + if (c == '\n') ++line_num;
4.50 +
4.51 + switch (skip_state) {
4.52 + case skip:
4.53 + if (c == '\n') skip_state = after_endl;
4.54 + break;
4.55 + case after_endl:
4.56 + switch (c) {
4.57 + case '@':
4.58 + is.putback(c);
4.59 + return;
4.60 + case '\n':
4.61 + continue;
4.62 + default:
4.63 + if (!isspace(c)) {
4.64 + skip_state = skip;
4.65 + }
4.66 + break;
4.67 + }
4.68 + }
4.69 + }
4.70 + }
4.71 +
4.72 public:
4.73
4.74 /// \brief Abstract base class for reading a section.
4.75 @@ -722,6 +751,7 @@
4.76 std::string line;
4.77
4.78 SectionReaders::iterator it;
4.79 + skipPreSection(*is, line_num);
4.80 while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
4.81 for (it = readers.begin(); it != readers.end(); ++it) {
4.82 if (it->first->header(line)) {
4.83 @@ -732,6 +762,7 @@
4.84 buffer.pubsetbuf(buf, sizeof(buf));
4.85 std::istream ss(&buffer);
4.86 it->first->read(ss);
4.87 + skipPreSection(*is, line_num);
4.88 break;
4.89 } catch (DataFormatError& error) {
4.90 error.line(buffer.line_num());
4.91 @@ -984,6 +1015,465 @@
4.92 };
4.93
4.94 /// \ingroup section_io
4.95 + /// \brief SectionReader for reading a bipartite graph's nodeset.
4.96 + ///
4.97 + /// The lemon format can store multiple bipartite graph nodesets
4.98 + /// with several maps. The bipartite graph nodeset section's header
4.99 + /// line is \c \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_name
4.100 + /// may be empty.
4.101 + ///
4.102 + /// The first line of the section contains \c "&anodeset" and the
4.103 + /// the names of the A-node maps and regular maps separated with
4.104 + /// white spaces. Each next lines describes an A-node in the anodeset,
4.105 + /// and contains the mapped values for each map. If one of the line
4.106 + /// starts with \c "&bnodeset" then this line contains the names of
4.107 + /// the B-node maps and the regular node maps. And the remaining lines
4.108 + /// contains the mapped values to the B-nodes.
4.109 + ///
4.110 + /// If there is "label" named map then it should be defined in both
4.111 + /// nodeset, and it will be regarded as id map. This map should
4.112 + /// contain only unique values and when the \c readLabel() member
4.113 + /// will read a value from the given stream it will give back that
4.114 + /// node which is mapped to this value.
4.115 + ///
4.116 + /// \relates LemonReader
4.117 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
4.118 + class BpNodeSetReader : public LemonReader::SectionReader {
4.119 + typedef LemonReader::SectionReader Parent;
4.120 + public:
4.121 +
4.122 + typedef _Graph Graph;
4.123 + typedef _Traits Traits;
4.124 + typedef typename Graph::Node Node;
4.125 + typedef typename Traits::Skipper DefaultSkipper;
4.126 +
4.127 + /// \brief Constructor.
4.128 + ///
4.129 + /// Constructor for BpNodeSetReader. It creates the BpNodeSetReader and
4.130 + /// attach it into the given LemonReader. The nodeset reader will
4.131 + /// add the read nodes to the given Graph. The reader will read
4.132 + /// the section when the \c section_name and the \c _name are the same.
4.133 + BpNodeSetReader(LemonReader& _reader,
4.134 + Graph& _graph,
4.135 + const std::string& _name = std::string(),
4.136 + const DefaultSkipper& _skipper = DefaultSkipper())
4.137 + : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {}
4.138 +
4.139 +
4.140 + /// \brief Destructor.
4.141 + ///
4.142 + /// Destructor for BpNodeSetReader.
4.143 + virtual ~BpNodeSetReader() {
4.144 + for (typename MapReaders::iterator it = readers.begin();
4.145 + it != readers.end(); ++it) {
4.146 + delete it->second;
4.147 + }
4.148 + }
4.149 +
4.150 + private:
4.151 + BpNodeSetReader(const BpNodeSetReader&);
4.152 + void operator=(const BpNodeSetReader&);
4.153 +
4.154 + public:
4.155 +
4.156 + /// \brief Add a new node map reader command for the reader.
4.157 + ///
4.158 + /// Add a new node map reader command for the reader.
4.159 + template <typename Map>
4.160 + BpNodeSetReader& readNodeMap(std::string label, Map& map) {
4.161 + return _readMap<
4.162 + typename Traits::template Reader<typename Map::Value>, Map,
4.163 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.164 + }
4.165 +
4.166 + template <typename Map>
4.167 + BpNodeSetReader& readNodeMap(std::string label, const Map& map) {
4.168 + return _readMap<
4.169 + typename Traits::template Reader<typename Map::Value>, Map,
4.170 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.171 + }
4.172 +
4.173 + /// \brief Add a new node map reader command for the reader.
4.174 + ///
4.175 + /// Add a new node map reader command for the reader.
4.176 + template <typename ItemReader, typename Map>
4.177 + BpNodeSetReader& readNodeMap(std::string label, Map& map,
4.178 + const ItemReader& ir = ItemReader()) {
4.179 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.180 + (label, map, ir);
4.181 + }
4.182 +
4.183 + template <typename ItemReader, typename Map>
4.184 + BpNodeSetReader& readNodeMap(std::string label, const Map& map,
4.185 + const ItemReader& ir = ItemReader()) {
4.186 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.187 + (label, map, ir);
4.188 + }
4.189 +
4.190 + private:
4.191 +
4.192 + template <typename ItemReader, typename Map, typename MapParameter>
4.193 + BpNodeSetReader& _readMap(std::string label, MapParameter map,
4.194 + const ItemReader& ir = ItemReader()) {
4.195 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
4.196 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
4.197 + if (areaders.find(label) != areaders.end() ||
4.198 + breaders.find(label) != breaders.end() ||
4.199 + readers.find(label) != readers.end()) {
4.200 + ErrorMessage msg;
4.201 + msg << "Multiple read rule for node map: " << label;
4.202 + throw IoParameterError(msg.message());
4.203 + }
4.204 + readers.insert(make_pair(label, new _reader_bits::
4.205 + MapReader<Node, Map, ItemReader>(map, ir)));
4.206 + return *this;
4.207 + }
4.208 +
4.209 + public:
4.210 +
4.211 + /// \brief Add a new A-node map reader command for the reader.
4.212 + ///
4.213 + /// Add a new A-node map reader command for the reader.
4.214 + template <typename Map>
4.215 + BpNodeSetReader& readANodeMap(std::string label, Map& map) {
4.216 + return _readAMap<
4.217 + typename Traits::template Reader<typename Map::Value>, Map,
4.218 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.219 + }
4.220 +
4.221 + template <typename Map>
4.222 + BpNodeSetReader& readANodeMap(std::string label, const Map& map) {
4.223 + return _readAMap<
4.224 + typename Traits::template Reader<typename Map::Value>, Map,
4.225 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.226 + }
4.227 +
4.228 + /// \brief Add a new A-node map reader command for the reader.
4.229 + ///
4.230 + /// Add a new A-node map reader command for the reader.
4.231 + template <typename ItemReader, typename Map>
4.232 + BpNodeSetReader& readANodeMap(std::string label, Map& map,
4.233 + const ItemReader& ir = ItemReader()) {
4.234 + return _readAMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.235 + (label, map, ir);
4.236 + }
4.237 +
4.238 + template <typename ItemReader, typename Map>
4.239 + BpNodeSetReader& readANodeMap(std::string label, const Map& map,
4.240 + const ItemReader& ir = ItemReader()) {
4.241 + return _readAMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.242 + (label, map, ir);
4.243 + }
4.244 +
4.245 + private:
4.246 +
4.247 + template <typename ItemReader, typename Map, typename MapParameter>
4.248 + BpNodeSetReader& _readAMap(std::string label, MapParameter map,
4.249 + const ItemReader& ir = ItemReader()) {
4.250 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
4.251 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
4.252 + if (label == "label") {
4.253 + throw IoParameterError("Label cannot be A-node map");
4.254 + }
4.255 + if (areaders.find(label) != areaders.end() ||
4.256 + readers.find(label) != readers.end()) {
4.257 + ErrorMessage msg;
4.258 + msg << "Multiple read rule for A-node map: " << label;
4.259 + throw IoParameterError(msg.message());
4.260 + }
4.261 + areaders.insert(make_pair(label, new _reader_bits::
4.262 + MapReader<Node, Map, ItemReader>(map, ir)));
4.263 + return *this;
4.264 + }
4.265 +
4.266 + public:
4.267 +
4.268 + /// \brief Add a new B-node map reader command for the reader.
4.269 + ///
4.270 + /// Add a new B-node map reader command for the reader.
4.271 + template <typename Map>
4.272 + BpNodeSetReader& readBNodeMap(std::string label, Map& map) {
4.273 + return _readBMap<
4.274 + typename Traits::template Reader<typename Map::Value>, Map,
4.275 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.276 + }
4.277 +
4.278 + template <typename Map>
4.279 + BpNodeSetReader& readBNodeMap(std::string label, const Map& map) {
4.280 + return _readBMap<
4.281 + typename Traits::template Reader<typename Map::Value>, Map,
4.282 + typename _reader_bits::Arg<Map>::Type>(label, map);
4.283 + }
4.284 +
4.285 + /// \brief Add a new B-node map reader command for the reader.
4.286 + ///
4.287 + /// Add a new B-node map reader command for the reader.
4.288 + template <typename ItemReader, typename Map>
4.289 + BpNodeSetReader& readBNodeMap(std::string label, Map& map,
4.290 + const ItemReader& ir = ItemReader()) {
4.291 + return _readBMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.292 + (label, map, ir);
4.293 + }
4.294 +
4.295 + template <typename ItemReader, typename Map>
4.296 + BpNodeSetReader& readBNodeMap(std::string label, const Map& map,
4.297 + const ItemReader& ir = ItemReader()) {
4.298 + return _readBMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
4.299 + (label, map, ir);
4.300 + }
4.301 +
4.302 + private:
4.303 +
4.304 + template <typename ItemReader, typename Map, typename MapParameter>
4.305 + BpNodeSetReader& _readBMap(std::string label, MapParameter map,
4.306 + const ItemReader& ir = ItemReader()) {
4.307 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
4.308 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
4.309 + if (label == "label") {
4.310 + throw IoParameterError("Label cannot be B-node map");
4.311 + }
4.312 + if (breaders.find(label) != breaders.end() ||
4.313 + readers.find(label) != readers.end()) {
4.314 + ErrorMessage msg;
4.315 + msg << "Multiple read rule for B-node map: " << label;
4.316 + throw IoParameterError(msg.message());
4.317 + }
4.318 + breaders.insert(make_pair(label, new _reader_bits::
4.319 + MapReader<Node, Map, ItemReader>(map, ir)));
4.320 + return *this;
4.321 + }
4.322 +
4.323 + public:
4.324 +
4.325 + /// \brief Add a new node map skipper command for the reader.
4.326 + ///
4.327 + /// Add a new node map skipper command for the reader.
4.328 + template <typename ItemReader>
4.329 + BpNodeSetReader& skipNodeMap(std::string label,
4.330 + const ItemReader& ir = ItemReader()) {
4.331 + if (areaders.find(label) != areaders.end() ||
4.332 + breaders.find(label) != breaders.end() ||
4.333 + readers.find(label) != readers.end()) {
4.334 + ErrorMessage msg;
4.335 + msg << "Multiple read rule for node map: " << label;
4.336 + throw IoParameterError(msg.message());
4.337 + }
4.338 + readers.insert(make_pair(label, new _reader_bits::
4.339 + SkipReader<Node, ItemReader>(ir)));
4.340 + return *this;
4.341 + }
4.342 +
4.343 + /// \brief Add a new A-node map skipper command for the reader.
4.344 + ///
4.345 + /// Add a new A-node map skipper command for the reader.
4.346 + template <typename ItemReader>
4.347 + BpNodeSetReader& skipANodeMap(std::string label,
4.348 + const ItemReader& ir = ItemReader()) {
4.349 + if (label == "label") {
4.350 + throw IoParameterError("Label cannot be A-node map");
4.351 + }
4.352 + if (areaders.find(label) != areaders.end() ||
4.353 + readers.find(label) != readers.end()) {
4.354 + ErrorMessage msg;
4.355 + msg << "Multiple read rule for A-node map: " << label;
4.356 + throw IoParameterError(msg.message());
4.357 + }
4.358 + areaders.insert(make_pair(label, new _reader_bits::
4.359 + SkipReader<Node, ItemReader>(ir)));
4.360 + return *this;
4.361 + }
4.362 +
4.363 + /// \brief Add a new B-node map skipper command for the reader.
4.364 + ///
4.365 + /// Add a new B-node map skipper command for the reader.
4.366 + template <typename ItemReader>
4.367 + BpNodeSetReader& skipBNodeMap(std::string label,
4.368 + const ItemReader& ir = ItemReader()) {
4.369 + if (label == "label") {
4.370 + throw IoParameterError("Label cannot be B-node map");
4.371 + }
4.372 + if (breaders.find(label) != breaders.end() ||
4.373 + readers.find(label) != readers.end()) {
4.374 + ErrorMessage msg;
4.375 + msg << "Multiple read rule for B-node map: " << label;
4.376 + throw IoParameterError(msg.message());
4.377 + }
4.378 + breaders.insert(make_pair(label, new _reader_bits::
4.379 + SkipReader<Node, ItemReader>(ir)));
4.380 + return *this;
4.381 + }
4.382 +
4.383 +
4.384 + protected:
4.385 +
4.386 + /// \brief Gives back true when the SectionReader can process
4.387 + /// the section with the given header line.
4.388 + ///
4.389 + /// It gives back true when the header line starts with \c \@nodeset,
4.390 + /// and the header line's name and the nodeset's name are the same.
4.391 + virtual bool header(const std::string& line) {
4.392 + std::istringstream ls(line);
4.393 + std::string command;
4.394 + std::string id;
4.395 + ls >> command >> id;
4.396 + return command == "@bpnodeset" && name == id;
4.397 + }
4.398 +
4.399 + /// \brief Reader function of the section.
4.400 + ///
4.401 + /// It reads the content of the section.
4.402 + virtual void read(std::istream& is) {
4.403 + std::string line;
4.404 + {
4.405 + std::vector<_reader_bits::MapReaderBase<Node>* > index;
4.406 + {
4.407 + getline(is, line);
4.408 + std::istringstream ls(line);
4.409 + std::string id;
4.410 + ls >> id;
4.411 + if (id != "&anodeset") {
4.412 + throw IoParameterError("Cannot find &anodeset subsection");
4.413 + }
4.414 + while (ls >> id) {
4.415 + typename MapReaders::iterator it = readers.find(id);
4.416 + typename MapReaders::iterator ait = areaders.find(id);
4.417 + if (it != readers.end()) {
4.418 + it->second->touch();
4.419 + index.push_back(it->second);
4.420 + } else if (ait != areaders.end()) {
4.421 + ait->second->touch();
4.422 + index.push_back(ait->second);
4.423 + }
4.424 + if (id == "label") {
4.425 + inverter.reset(index.back()->getInverter());
4.426 + index.back() = inverter.get();
4.427 + }
4.428 + }
4.429 + }
4.430 + for (typename MapReaders::iterator it = areaders.begin();
4.431 + it != areaders.end(); ++it) {
4.432 + if (!it->second->touched()) {
4.433 + ErrorMessage msg;
4.434 + msg << "Map not found in file: " << it->first;
4.435 + throw IoParameterError(msg.message());
4.436 + }
4.437 + }
4.438 + for (typename MapReaders::iterator it = readers.begin();
4.439 + it != readers.end(); ++it) {
4.440 + if (!it->second->touched()) {
4.441 + ErrorMessage msg;
4.442 + msg << "Map not found in file: " << it->first;
4.443 + throw IoParameterError(msg.message());
4.444 + }
4.445 + it->second->touch(false);
4.446 + }
4.447 +
4.448 + while (getline(is, line)) {
4.449 + if (line[0] == '&') {
4.450 + std::istringstream ls(line);
4.451 + std::string id;
4.452 + ls >> id;
4.453 + if (id == "&bnodeset") break;
4.454 + }
4.455 + Node node = graph.addANode();
4.456 + std::istringstream ls(line);
4.457 + for (int i = 0; i < int(index.size()); ++i) {
4.458 + index[i]->read(ls, node);
4.459 + }
4.460 + }
4.461 + }
4.462 +
4.463 + {
4.464 + std::vector<_reader_bits::MapReaderBase<Node>* > index;
4.465 + {
4.466 + std::istringstream ls(line);
4.467 + std::string id;
4.468 + ls >> id;
4.469 + if (id != "&bnodeset") {
4.470 + throw IoParameterError("Cannot find &bnodeset subsection");
4.471 + }
4.472 + while (ls >> id) {
4.473 + typename MapReaders::iterator it = readers.find(id);
4.474 + typename MapReaders::iterator bit = breaders.find(id);
4.475 + if (it != readers.end()) {
4.476 + it->second->touch();
4.477 + index.push_back(it->second);
4.478 + } else if (bit != breaders.end()) {
4.479 + bit->second->touch();
4.480 + index.push_back(bit->second);
4.481 + }
4.482 + if (id == "label" && inverter.get() != 0) {
4.483 + index.back() = inverter.get();
4.484 + }
4.485 + }
4.486 + }
4.487 + for (typename MapReaders::iterator it = breaders.begin();
4.488 + it != breaders.end(); ++it) {
4.489 + if (!it->second->touched()) {
4.490 + ErrorMessage msg;
4.491 + msg << "Map not found in file: " << it->first;
4.492 + throw IoParameterError(msg.message());
4.493 + }
4.494 + }
4.495 + for (typename MapReaders::iterator it = readers.begin();
4.496 + it != readers.end(); ++it) {
4.497 + if (!it->second->touched()) {
4.498 + ErrorMessage msg;
4.499 + msg << "Map not found in file: " << it->first;
4.500 + throw IoParameterError(msg.message());
4.501 + }
4.502 + }
4.503 + while (getline(is, line)) {
4.504 + Node node = graph.addBNode();
4.505 + std::istringstream ls(line);
4.506 + for (int i = 0; i < int(index.size()); ++i) {
4.507 + index[i]->read(ls, node);
4.508 + }
4.509 + }
4.510 + }
4.511 + }
4.512 +
4.513 + virtual void missing() {
4.514 + if (readers.empty()) return;
4.515 + ErrorMessage msg;
4.516 + msg << "BpNodeSet section not found in file: @bpnodeset " << name;
4.517 + throw IoParameterError(msg.message());
4.518 + }
4.519 +
4.520 + public:
4.521 +
4.522 + /// \brief Returns true if the nodeset can give back the node by its label.
4.523 + ///
4.524 + /// Returns true if the nodeset can give back the node by its label.
4.525 + /// It is possible only if an "label" named map was read.
4.526 + bool isLabelReader() const {
4.527 + return inverter.get() != 0;
4.528 + }
4.529 +
4.530 + /// \brief Gives back the node by its label.
4.531 + ///
4.532 + /// It reads an id from the stream and gives back which node belongs to
4.533 + /// it. It is possible only if there was read an "label" named map.
4.534 + void readLabel(std::istream& is, Node& node) const {
4.535 + node = inverter->read(is);
4.536 + }
4.537 +
4.538 + private:
4.539 +
4.540 + typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*>
4.541 + MapReaders;
4.542 +
4.543 + MapReaders areaders, breaders, readers;
4.544 +
4.545 + Graph& graph;
4.546 + std::string name;
4.547 + _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
4.548 +
4.549 + std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
4.550 + };
4.551 +
4.552 +
4.553 + /// \ingroup section_io
4.554 /// \brief SectionReader for reading a graph's edgeset.
4.555 ///
4.556 /// The lemon format can store multiple graph edgesets with several maps.
5.1 --- a/lemon/lemon_writer.h Sat Oct 20 14:29:12 2007 +0000
5.2 +++ b/lemon/lemon_writer.h Wed Oct 24 16:31:49 2007 +0000
5.3 @@ -144,8 +144,8 @@
5.4 }
5.5
5.6 private:
5.7 + const Graph& graph;
5.8 typename Ref<Map>::Type map;
5.9 - const Graph& graph;
5.10 };
5.11
5.12 template <typename Graph, typename Map>
5.13 @@ -168,8 +168,8 @@
5.14 }
5.15
5.16 private:
5.17 + const Graph& graph;
5.18 typename Ref<Map>::Type map;
5.19 - const Graph& graph;
5.20 };
5.21
5.22 template <typename Graph, typename Map>
5.23 @@ -502,7 +502,7 @@
5.24 /// \c writeLabel() member will be called with a node it will write it's
5.25 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
5.26 /// then the label map will be the id in the graph. In addition if the
5.27 - /// the \c _forceSort is true then the writer will write the edges
5.28 + /// the \c _forceSort is true then the writer will write the nodes
5.29 /// sorted by the labels.
5.30 ///
5.31 /// \relates LemonWriter
5.32 @@ -680,6 +680,300 @@
5.33 };
5.34
5.35 /// \ingroup section_io
5.36 + /// \brief SectionWriter for writing a bipartite graph's nodeset.
5.37 + ///
5.38 + /// The lemon format can store multiple bipartite graph nodesets
5.39 + /// with several maps. The nodeset section's header line is \c
5.40 + /// \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_name may be empty.
5.41 + ///
5.42 + /// The first line of the section contains the names of the maps separated
5.43 + /// with white spaces. Each next lines describes a node in the nodeset, and
5.44 + /// contains the mapped values for each map.
5.45 + ///
5.46 + /// If the nodeset contains an \c "label" named map then it will be regarded
5.47 + /// as label map. This map should contain only unique values and when the
5.48 + /// \c writeLabel() member will be called with a node it will write it's
5.49 + /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
5.50 + /// then the label map will be the id in the graph. In addition if the
5.51 + /// the \c _forceSort is true then the writer will write the edges
5.52 + /// sorted by the labels.
5.53 + ///
5.54 + /// \relates LemonWriter
5.55 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
5.56 + class BpNodeSetWriter : public LemonWriter::SectionWriter {
5.57 + typedef LemonWriter::SectionWriter Parent;
5.58 + public:
5.59 +
5.60 + typedef _Graph Graph;
5.61 + typedef _Traits Traits;
5.62 + typedef typename Graph::Node Node;
5.63 +
5.64 + /// \brief Constructor.
5.65 + ///
5.66 + /// Constructor for BpNodeSetWriter. It creates the BpNodeSetWriter and
5.67 + /// attach it into the given LemonWriter. If the \c _forceLabelMap
5.68 + /// parameter is true then the writer will write own label map when
5.69 + /// the user does not give "label" named map. In addition if the
5.70 + /// the \c _forceSort is true then the writer will write the nodes
5.71 + /// sorted by the labels.
5.72 + BpNodeSetWriter(LemonWriter& _writer, const Graph& _graph,
5.73 + const std::string& _name = std::string(),
5.74 + bool _forceLabelMap = true, bool _forceSort = true)
5.75 + : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
5.76 + forceSort(_forceSort), graph(_graph), name(_name) {}
5.77 +
5.78 + /// \brief Destructor.
5.79 + ///
5.80 + /// Destructor for BpNodeSetWriter.
5.81 + virtual ~BpNodeSetWriter() {
5.82 + typename MapWriters::iterator it;
5.83 + for (it = writers.begin(); it != writers.end(); ++it) {
5.84 + delete it->second;
5.85 + }
5.86 + }
5.87 +
5.88 + private:
5.89 + BpNodeSetWriter(const BpNodeSetWriter&);
5.90 + void operator=(const BpNodeSetWriter&);
5.91 +
5.92 + public:
5.93 +
5.94 + /// \brief Add a new A-node map writer command for the writer.
5.95 + ///
5.96 + /// Add a new A-node map writer command for the writer.
5.97 + template <typename Map>
5.98 + BpNodeSetWriter& writeANodeMap(std::string label, const Map& map) {
5.99 + return writeANodeMap<typename Traits::
5.100 + template Writer<typename Map::Value>, Map>(label, map);
5.101 + }
5.102 +
5.103 + /// \brief Add a new A-node map writer command for the writer.
5.104 + ///
5.105 + /// Add a new A-node map writer command for the writer.
5.106 + template <typename ItemWriter, typename Map>
5.107 + BpNodeSetWriter& writeANodeMap(std::string label, const Map& map,
5.108 + const ItemWriter& iw = ItemWriter()) {
5.109 + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
5.110 + checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
5.111 + if (label == "label") {
5.112 + throw IoParameterError("Label cannot be A-node map");
5.113 + }
5.114 + awriters.push_back(make_pair(label, new _writer_bits::
5.115 + MapWriter<Node, Map, ItemWriter>(map, iw)));
5.116 + return *this;
5.117 + }
5.118 +
5.119 + /// \brief Add a new B-node map writer command for the writer.
5.120 + ///
5.121 + /// Add a new B-node map writer command for the writer.
5.122 + template <typename Map>
5.123 + BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map) {
5.124 + return writeBNodeMap<typename Traits::
5.125 + template Writer<typename Map::Value>, Map>(label, map);
5.126 + }
5.127 +
5.128 + /// \brief Add a new B-node map writer command for the writer.
5.129 + ///
5.130 + /// Add a new B-node map writer command for the writer.
5.131 + template <typename ItemWriter, typename Map>
5.132 + BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map,
5.133 + const ItemWriter& iw = ItemWriter()) {
5.134 + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
5.135 + checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
5.136 + if (label == "label") {
5.137 + throw IoParameterError("Label cannot be B-node map");
5.138 + }
5.139 + bwriters.push_back(make_pair(label, new _writer_bits::
5.140 + MapWriter<Node, Map, ItemWriter>(map, iw)));
5.141 + return *this;
5.142 + }
5.143 +
5.144 + /// \brief Add a new node map writer command for the writer.
5.145 + ///
5.146 + /// Add a new node map writer command for the writer.
5.147 + template <typename Map>
5.148 + BpNodeSetWriter& writeNodeMap(std::string label, const Map& map) {
5.149 + return writeNodeMap<typename Traits::
5.150 + template Writer<typename Map::Value>, Map>(label, map);
5.151 + }
5.152 +
5.153 + /// \brief Add a new node map writer command for the writer.
5.154 + ///
5.155 + /// Add a new node map writer command for the writer.
5.156 + template <typename ItemWriter, typename Map>
5.157 + BpNodeSetWriter& writeNodeMap(std::string label, const Map& map,
5.158 + const ItemWriter& iw = ItemWriter()) {
5.159 + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
5.160 + checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
5.161 + writers.push_back(make_pair(label, new _writer_bits::
5.162 + MapWriter<Node, Map, ItemWriter>(map, iw)));
5.163 + return *this;
5.164 + }
5.165 +
5.166 + protected:
5.167 +
5.168 + /// \brief The header of the section.
5.169 + ///
5.170 + /// It gives back the header of the section.
5.171 + virtual std::string header() {
5.172 + return "@bpnodeset " + name;
5.173 + }
5.174 +
5.175 + /// \brief Writer function of the section.
5.176 + ///
5.177 + /// Write the content of the section.
5.178 + virtual void write(std::ostream& os) {
5.179 + for (int i = 0; i < int(writers.size()); ++i) {
5.180 + if (writers[i].first == "label") {
5.181 + labelMap = writers[i].second;
5.182 + forceLabelMap = false;
5.183 + break;
5.184 + }
5.185 + }
5.186 + {
5.187 + os << "&anodeset ";
5.188 + std::vector<Node> items;
5.189 + for (typename Graph::ANodeIt it(graph); it != INVALID; ++it) {
5.190 + items.push_back(it);
5.191 + }
5.192 + if (forceSort) {
5.193 + if (labelMap) {
5.194 + labelMap->sort(items);
5.195 + } else {
5.196 + typedef IdMap<Graph, Node> Map;
5.197 + Map map(graph);
5.198 + _writer_bits::ComposeLess<Map> less(map);
5.199 + std::sort(items.begin(), items.end(), less);
5.200 + }
5.201 + }
5.202 + if (forceLabelMap) {
5.203 + os << "label\t";
5.204 + }
5.205 + for (int i = 0; i < int(writers.size()); ++i) {
5.206 + os << writers[i].first << '\t';
5.207 + }
5.208 + for (int i = 0; i < int(awriters.size()); ++i) {
5.209 + os << awriters[i].first << '\t';
5.210 + }
5.211 + os << std::endl;
5.212 + for (typename std::vector<Node>::iterator it = items.begin();
5.213 + it != items.end(); ++it) {
5.214 + if (forceLabelMap) {
5.215 + os << graph.id(*it) << '\t';
5.216 + }
5.217 + for (int i = 0; i < int(writers.size()); ++i) {
5.218 + writers[i].second->write(os, *it);
5.219 + os << '\t';
5.220 + }
5.221 + for (int i = 0; i < int(awriters.size()); ++i) {
5.222 + awriters[i].second->write(os, *it);
5.223 + os << '\t';
5.224 + }
5.225 + os << std::endl;
5.226 + }
5.227 + }
5.228 + {
5.229 + os << "&bnodeset ";
5.230 + std::vector<Node> items;
5.231 + for (typename Graph::BNodeIt it(graph); it != INVALID; ++it) {
5.232 + items.push_back(it);
5.233 + }
5.234 + if (forceSort) {
5.235 + if (labelMap) {
5.236 + labelMap->sort(items);
5.237 + } else {
5.238 + typedef IdMap<Graph, Node> Map;
5.239 + Map map(graph);
5.240 + _writer_bits::ComposeLess<Map> less(map);
5.241 + std::sort(items.begin(), items.end(), less);
5.242 + }
5.243 + }
5.244 + if (forceLabelMap) {
5.245 + os << "label\t";
5.246 + }
5.247 + for (int i = 0; i < int(writers.size()); ++i) {
5.248 + os << writers[i].first << '\t';
5.249 + }
5.250 + for (int i = 0; i < int(bwriters.size()); ++i) {
5.251 + os << bwriters[i].first << '\t';
5.252 + }
5.253 + os << std::endl;
5.254 + for (typename std::vector<Node>::iterator it = items.begin();
5.255 + it != items.end(); ++it) {
5.256 + if (forceLabelMap) {
5.257 + os << graph.id(*it) << '\t';
5.258 + }
5.259 + for (int i = 0; i < int(writers.size()); ++i) {
5.260 + writers[i].second->write(os, *it);
5.261 + os << '\t';
5.262 + }
5.263 + for (int i = 0; i < int(bwriters.size()); ++i) {
5.264 + bwriters[i].second->write(os, *it);
5.265 + os << '\t';
5.266 + }
5.267 + os << std::endl;
5.268 + }
5.269 + }
5.270 + }
5.271 +
5.272 + public:
5.273 +
5.274 + /// \brief Returns true if the nodeset can write the labels of the nodes.
5.275 + ///
5.276 + /// Returns true if the nodeset can write the labels of the nodes.
5.277 + /// It is possible only if a "label" named map was written or the
5.278 + /// \c _forceLabelMap constructor parameter was true.
5.279 + bool isLabelWriter() const {
5.280 + return labelMap != 0 || forceLabelMap;
5.281 + }
5.282 +
5.283 + /// \brief Write the label of the given node.
5.284 + ///
5.285 + /// It writes the label of the given node. If there was written a "label"
5.286 + /// named map then it will write the map value belongs to the node.
5.287 + /// Otherwise if the \c forceLabel parameter was true it will write
5.288 + /// its label in the graph.
5.289 + void writeLabel(std::ostream& os, const Node& item) const {
5.290 + if (forceLabelMap) {
5.291 + os << graph.id(item);
5.292 + } else {
5.293 + labelMap->write(os, item);
5.294 + }
5.295 + }
5.296 +
5.297 + /// \brief Sorts the given node vector by label.
5.298 + ///
5.299 + /// Sorts the given node vector by label. If there was written an
5.300 + /// "label" named map then the vector will be sorted by the values
5.301 + /// of this map. Otherwise if the \c forceLabel parameter was true
5.302 + /// it will be sorted by its id in the graph.
5.303 + void sortByLabel(std::vector<Node>& nodes) const {
5.304 + if (labelMap) {
5.305 + labelMap->sort(nodes);
5.306 + } else {
5.307 + typedef IdMap<Graph, Node> Map;
5.308 + Map map(graph);
5.309 + _writer_bits::ComposeLess<Map> less(map);
5.310 + std::sort(nodes.begin(), nodes.end(), less);
5.311 + }
5.312 + }
5.313 +
5.314 + private:
5.315 +
5.316 + typedef std::vector<std::pair<std::string, _writer_bits::
5.317 + MapWriterBase<Node>*> > MapWriters;
5.318 + MapWriters awriters, bwriters, writers;
5.319 +
5.320 + _writer_bits::MapWriterBase<Node>* labelMap;
5.321 + bool forceLabelMap;
5.322 + bool forceSort;
5.323 +
5.324 + const Graph& graph;
5.325 + std::string name;
5.326 +
5.327 + };
5.328 +
5.329 + /// \ingroup section_io
5.330 /// \brief SectionWriter for writing a graph's edgesets.
5.331 ///
5.332 /// The lemon format can store multiple graph edgesets with several maps.