IO with undirected edgesets and undirected graphs.
Missing features:
InfoReader,
aliased edges in undir edgesets
1.1 --- a/src/lemon/graph_reader.h Sat May 14 17:37:33 2005 +0000
1.2 +++ b/src/lemon/graph_reader.h Sat May 14 17:39:37 2005 +0000
1.3 @@ -56,8 +56,7 @@
1.4 /// parameters.
1.5 ///
1.6 /// \code
1.7 - /// reader.readNodeMap("x-coord", xCoordMap);
1.8 - /// reader.readNodeMap("y-coord", yCoordMap);
1.9 + /// reader.readNodeMap("coords", coords);
1.10 ///
1.11 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
1.12 /// reader.skipNodeMap<QuotedStringReader>("description");
1.13 @@ -114,12 +113,13 @@
1.14 ///
1.15 /// Construct a new GraphReader. It reads into the given graph
1.16 /// and it use the given reader as the default skipper.
1.17 - GraphReader(std::istream& _is, Graph& _graph,
1.18 + GraphReader(std::istream& _is,
1.19 + typename SmartParameter<Graph>::Type _graph,
1.20 const DefaultSkipper& _skipper = DefaultSkipper())
1.21 - : reader(new LemonReader(_is)), own_reader(true),
1.22 - graph(_graph), skipper(_skipper),
1.23 - nodeset_reader(*reader, graph, std::string(), skipper),
1.24 - edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
1.25 + : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
1.26 + nodeset_reader(*reader, _graph, std::string(), skipper),
1.27 + edgeset_reader(*reader, _graph, nodeset_reader,
1.28 + std::string(), skipper),
1.29 node_reader(*reader, nodeset_reader, std::string()),
1.30 edge_reader(*reader, edgeset_reader, std::string()),
1.31 attribute_reader(*reader, std::string()) {}
1.32 @@ -128,12 +128,14 @@
1.33 ///
1.34 /// Construct a new GraphReader. It reads into the given graph
1.35 /// and it use the given reader as the default skipper.
1.36 - GraphReader(const std::string& _filename, Graph& _graph,
1.37 + GraphReader(const std::string& _filename,
1.38 + typename SmartParameter<Graph>::Type _graph,
1.39 const DefaultSkipper& _skipper = DefaultSkipper())
1.40 : reader(new LemonReader(_filename)), own_reader(true),
1.41 - graph(_graph), skipper(_skipper),
1.42 - nodeset_reader(*reader, graph, std::string(), skipper),
1.43 - edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
1.44 + skipper(_skipper),
1.45 + nodeset_reader(*reader, _graph, std::string(), skipper),
1.46 + edgeset_reader(*reader, _graph, nodeset_reader,
1.47 + std::string(), skipper),
1.48 node_reader(*reader, nodeset_reader, std::string()),
1.49 edge_reader(*reader, edgeset_reader, std::string()),
1.50 attribute_reader(*reader, std::string()) {}
1.51 @@ -142,12 +144,13 @@
1.52 ///
1.53 /// Construct a new GraphReader. It reads into the given graph
1.54 /// and it use the given reader as the default skipper.
1.55 - GraphReader(LemonReader& _reader, Graph& _graph,
1.56 + GraphReader(LemonReader& _reader,
1.57 + typename SmartParameter<Graph>::Type _graph,
1.58 const DefaultSkipper& _skipper = DefaultSkipper())
1.59 - : reader(_reader), own_reader(false),
1.60 - graph(_graph), skipper(_skipper),
1.61 - nodeset_reader(*reader, graph, std::string(), skipper),
1.62 - edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
1.63 + : reader(_reader), own_reader(false), skipper(_skipper),
1.64 + nodeset_reader(*reader, _graph, std::string(), skipper),
1.65 + edgeset_reader(*reader, _graph, nodeset_reader,
1.66 + std::string(), skipper),
1.67 node_reader(*reader, nodeset_reader, std::string()),
1.68 edge_reader(*reader, edgeset_reader, std::string()),
1.69 attribute_reader(*reader, std::string()) {}
1.70 @@ -165,7 +168,13 @@
1.71 /// Add a new node map reader command for the reader.
1.72 template <typename Map>
1.73 GraphReader& readNodeMap(std::string name, Map& map) {
1.74 - nodeset_reader.readMap(name, map);
1.75 + nodeset_reader.readNodeMap(name, map);
1.76 + return *this;
1.77 + }
1.78 +
1.79 + template <typename Map>
1.80 + GraphReader& readNodeMap(std::string name, const Map& map) {
1.81 + nodeset_reader.readNodeMap(name, map);
1.82 return *this;
1.83 }
1.84
1.85 @@ -175,7 +184,14 @@
1.86 template <typename Reader, typename Map>
1.87 GraphReader& readNodeMap(std::string name, Map& map,
1.88 const Reader& reader = Reader()) {
1.89 - nodeset_reader.readMap(name, map, reader);
1.90 + nodeset_reader.readNodeMap(name, map, reader);
1.91 + return *this;
1.92 + }
1.93 +
1.94 + template <typename Reader, typename Map>
1.95 + GraphReader& readNodeMap(std::string name, const Map& map,
1.96 + const Reader& reader = Reader()) {
1.97 + nodeset_reader.readNodeMap(name, map, reader);
1.98 return *this;
1.99 }
1.100
1.101 @@ -185,7 +201,7 @@
1.102 template <typename Reader>
1.103 GraphReader& skipNodeMap(std::string name,
1.104 const Reader& reader = Reader()) {
1.105 - nodeset_reader.skipMap(name, reader);
1.106 + nodeset_reader.skipNodeMap(name, reader);
1.107 return *this;
1.108 }
1.109
1.110 @@ -194,7 +210,13 @@
1.111 /// Add a new edge map reader command for the reader.
1.112 template <typename Map>
1.113 GraphReader& readEdgeMap(std::string name, Map& map) {
1.114 - edgeset_reader.readMap(name, map);
1.115 + edgeset_reader.readEdgeMap(name, map);
1.116 + return *this;
1.117 + }
1.118 +
1.119 + template <typename Map>
1.120 + GraphReader& readEdgeMap(std::string name, const Map& map) {
1.121 + edgeset_reader.readEdgeMap(name, map);
1.122 return *this;
1.123 }
1.124
1.125 @@ -205,7 +227,14 @@
1.126 template <typename Reader, typename Map>
1.127 GraphReader& readEdgeMap(std::string name, Map& map,
1.128 const Reader& reader = Reader()) {
1.129 - edgeset_reader.readMap(name, map, reader);
1.130 + edgeset_reader.readEdgeMap(name, map, reader);
1.131 + return *this;
1.132 + }
1.133 +
1.134 + template <typename Reader, typename Map>
1.135 + GraphReader& readEdgeMap(std::string name, const Map& map,
1.136 + const Reader& reader = Reader()) {
1.137 + edgeset_reader.readEdgeMap(name, map, reader);
1.138 return *this;
1.139 }
1.140
1.141 @@ -213,10 +242,9 @@
1.142 ///
1.143 /// Add a new edge map skipper command for the reader.
1.144 template <typename Reader>
1.145 - GraphReader& skipEdgeMap(std::string name,
1.146 + GraphReader& skipEdgeMap(std::string name,
1.147 const Reader& reader = Reader()) {
1.148 -
1.149 - edgeset_reader.skipMap(name, reader);
1.150 + edgeset_reader.skipEdgeMap(name, reader);
1.151 return *this;
1.152 }
1.153
1.154 @@ -276,8 +304,6 @@
1.155 LemonReader* reader;
1.156 bool own_reader;
1.157
1.158 - Graph& graph;
1.159 -
1.160 DefaultSkipper skipper;
1.161
1.162 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
1.163 @@ -368,6 +394,365 @@
1.164 reader.run();
1.165 }
1.166
1.167 + /// \brief The undir graph reader class.
1.168 + ///
1.169 + /// The given file format may contain several maps and labeled nodes or
1.170 + /// edges.
1.171 + ///
1.172 + /// If you read a graph you need not read all the maps and items just those
1.173 + /// that you need. The interface of the \c GraphReader is very similar to
1.174 + /// the GraphWriter but the reading method does not depend on the order the
1.175 + /// given commands.
1.176 + ///
1.177 + /// The reader object suppose that each not readed value does not contain
1.178 + /// whitespaces, therefore it has some extra possibilities to control how
1.179 + /// it should skip the values when the string representation contains spaces.
1.180 + ///
1.181 + /// \code
1.182 + /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
1.183 + /// \endcode
1.184 + ///
1.185 + /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
1.186 + /// If there is a map that you do not want to read from the file and there is
1.187 + /// whitespace in the string represenation of the values then you should
1.188 + /// call the \c skipNodeMap() template member function with proper
1.189 + /// parameters.
1.190 + ///
1.191 + /// \code
1.192 + /// reader.readNodeMap("coords", coords);
1.193 + ///
1.194 + /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
1.195 + /// reader.skipNodeMap<QuotedStringReader>("description");
1.196 + ///
1.197 + /// reader.readNodeMap("color", colorMap);
1.198 + /// \endcode
1.199 + ///
1.200 + /// With the \c readUndirEdgeMap() member function you can give an
1.201 + /// undir edge map reading command similar to the NodeMaps.
1.202 + ///
1.203 + /// \code
1.204 + /// reader.readUndirEdgeMap("capacity", capacityMap);
1.205 + /// \endcode
1.206 + ///
1.207 + /// The reading of the directed edge maps is just a syntactical sugar.
1.208 + /// It reads two undirected edgemaps into a directed edge map. The
1.209 + /// undirected edge maps' name should be start with the \c '+' and the
1.210 + /// \c '-' character and the same.
1.211 + ///
1.212 + /// \code
1.213 + /// reader.readEdgeMap("flow", flowMap);
1.214 + /// \endcode
1.215 + ///
1.216 + /// With \c readNode() and \c readUndirEdge() functions you can read
1.217 + /// labeled Nodes and UndirEdges.
1.218 + ///
1.219 + /// \code
1.220 + /// reader.readNode("source", sourceNode);
1.221 + /// reader.readNode("target", targetNode);
1.222 + ///
1.223 + /// reader.readUndirEdge("observed", undirEdge);
1.224 + /// \endcode
1.225 + ///
1.226 + /// With the \c readAttribute() functions you can read an attribute
1.227 + /// in a variable. You can specify the reader for the attribute as
1.228 + /// the nodemaps.
1.229 + ///
1.230 + /// After you give all read commands you must call the \c run() member
1.231 + /// function, which execute all the commands.
1.232 + ///
1.233 + /// \code
1.234 + /// reader.run();
1.235 + /// \endcode
1.236 + ///
1.237 + /// \see GraphReader
1.238 + /// \see DefaultReaderTraits
1.239 + /// \see \ref UndirGraphWriter
1.240 + /// \see \ref graph-io-page
1.241 + ///
1.242 + /// \author Balazs Dezso
1.243 + template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
1.244 + class UndirGraphReader {
1.245 + public:
1.246 +
1.247 + typedef _Graph Graph;
1.248 + typedef typename Graph::Node Node;
1.249 + typedef typename Graph::Edge Edge;
1.250 + typedef typename Graph::UndirEdge UndirEdge;
1.251 +
1.252 + typedef _ReaderTraits ReaderTraits;
1.253 + typedef typename ReaderTraits::Skipper DefaultSkipper;
1.254 +
1.255 + /// \brief Construct a new UndirGraphReader.
1.256 + ///
1.257 + /// Construct a new UndirGraphReader. It reads into the given graph
1.258 + /// and it use the given reader as the default skipper.
1.259 + UndirGraphReader(std::istream& _is, Graph& _graph,
1.260 + const DefaultSkipper& _skipper = DefaultSkipper())
1.261 + : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
1.262 + nodeset_reader(*reader, _graph, std::string(), skipper),
1.263 + undir_edgeset_reader(*reader, _graph, nodeset_reader,
1.264 + std::string(), skipper),
1.265 + node_reader(*reader, nodeset_reader, std::string()),
1.266 + undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
1.267 + attribute_reader(*reader, std::string()) {}
1.268 +
1.269 + /// \brief Construct a new UndirGraphReader.
1.270 + ///
1.271 + /// Construct a new UndirGraphReader. It reads into the given graph
1.272 + /// and it use the given reader as the default skipper.
1.273 + UndirGraphReader(const std::string& _filename, Graph& _graph,
1.274 + const DefaultSkipper& _skipper = DefaultSkipper())
1.275 + : reader(new LemonReader(_filename)), own_reader(true),
1.276 + skipper(_skipper),
1.277 + nodeset_reader(*reader, _graph, std::string(), skipper),
1.278 + undir_edgeset_reader(*reader, _graph, nodeset_reader,
1.279 + std::string(), skipper),
1.280 + node_reader(*reader, nodeset_reader, std::string()),
1.281 + undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
1.282 + attribute_reader(*reader, std::string()) {}
1.283 +
1.284 + /// \brief Construct a new UndirGraphReader.
1.285 + ///
1.286 + /// Construct a new UndirGraphReader. It reads into the given graph
1.287 + /// and it use the given reader as the default skipper.
1.288 + UndirGraphReader(LemonReader& _reader, Graph& _graph,
1.289 + const DefaultSkipper& _skipper = DefaultSkipper())
1.290 + : reader(_reader), own_reader(false), skipper(_skipper),
1.291 + nodeset_reader(*reader, _graph, std::string(), skipper),
1.292 + undir_edgeset_reader(*reader, _graph, nodeset_reader,
1.293 + std::string(), skipper),
1.294 + node_reader(*reader, nodeset_reader, std::string()),
1.295 + undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
1.296 + attribute_reader(*reader, std::string()) {}
1.297 +
1.298 + /// \brief Destruct the graph reader.
1.299 + ///
1.300 + /// Destruct the graph reader.
1.301 + ~UndirGraphReader() {
1.302 + if (own_reader)
1.303 + delete reader;
1.304 + }
1.305 +
1.306 + /// \brief Add a new node map reader command for the reader.
1.307 + ///
1.308 + /// Add a new node map reader command for the reader.
1.309 + template <typename Map>
1.310 + UndirGraphReader& readNodeMap(std::string name, Map& map) {
1.311 + nodeset_reader.readNodeMap(name, map);
1.312 + return *this;
1.313 + }
1.314 +
1.315 + template <typename Map>
1.316 + UndirGraphReader& readNodeMap(std::string name, const Map& map) {
1.317 + nodeset_reader.readNodeMap(name, map);
1.318 + return *this;
1.319 + }
1.320 +
1.321 + /// \brief Add a new node map reader command for the reader.
1.322 + ///
1.323 + /// Add a new node map reader command for the reader.
1.324 + template <typename Reader, typename Map>
1.325 + UndirGraphReader& readNodeMap(std::string name, Map& map,
1.326 + const Reader& reader = Reader()) {
1.327 + nodeset_reader.readNodeMap(name, map, reader);
1.328 + return *this;
1.329 + }
1.330 +
1.331 + template <typename Reader, typename Map>
1.332 + UndirGraphReader& readNodeMap(std::string name, const Map& map,
1.333 + const Reader& reader = Reader()) {
1.334 + nodeset_reader.readNodeMap(name, map, reader);
1.335 + return *this;
1.336 + }
1.337 +
1.338 + /// \brief Add a new node map skipper command for the reader.
1.339 + ///
1.340 + /// Add a new node map skipper command for the reader.
1.341 + template <typename Reader>
1.342 + UndirGraphReader& skipNodeMap(std::string name,
1.343 + const Reader& reader = Reader()) {
1.344 + nodeset_reader.skipNodeMap(name, reader);
1.345 + return *this;
1.346 + }
1.347 +
1.348 + /// \brief Add a new undirected edge map reader command for the reader.
1.349 + ///
1.350 + /// Add a new undirected edge map reader command for the reader.
1.351 + template <typename Map>
1.352 + UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
1.353 + undir_edgeset_reader.readUndirEdgeMap(name, map);
1.354 + return *this;
1.355 + }
1.356 +
1.357 + template <typename Map>
1.358 + UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
1.359 + undir_edgeset_reader.readUndirEdgeMap(name, map);
1.360 + return *this;
1.361 + }
1.362 +
1.363 +
1.364 + /// \brief Add a new undirected edge map reader command for the reader.
1.365 + ///
1.366 + /// Add a new undirected edge map reader command for the reader.
1.367 + template <typename Reader, typename Map>
1.368 + UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
1.369 + const Reader& reader = Reader()) {
1.370 + undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
1.371 + return *this;
1.372 + }
1.373 +
1.374 + template <typename Reader, typename Map>
1.375 + UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
1.376 + const Reader& reader = Reader()) {
1.377 + undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
1.378 + return *this;
1.379 + }
1.380 +
1.381 + /// \brief Add a new undirected edge map skipper command for the reader.
1.382 + ///
1.383 + /// Add a new undirected edge map skipper command for the reader.
1.384 + template <typename Reader>
1.385 + UndirGraphReader& skipUndirEdgeMap(std::string name,
1.386 + const Reader& reader = Reader()) {
1.387 + undir_edgeset_reader.skipUndirMap(name, reader);
1.388 + return *this;
1.389 + }
1.390 +
1.391 +
1.392 + /// \brief Add a new edge map reader command for the reader.
1.393 + ///
1.394 + /// Add a new edge map reader command for the reader.
1.395 + template <typename Map>
1.396 + UndirGraphReader& readEdgeMap(std::string name, Map& map) {
1.397 + undir_edgeset_reader.readEdgeMap(name, map);
1.398 + return *this;
1.399 + }
1.400 +
1.401 + template <typename Map>
1.402 + UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
1.403 + undir_edgeset_reader.readEdgeMap(name, map);
1.404 + return *this;
1.405 + }
1.406 +
1.407 +
1.408 + /// \brief Add a new edge map reader command for the reader.
1.409 + ///
1.410 + /// Add a new edge map reader command for the reader.
1.411 + template <typename Reader, typename Map>
1.412 + UndirGraphReader& readEdgeMap(std::string name, Map& map,
1.413 + const Reader& reader = Reader()) {
1.414 + undir_edgeset_reader.readEdgeMap(name, map, reader);
1.415 + return *this;
1.416 + }
1.417 +
1.418 + template <typename Reader, typename Map>
1.419 + UndirGraphReader& readEdgeMap(std::string name, const Map& map,
1.420 + const Reader& reader = Reader()) {
1.421 + undir_edgeset_reader.readEdgeMap(name, map, reader);
1.422 + return *this;
1.423 + }
1.424 +
1.425 + /// \brief Add a new edge map skipper command for the reader.
1.426 + ///
1.427 + /// Add a new edge map skipper command for the reader.
1.428 + template <typename Reader>
1.429 + UndirGraphReader& skipEdgeMap(std::string name,
1.430 + const Reader& reader = Reader()) {
1.431 + undir_edgeset_reader.skipEdgeMap(name, reader);
1.432 + return *this;
1.433 + }
1.434 +
1.435 + /// \brief Add a new labeled node reader for the reader.
1.436 + ///
1.437 + /// Add a new labeled node reader for the reader.
1.438 + UndirGraphReader& readNode(std::string name, Node& node) {
1.439 + node_reader.readNode(name, node);
1.440 + return *this;
1.441 + }
1.442 +
1.443 + /// \brief Add a new labeled edge reader for the reader.
1.444 + ///
1.445 + /// Add a new labeled edge reader for the reader.
1.446 + UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
1.447 + undir_edge_reader.readUndirEdge(name, edge);
1.448 + }
1.449 +
1.450 + /// \brief Add a new attribute reader command.
1.451 + ///
1.452 + /// Add a new attribute reader command.
1.453 + template <typename Value>
1.454 + UndirGraphReader& readAttribute(std::string name, Value& value) {
1.455 + attribute_reader.readAttribute(name, value);
1.456 + return *this;
1.457 + }
1.458 +
1.459 + /// \brief Add a new attribute reader command.
1.460 + ///
1.461 + /// Add a new attribute reader command.
1.462 + template <typename Reader, typename Value>
1.463 + UndirGraphReader& readAttribute(std::string name, Value& value,
1.464 + const Reader& reader) {
1.465 + attribute_reader.readAttribute<Reader>(name, value, reader);
1.466 + return *this;
1.467 + }
1.468 +
1.469 + /// \brief Conversion operator to LemonReader.
1.470 + ///
1.471 + /// Conversion operator to LemonReader. It make possible
1.472 + /// to access the encapsulated \e LemonReader, this way
1.473 + /// you can attach to this reader new instances of
1.474 + /// \e LemonReader::SectionReader.
1.475 + operator LemonReader&() {
1.476 + return *reader;
1.477 + }
1.478 +
1.479 + /// \brief Executes the reader commands.
1.480 + ///
1.481 + /// Executes the reader commands.
1.482 + void run() {
1.483 + reader->run();
1.484 + }
1.485 +
1.486 + private:
1.487 +
1.488 + LemonReader* reader;
1.489 + bool own_reader;
1.490 +
1.491 + DefaultSkipper skipper;
1.492 +
1.493 + NodeSetReader<Graph, ReaderTraits> nodeset_reader;
1.494 + UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
1.495 +
1.496 + NodeReader<Graph> node_reader;
1.497 + UndirEdgeReader<Graph> undir_edge_reader;
1.498 +
1.499 + AttributeReader<ReaderTraits> attribute_reader;
1.500 + };
1.501 +
1.502 + /// \brief Read an undir graph from the input.
1.503 + ///
1.504 + /// Read an undir graph from the input.
1.505 + /// \param is The input stream.
1.506 + /// \param g The graph.
1.507 + /// \param capacity The capacity map.
1.508 + template<typename Graph, typename CapacityMap>
1.509 + void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
1.510 + UndirGraphReader<Graph> reader(is, g);
1.511 + reader.readUndirEdgeMap("capacity", capacity);
1.512 + reader.run();
1.513 + }
1.514 +
1.515 + /// \brief Read an undir graph from the input.
1.516 + ///
1.517 + /// Read an undir graph from the input.
1.518 + /// \param is The input stream.
1.519 + /// \param g The graph.
1.520 + template<typename Graph>
1.521 + void readUndirGraph(std::istream& is, Graph &g) {
1.522 + UndirGraphReader<Graph> reader(is, g);
1.523 + reader.run();
1.524 + }
1.525 +
1.526 /// @}
1.527 }
1.528
2.1 --- a/src/lemon/graph_writer.h Sat May 14 17:37:33 2005 +0000
2.2 +++ b/src/lemon/graph_writer.h Sat May 14 17:39:37 2005 +0000
2.3 @@ -52,8 +52,7 @@
2.4 /// IdMap<ListGraph, Node> nodeIdMap;
2.5 /// writer.writeNodeMap("id", nodeIdMap);
2.6 ///
2.7 - /// writer.writeNodeMap("x-coord", xCoordMap);
2.8 - /// writer.writeNodeMap("y-coord", yCoordMap);
2.9 + /// writer.writeNodeMap("coords", coords);
2.10 /// writer.writeNodeMap("color", colorMap);
2.11 /// \endcode
2.12 ///
2.13 @@ -91,7 +90,7 @@
2.14 /// \see QuotedStringWriter
2.15 /// \see IdMap
2.16 /// \see DescriptorMap
2.17 - /// \see \ref GraphWriter
2.18 + /// \see \ref GraphReader
2.19 /// \see \ref graph-io-page
2.20 /// \author Balazs Dezso
2.21 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
2.22 @@ -110,9 +109,8 @@
2.23 /// to the given stream.
2.24 GraphWriter(std::ostream& _os, const Graph& _graph)
2.25 : writer(new LemonWriter(_os)), own_writer(true),
2.26 - graph(_graph),
2.27 - nodeset_writer(*writer, graph, std::string()),
2.28 - edgeset_writer(*writer, graph, nodeset_writer, std::string()),
2.29 + nodeset_writer(*writer, _graph, std::string()),
2.30 + edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
2.31 node_writer(*writer, nodeset_writer, std::string()),
2.32 edge_writer(*writer, edgeset_writer, std::string()),
2.33 attribute_writer(*writer, std::string()) {}
2.34 @@ -123,9 +121,8 @@
2.35 /// to the given file.
2.36 GraphWriter(const std::string& _filename, const Graph& _graph)
2.37 : writer(new LemonWriter(_filename)), own_writer(true),
2.38 - graph(_graph),
2.39 - nodeset_writer(*writer, graph, std::string()),
2.40 - edgeset_writer(*writer, graph, nodeset_writer, std::string()),
2.41 + nodeset_writer(*writer, _graph, std::string()),
2.42 + edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
2.43 node_writer(*writer, nodeset_writer, std::string()),
2.44 edge_writer(*writer, edgeset_writer, std::string()),
2.45 attribute_writer(*writer, std::string()) {}
2.46 @@ -136,9 +133,8 @@
2.47 /// to given LemonReader.
2.48 GraphWriter(LemonWriter& _writer, const Graph& _graph)
2.49 : writer(_writer), own_writer(false),
2.50 - graph(_graph),
2.51 - nodeset_writer(*writer, graph, std::string()),
2.52 - edgeset_writer(*writer, graph, nodeset_writer, std::string()),
2.53 + nodeset_writer(*writer, _graph, std::string()),
2.54 + edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
2.55 node_writer(*writer, nodeset_writer, std::string()),
2.56 edge_writer(*writer, edgeset_writer, std::string()),
2.57 attribute_writer(*writer, std::string()) {}
2.58 @@ -156,7 +152,7 @@
2.59 /// Add a new node map writer command for the writer.
2.60 template <typename Map>
2.61 GraphWriter& writeNodeMap(std::string name, const Map& map) {
2.62 - nodeset_writer.writeMap(name, map);
2.63 + nodeset_writer.writeNodeMap(name, map);
2.64 return *this;
2.65 }
2.66
2.67 @@ -165,8 +161,8 @@
2.68 /// Add a new node map writer command for the writer.
2.69 template <typename Writer, typename Map>
2.70 GraphWriter& writeNodeMap(std::string name, const Map& map,
2.71 - const Writer& writer = Writer()) {
2.72 - nodeset_writer.writeMap(name, map, writer);
2.73 + const Writer& writer = Writer()) {
2.74 + nodeset_writer.writeNodeMap(name, map, writer);
2.75 return *this;
2.76 }
2.77
2.78 @@ -176,7 +172,7 @@
2.79 /// Add a new edge map writer command for the writer.
2.80 template <typename Map>
2.81 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
2.82 - edgeset_writer.writeMap(name, map);
2.83 + edgeset_writer.writeEdgeMap(name, map);
2.84 return *this;
2.85 }
2.86
2.87 @@ -186,8 +182,8 @@
2.88 /// Add a new edge map writer command for the writer.
2.89 template <typename Writer, typename Map>
2.90 GraphWriter& writeEdgeMap(std::string name, const Map& map,
2.91 - const Writer& writer = Writer()) {
2.92 - edgeset_writer.writeMap(name, map, writer);
2.93 + const Writer& writer = Writer()) {
2.94 + edgeset_writer.writeEdgeMap(name, map, writer);
2.95 return *this;
2.96 }
2.97
2.98 @@ -247,8 +243,6 @@
2.99 LemonWriter* writer;
2.100 bool own_writer;
2.101
2.102 - const Graph& graph;
2.103 -
2.104 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
2.105 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
2.106
2.107 @@ -360,6 +354,279 @@
2.108 writer.run();
2.109 }
2.110
2.111 + /// \brief The undirected graph writer class.
2.112 + ///
2.113 + /// The \c UndirGraphWriter class provides the undir graph output. To write
2.114 + /// a graph you should first give writing commands for the writer. You can
2.115 + /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap
2.116 + /// writing and labeled Node, Edge or UndirEdge writing.
2.117 + ///
2.118 + /// \code
2.119 + /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
2.120 + /// \endcode
2.121 + ///
2.122 + /// The \c writeNodeMap() function declares a \c NodeMap writing
2.123 + /// command in the \c UndirGraphWriter. You should give as parameter
2.124 + /// the name of the map and the map object. The NodeMap writing
2.125 + /// command with name "id" should write a unique map because it
2.126 + /// is regarded as ID map.
2.127 + ///
2.128 + /// \code
2.129 + /// IdMap<UndirListGraph, Node> nodeIdMap;
2.130 + /// writer.writeNodeMap("id", nodeIdMap);
2.131 + ///
2.132 + /// writer.writeNodeMap("coords", coords);
2.133 + /// writer.writeNodeMap("color", colorMap);
2.134 + /// \endcode
2.135 + ///
2.136 + /// With the \c writeUndirEdgeMap() member function you can give an
2.137 + /// undirected edge map writing command similar to the NodeMaps.
2.138 + ///
2.139 + /// \code
2.140 + /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
2.141 + /// edgeDescMap(graph);
2.142 + /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
2.143 + ///
2.144 + /// writer.writeUndirEdgeMap("weight", weightMap);
2.145 + /// writer.writeUndirEdgeMap("label", labelMap);
2.146 + /// \endcode
2.147 + ///
2.148 + /// The EdgeMap handling is just a syntactical sugar. It writes
2.149 + /// two undirected edge map with '+' and '-' prefix in the name.
2.150 + ///
2.151 + /// \code
2.152 + /// writer.writeEdgeMap("capacity", capacityMap);
2.153 + /// \endcode
2.154 + ///
2.155 + ///
2.156 + /// With \c writeNode() and \c writeUndirEdge() functions you can
2.157 + /// point out nodes and undirected edges in the graph. By example, you can
2.158 + /// write out the source and target of the graph.
2.159 + ///
2.160 + /// \code
2.161 + /// writer.writeNode("source", sourceNode);
2.162 + /// writer.writeNode("target", targetNode);
2.163 + ///
2.164 + /// writer.writeUndirEdge("observed", undirEdge);
2.165 + /// \endcode
2.166 + ///
2.167 + /// After you give all write commands you must call the \c run() member
2.168 + /// function, which execute all the writer commands.
2.169 + ///
2.170 + /// \code
2.171 + /// writer.run();
2.172 + /// \endcode
2.173 + ///
2.174 + /// \see DefaultWriterTraits
2.175 + /// \see QuotedStringWriter
2.176 + /// \see IdMap
2.177 + /// \see DescriptorMap
2.178 + /// \see \ref GraphWriter
2.179 + /// \see \ref graph-io-page
2.180 + /// \author Balazs Dezso
2.181 + template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
2.182 + class UndirGraphWriter {
2.183 + public:
2.184 +
2.185 + typedef _Graph Graph;
2.186 + typedef typename Graph::Node Node;
2.187 + typedef typename Graph::Edge Edge;
2.188 + typedef typename Graph::UndirEdge UndirEdge;
2.189 +
2.190 + typedef _WriterTraits WriterTraits;
2.191 +
2.192 + /// \brief Construct a new UndirGraphWriter.
2.193 + ///
2.194 + /// Construct a new UndirGraphWriter. It writes the given graph
2.195 + /// to the given stream.
2.196 + UndirGraphWriter(std::ostream& _os, const Graph& _graph)
2.197 + : writer(new LemonWriter(_os)), own_writer(true),
2.198 + nodeset_writer(*writer, _graph, std::string()),
2.199 + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
2.200 + node_writer(*writer, nodeset_writer, std::string()),
2.201 + undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
2.202 + attribute_writer(*writer, std::string()) {}
2.203 +
2.204 + /// \brief Construct a new UndirGraphWriter.
2.205 + ///
2.206 + /// Construct a new UndirGraphWriter. It writes into the given graph
2.207 + /// to the given file.
2.208 + UndirGraphWriter(const std::string& _filename, const Graph& _graph)
2.209 + : writer(new LemonWriter(_filename)), own_writer(true),
2.210 + nodeset_writer(*writer, _graph, std::string()),
2.211 + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
2.212 + node_writer(*writer, nodeset_writer, std::string()),
2.213 + undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
2.214 + attribute_writer(*writer, std::string()) {}
2.215 +
2.216 + /// \brief Construct a new UndirGraphWriter.
2.217 + ///
2.218 + /// Construct a new UndirGraphWriter. It writes into the given graph
2.219 + /// to given LemonReader.
2.220 + UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
2.221 + : writer(_writer), own_writer(false),
2.222 + nodeset_writer(*writer, _graph, std::string()),
2.223 + undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
2.224 + node_writer(*writer, nodeset_writer, std::string()),
2.225 + undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
2.226 + attribute_writer(*writer, std::string()) {}
2.227 +
2.228 + /// \brief Destruct the graph writer.
2.229 + ///
2.230 + /// Destruct the graph writer.
2.231 + ~UndirGraphWriter() {
2.232 + if (own_writer)
2.233 + delete writer;
2.234 + }
2.235 +
2.236 + /// \brief Add a new node map writer command for the writer.
2.237 + ///
2.238 + /// Add a new node map writer command for the writer.
2.239 + template <typename Map>
2.240 + UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
2.241 + nodeset_writer.writeNodeMap(name, map);
2.242 + return *this;
2.243 + }
2.244 +
2.245 + /// \brief Add a new node map writer command for the writer.
2.246 + ///
2.247 + /// Add a new node map writer command for the writer.
2.248 + template <typename Writer, typename Map>
2.249 + UndirGraphWriter& writeNodeMap(std::string name, const Map& map,
2.250 + const Writer& writer = Writer()) {
2.251 + nodeset_writer.writeNodeMap(name, map, writer);
2.252 + return *this;
2.253 + }
2.254 +
2.255 + /// \brief Add a new edge map writer command for the writer.
2.256 + ///
2.257 + /// Add a new edge map writer command for the writer.
2.258 + template <typename Map>
2.259 + UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) {
2.260 + undir_edgeset_writer.writeEdgeMap(name, map);
2.261 + return *this;
2.262 + }
2.263 +
2.264 + /// \brief Add a new edge map writer command for the writer.
2.265 + ///
2.266 + /// Add a new edge map writer command for the writer.
2.267 + template <typename Writer, typename Map>
2.268 + UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
2.269 + const Writer& writer = Writer()) {
2.270 + undir_edgeset_writer.writeEdgeMap(name, map, writer);
2.271 + return *this;
2.272 + }
2.273 +
2.274 + /// \brief Add a new undirected edge map writer command for the writer.
2.275 + ///
2.276 + /// Add a new undirected edge map writer command for the writer.
2.277 + template <typename Map>
2.278 + UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) {
2.279 + undir_edgeset_writer.writeUndirEdgeMap(name, map);
2.280 + return *this;
2.281 + }
2.282 +
2.283 + /// \brief Add a new undirected edge map writer command for the writer.
2.284 + ///
2.285 + /// Add a new edge undirected map writer command for the writer.
2.286 + template <typename Writer, typename Map>
2.287 + UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
2.288 + const Writer& writer = Writer()) {
2.289 + undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
2.290 + return *this;
2.291 + }
2.292 +
2.293 + /// \brief Add a new labeled node writer for the writer.
2.294 + ///
2.295 + /// Add a new labeled node writer for the writer.
2.296 + UndirGraphWriter& writeNode(std::string name, const Node& node) {
2.297 + node_writer.writeNode(name, node);
2.298 + return *this;
2.299 + }
2.300 +
2.301 + /// \brief Add a new labeled edge writer for the writer.
2.302 + ///
2.303 + /// Add a new labeled edge writer for the writer.
2.304 + UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
2.305 + undir_edge_writer.writeUndirEdge(name, edge);
2.306 + }
2.307 +
2.308 + /// \brief Add a new attribute writer command.
2.309 + ///
2.310 + /// Add a new attribute writer command.
2.311 + template <typename Value>
2.312 + UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
2.313 + attribute_writer.writeAttribute(name, value);
2.314 + return *this;
2.315 + }
2.316 +
2.317 + /// \brief Add a new attribute writer command.
2.318 + ///
2.319 + /// Add a new attribute writer command.
2.320 + template <typename Writer, typename Value>
2.321 + UndirGraphWriter& writeAttribute(std::string name, const Value& value,
2.322 + const Writer& writer) {
2.323 + attribute_writer.writeAttribute<Writer>(name, value, writer);
2.324 + return *this;
2.325 + }
2.326 +
2.327 + /// \brief Conversion operator to LemonWriter.
2.328 + ///
2.329 + /// Conversion operator to LemonWriter. It make possible
2.330 + /// to access the encapsulated \e LemonWriter, this way
2.331 + /// you can attach to this writer new instances of
2.332 + /// \e LemonWriter::SectionWriter.
2.333 + operator LemonWriter&() {
2.334 + return *writer;
2.335 + }
2.336 +
2.337 + /// \brief Executes the writer commands.
2.338 + ///
2.339 + /// Executes the writer commands.
2.340 + void run() {
2.341 + writer->run();
2.342 + }
2.343 +
2.344 + private:
2.345 +
2.346 + LemonWriter* writer;
2.347 + bool own_writer;
2.348 +
2.349 + NodeSetWriter<Graph, WriterTraits> nodeset_writer;
2.350 + UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
2.351 +
2.352 + NodeWriter<Graph> node_writer;
2.353 + UndirEdgeWriter<Graph> undir_edge_writer;
2.354 +
2.355 + AttributeWriter<WriterTraits> attribute_writer;
2.356 + };
2.357 +
2.358 +
2.359 + /// \brief Write an undirected graph to the output.
2.360 + ///
2.361 + /// Write an undirected graph to the output.
2.362 + /// \param os The output stream.
2.363 + /// \param g The graph.
2.364 + /// \param capacity The capacity undirected map.
2.365 + template<typename Graph, typename CapacityMap>
2.366 + void writeUndirGraph(std::ostream& os, const Graph &g,
2.367 + const CapacityMap& capacity) {
2.368 + UndirGraphWriter<Graph> writer(os, g);
2.369 + writer.writeUndirEdgeMap("capacity", capacity);
2.370 + writer.run();
2.371 + }
2.372 +
2.373 + /// \brief Write an undirected graph to the output.
2.374 + ///
2.375 + /// Write an undirected graph to the output.
2.376 + /// \param os The output stream.
2.377 + /// \param g The graph.
2.378 + template<typename Graph>
2.379 + void writeUndirGraph(std::ostream& os, const Graph &g) {
2.380 + UndirGraphWriter<Graph> writer(os, g);
2.381 + writer.run();
2.382 + }
2.383 +
2.384 /// @}
2.385
2.386 }
3.1 --- a/src/lemon/lemon_reader.h Sat May 14 17:37:33 2005 +0000
3.2 +++ b/src/lemon/lemon_reader.h Sat May 14 17:39:37 2005 +0000
3.3 @@ -18,9 +18,11 @@
3.4 ///\file
3.5 ///\brief Lemon Format reader.
3.6
3.7 +
3.8 #ifndef LEMON_LEMON_READER_H
3.9 #define LEMON_LEMON_READER_H
3.10
3.11 +
3.12 #include <iostream>
3.13 #include <fstream>
3.14 #include <string>
3.15 @@ -30,11 +32,61 @@
3.16 #include <memory>
3.17
3.18 #include <lemon/error.h>
3.19 +#include <lemon/graph_utils.h>
3.20 +#include <lemon/utility.h>
3.21 #include <lemon/bits/item_reader.h>
3.22
3.23
3.24 namespace lemon {
3.25
3.26 + namespace _reader_bits {
3.27 +
3.28 + template <typename T>
3.29 + bool operator<(T, T) {
3.30 + throw DataFormatError("Id is not comparable");
3.31 + }
3.32 +
3.33 + template <typename T>
3.34 + struct Less {
3.35 + bool operator()(const T& p, const T& q) const {
3.36 + return p < q;
3.37 + }
3.38 + };
3.39 +
3.40 + template <typename M1, typename M2>
3.41 + class WriteComposeMap {
3.42 + public:
3.43 + typedef True NeedCopy;
3.44 +
3.45 + typedef typename M2::Key Key;
3.46 + typedef typename M1::Value Value;
3.47 +
3.48 + WriteComposeMap(typename SmartParameter<M1>::Type _m1, const M2& _m2)
3.49 + : m1(_m1), m2(_m2) {}
3.50 +
3.51 + void set(const Key& key, const Value& value) {
3.52 + m1.set(m2[key], value);
3.53 + }
3.54 +
3.55 + private:
3.56 +
3.57 + typename SmartReference<M1>::Type m1;
3.58 + typename SmartConstReference<M2>::Type m2;
3.59 +
3.60 + };
3.61 +
3.62 + template <typename M1, typename M2>
3.63 + WriteComposeMap<M1, M2> writeComposeMap(M1& m1, const M2& m2) {
3.64 + return WriteComposeMap<M1, M2>(m1, m2);
3.65 + }
3.66 +
3.67 + template <typename M1, typename M2>
3.68 + WriteComposeMap<M1, M2> writeComposeMap(const M1& m1, const M2& m2) {
3.69 + return WriteComposeMap<M1, M2>(m1, m2);
3.70 + }
3.71 +
3.72 + }
3.73 +
3.74 /// \ingroup io_group
3.75 /// \brief Lemon Format reader class.
3.76 ///
3.77 @@ -338,8 +390,6 @@
3.78 virtual InverterBase<_Item>* getInverter() {
3.79 return this;
3.80 }
3.81 -
3.82 -
3.83 };
3.84
3.85 template <typename _Item, typename _Map, typename _Reader>
3.86 @@ -349,13 +399,15 @@
3.87 typedef _Reader Reader;
3.88 typedef typename Reader::Value Value;
3.89 typedef _Map Map;
3.90 - typedef std::map<Value, Item> Inverse;
3.91 + typedef std::map<Value, Item,
3.92 + typename _reader_bits::template Less<Value> > Inverse;
3.93
3.94 - Map& map;
3.95 + typename SmartReference<Map>::Type map;
3.96 Reader reader;
3.97 Inverse inverse;
3.98
3.99 - MapReaderInverter(Map& _map, const Reader& _reader)
3.100 + MapReaderInverter(typename SmartParameter<Map>::Type _map,
3.101 + const Reader& _reader)
3.102 : map(_map), reader(_reader) {}
3.103
3.104 virtual ~MapReaderInverter() {}
3.105 @@ -382,7 +434,6 @@
3.106 throw DataFormatError("Invalid ID error");
3.107 }
3.108 }
3.109 -
3.110 };
3.111
3.112 template <typename _Item, typename _Reader>
3.113 @@ -391,7 +442,8 @@
3.114 typedef _Item Item;
3.115 typedef _Reader Reader;
3.116 typedef typename Reader::Value Value;
3.117 - typedef std::map<Value, Item> Inverse;
3.118 + typedef std::map<Value, Item,
3.119 + typename _reader_bits::template Less<Value> > Inverse;
3.120
3.121 Reader reader;
3.122
3.123 @@ -426,8 +478,6 @@
3.124 Inverse inverse;
3.125 };
3.126
3.127 - // Readers
3.128 -
3.129 template <typename _Item>
3.130 class ReaderBase {
3.131 public:
3.132 @@ -447,10 +497,11 @@
3.133 typedef typename Reader::Value Value;
3.134 typedef _Item Item;
3.135
3.136 - Map& map;
3.137 + typename SmartReference<Map>::Type map;
3.138 Reader reader;
3.139
3.140 - MapReader(Map& _map, const Reader& _reader)
3.141 + MapReader(typename SmartParameter<Map>::Type _map,
3.142 + const Reader& _reader)
3.143 : map(_map), reader(_reader) {}
3.144
3.145 virtual ~MapReader() {}
3.146 @@ -569,7 +620,8 @@
3.147 /// attach it into the given LemonReader. The nodeset reader will
3.148 /// add the readed nodes to the given Graph. The reader will read
3.149 /// the section when the \c section_id and the \c _id are the same.
3.150 - NodeSetReader(LemonReader& _reader, Graph& _graph,
3.151 + NodeSetReader(LemonReader& _reader,
3.152 + typename SmartParameter<Graph>::Type _graph,
3.153 const std::string& _id = std::string(),
3.154 const DefaultSkipper& _skipper = DefaultSkipper())
3.155 : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {}
3.156 @@ -595,17 +647,43 @@
3.157 ///
3.158 /// Add a new node map reader command for the reader.
3.159 template <typename Map>
3.160 - NodeSetReader& readMap(std::string name, Map& map) {
3.161 - return readMap<typename Traits::
3.162 - template Reader<typename Map::Value>, Map>(name, map);
3.163 + NodeSetReader& readNodeMap(std::string name, Map& map) {
3.164 + return _readMap<
3.165 + typename Traits::template Reader<typename Map::Value>, Map,
3.166 + typename SmartParameter<Map>::Type>(name, map);
3.167 + }
3.168 +
3.169 + template <typename Map>
3.170 + NodeSetReader& readNodeMap(std::string name, const Map& map) {
3.171 + return _readMap<
3.172 + typename Traits::template Reader<typename Map::Value>, Map,
3.173 + typename SmartParameter<Map>::Type>(name, map);
3.174 }
3.175
3.176 /// \brief Add a new node map reader command for the reader.
3.177 ///
3.178 /// Add a new node map reader command for the reader.
3.179 template <typename Reader, typename Map>
3.180 - NodeSetReader& readMap(std::string name, Map& map,
3.181 - const Reader& reader = Reader()) {
3.182 + NodeSetReader& readNodeMap(std::string name, Map& map,
3.183 + const Reader& reader = Reader()) {
3.184 + return _readMap<
3.185 + typename Traits::template Reader<typename Map::Value>, Map,
3.186 + typename SmartParameter<Map>::Type>(name, map, reader);
3.187 + }
3.188 +
3.189 + template <typename Reader, typename Map>
3.190 + NodeSetReader& readNodeMap(std::string name, const Map& map,
3.191 + const Reader& reader = Reader()) {
3.192 + return _readMap<
3.193 + typename Traits::template Reader<typename Map::Value>, Map,
3.194 + typename SmartParameter<Map>::Type>(name, map, reader);
3.195 + }
3.196 +
3.197 + private:
3.198 +
3.199 + template <typename Reader, typename Map, typename MapParameter>
3.200 + NodeSetReader& _readMap(std::string name, MapParameter map,
3.201 + const Reader& reader = Reader()) {
3.202 if (readers.find(name) != readers.end()) {
3.203 ErrorMessage msg;
3.204 msg << "Multiple read rule for node map: " << name;
3.205 @@ -616,11 +694,13 @@
3.206 return *this;
3.207 }
3.208
3.209 + public:
3.210 +
3.211 /// \brief Add a new node map skipper command for the reader.
3.212 ///
3.213 /// Add a new node map skipper command for the reader.
3.214 template <typename Reader>
3.215 - NodeSetReader& skipMap(std::string name,
3.216 + NodeSetReader& skipNodeMap(std::string name,
3.217 const Reader& reader = Reader()) {
3.218 if (readers.find(name) != readers.end()) {
3.219 ErrorMessage msg;
3.220 @@ -636,7 +716,7 @@
3.221 /// \brief Gives back true when the SectionReader can process
3.222 /// the section with the given header line.
3.223 ///
3.224 - /// It gives back true when the header line starts with \c @nodeset,
3.225 + /// It gives back true when the header line starts with \c \@nodeset,
3.226 /// and the header line's id and the nodeset's id are the same.
3.227 virtual bool header(const std::string& line) {
3.228 std::istringstream ls(line);
3.229 @@ -690,7 +770,7 @@
3.230 ///
3.231 /// It reads an id from the stream and gives back which node belongs to
3.232 /// it. It is possible only if there was read an "id" named map.
3.233 - typename Graph::Node readId(std::istream& is) const {
3.234 + Item readId(std::istream& is) const {
3.235 return inverter->read(is);
3.236 }
3.237
3.238 @@ -699,7 +779,7 @@
3.239 typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
3.240 MapReaders readers;
3.241
3.242 - Graph& graph;
3.243 + typename SmartReference<Graph>::Type graph;
3.244 std::string id;
3.245 SkipReader<Item, DefaultSkipper> skipper;
3.246
3.247 @@ -714,8 +794,9 @@
3.248 /// \c edgeset_id may be empty.
3.249 ///
3.250 /// The first line of the section contains the names of the maps separated
3.251 - /// with white spaces. Each next lines describes a node in the nodeset. The
3.252 - /// line contains the two nodes' id and the mapped values for each map.
3.253 + /// with white spaces. Each next lines describes an edge in the edgeset. The
3.254 + /// line contains the source and the target nodes' id and the mapped
3.255 + /// values for each map.
3.256 ///
3.257 /// If the edgeset contains an \c "id" named map then it will be regarded
3.258 /// as id map. This map should contain only unique values and when the
3.259 @@ -746,7 +827,8 @@
3.260 /// The reader will read the section only if the \c _id and the
3.261 /// \c edgset_id are the same.
3.262 template <typename NodeIdReader>
3.263 - EdgeSetReader(LemonReader& _reader, Graph& _graph,
3.264 + EdgeSetReader(LemonReader& _reader,
3.265 + typename SmartParameter<Graph>::Type _graph,
3.266 const NodeIdReader& _nodeIdReader,
3.267 const std::string& _id = std::string(),
3.268 const DefaultSkipper& _skipper = DefaultSkipper())
3.269 @@ -774,17 +856,43 @@
3.270 ///
3.271 /// Add a new edge map reader command for the reader.
3.272 template <typename Map>
3.273 - EdgeSetReader& readMap(std::string name, Map& map) {
3.274 - return readMap<typename Traits::
3.275 - template Reader<typename Map::Value>, Map>(name, map);
3.276 + EdgeSetReader& readEdgeMap(std::string name, Map& map) {
3.277 + return _readMap<
3.278 + typename Traits::template Reader<typename Map::Value>, Map,
3.279 + typename SmartParameter<Map>::Type>(name, map);
3.280 + }
3.281 +
3.282 + template <typename Map>
3.283 + EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
3.284 + return _readMap<
3.285 + typename Traits::template Reader<typename Map::Value>, Map,
3.286 + typename SmartParameter<Map>::Type>(name, map);
3.287 }
3.288
3.289 /// \brief Add a new edge map reader command for the reader.
3.290 ///
3.291 /// Add a new edge map reader command for the reader.
3.292 template <typename Reader, typename Map>
3.293 - EdgeSetReader& readMap(std::string name, Map& map,
3.294 - const Reader& reader = Reader()) {
3.295 + EdgeSetReader& readEdgeMap(std::string name, Map& map,
3.296 + const Reader& reader = Reader()) {
3.297 + return _readMap<
3.298 + typename Traits::template Reader<typename Map::Value>, Map,
3.299 + typename SmartParameter<Map>::Type>(name, map, reader);
3.300 + }
3.301 +
3.302 + template <typename Reader, typename Map>
3.303 + EdgeSetReader& readEdgeMap(std::string name, const Map& map,
3.304 + const Reader& reader = Reader()) {
3.305 + return _readMap<
3.306 + typename Traits::template Reader<typename Map::Value>, Map,
3.307 + typename SmartParameter<Map>::Type>(name, map, reader);
3.308 + }
3.309 +
3.310 + private:
3.311 +
3.312 + template <typename Reader, typename Map, typename MapParameter>
3.313 + EdgeSetReader& _readMap(std::string name, MapParameter map,
3.314 + const Reader& reader = Reader()) {
3.315 if (readers.find(name) != readers.end()) {
3.316 ErrorMessage msg;
3.317 msg << "Multiple read rule for edge map: " << name;
3.318 @@ -795,15 +903,17 @@
3.319 return *this;
3.320 }
3.321
3.322 + public:
3.323 +
3.324 /// \brief Add a new edge map skipper command for the reader.
3.325 ///
3.326 /// Add a new edge map skipper command for the reader.
3.327 template <typename Reader>
3.328 - EdgeSetReader& skipMap(std::string name,
3.329 - const Reader& reader = Reader()) {
3.330 + EdgeSetReader& skipEdgeMap(std::string name,
3.331 + const Reader& reader = Reader()) {
3.332 if (readers.find(name) != readers.end()) {
3.333 ErrorMessage msg;
3.334 - msg << "Multiple read rule for node map: " << name;
3.335 + msg << "Multiple read rule for edge map: " << name;
3.336 throw IOParameterError(msg.message());
3.337 }
3.338 readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
3.339 @@ -815,7 +925,7 @@
3.340 /// \brief Gives back true when the SectionReader can process
3.341 /// the section with the given header line.
3.342 ///
3.343 - /// It gives back true when the header line starts with \c @edgeset,
3.344 + /// It gives back true when the header line starts with \c \@edgeset,
3.345 /// and the header line's id and the edgeset's id are the same.
3.346 virtual bool header(const std::string& line) {
3.347 std::istringstream ls(line);
3.348 @@ -871,7 +981,7 @@
3.349 ///
3.350 /// It reads an id from the stream and gives back which edge belongs to
3.351 /// it. It is possible only if there was read an "id" named map.
3.352 - typename Graph::Edge readId(std::istream& is) const {
3.353 + Item readId(std::istream& is) const {
3.354 return inverter->read(is);
3.355 }
3.356
3.357 @@ -880,7 +990,281 @@
3.358 typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
3.359 MapReaders readers;
3.360
3.361 - Graph& graph;
3.362 + typename SmartReference<Graph>::Type graph;
3.363 + std::string id;
3.364 + SkipReader<Item, DefaultSkipper> skipper;
3.365 +
3.366 + std::auto_ptr<InverterBase<Item> > inverter;
3.367 + std::auto_ptr<IdReaderBase<typename Graph::Node> > nodeIdReader;
3.368 + };
3.369 +
3.370 + /// \ingroup io_group
3.371 + /// \brief SectionReader for reading a undirected graph's edgeset.
3.372 + ///
3.373 + /// The lemon format can store multiple undirected edgesets with several
3.374 + /// maps. The undirected edgeset section's header line is \c \@undiredgeset
3.375 + /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
3.376 + ///
3.377 + /// The first line of the section contains the names of the maps separated
3.378 + /// with white spaces. Each next lines describes an edge in the edgeset. The
3.379 + /// line contains the connected nodes' id and the mapped values for each map.
3.380 + ///
3.381 + /// The section can handle the directed as a syntactical sugar. Two
3.382 + /// undirected edge map describes one directed edge map. This two maps
3.383 + /// are the forward map and the backward map and the names of this map
3.384 + /// is near the same just with a prefix \c '+' or \c '-' character
3.385 + /// difference.
3.386 + ///
3.387 + /// If the edgeset contains an \c "id" named map then it will be regarded
3.388 + /// as id map. This map should contain only unique values and when the
3.389 + /// \c readId() member will read a value from the given stream it will
3.390 + /// give back that undiricted edge which is mapped to this value.
3.391 + ///
3.392 + /// The undirected edgeset reader needs a node id reader to identify which
3.393 + /// nodes have to be connected. If a NodeSetReader reads an "id" named map,
3.394 + /// it will be able to resolve the nodes by ids.
3.395 + ///
3.396 + /// \relates LemonReader
3.397 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
3.398 + class UndirEdgeSetReader : public CommonSectionReaderBase {
3.399 + typedef CommonSectionReaderBase Parent;
3.400 + public:
3.401 +
3.402 + typedef _Graph Graph;
3.403 + typedef _Traits Traits;
3.404 + typedef typename Graph::UndirEdge Item;
3.405 + typedef typename Traits::Skipper DefaultSkipper;
3.406 +
3.407 + /// \brief Constructor.
3.408 + ///
3.409 + /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader
3.410 + /// and attach it into the given LemonReader. The undirected edgeset
3.411 + /// reader will add the readed undirected edges to the given Graph. It
3.412 + /// will use the given node id reader to read the source and target
3.413 + /// nodes of the edges. The reader will read the section only if the
3.414 + /// \c _id and the \c undiredgset_id are the same.
3.415 + template <typename NodeIdReader>
3.416 + UndirEdgeSetReader(LemonReader& _reader,
3.417 + typename SmartParameter<Graph>::Type _graph,
3.418 + const NodeIdReader& _nodeIdReader,
3.419 + const std::string& _id = std::string(),
3.420 + const DefaultSkipper& _skipper = DefaultSkipper())
3.421 + : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
3.422 + nodeIdReader(new IdReader<typename Graph::Node, NodeIdReader>
3.423 + (_nodeIdReader)) {}
3.424 +
3.425 + /// \brief Destructor.
3.426 + ///
3.427 + /// Destructor for UndirEdgeSetReader.
3.428 + virtual ~UndirEdgeSetReader() {
3.429 + for (typename MapReaders::iterator it = readers.begin();
3.430 + it != readers.end(); ++it) {
3.431 + delete it->second;
3.432 + }
3.433 + }
3.434 +
3.435 + private:
3.436 + UndirEdgeSetReader(const UndirEdgeSetReader&);
3.437 + void operator=(const UndirEdgeSetReader&);
3.438 +
3.439 + public:
3.440 +
3.441 + /// \brief Add a new undirected edge map reader command for the reader.
3.442 + ///
3.443 + /// Add a new edge undirected map reader command for the reader.
3.444 + template <typename Map>
3.445 + UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) {
3.446 + return _readMap<
3.447 + typename Traits::template Reader<typename Map::Value>, Map,
3.448 + typename SmartParameter<Map>::Type>(name, map);
3.449 + }
3.450 +
3.451 + template <typename Map>
3.452 + UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) {
3.453 + return _readMap<
3.454 + typename Traits::template Reader<typename Map::Value>, Map,
3.455 + typename SmartParameter<Map>::Type>(name, map);
3.456 + }
3.457 +
3.458 + /// \brief Add a new undirected edge map reader command for the reader.
3.459 + ///
3.460 + /// Add a new edge undirected map reader command for the reader.
3.461 + template <typename Reader, typename Map>
3.462 + UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map,
3.463 + const Reader& reader = Reader()) {
3.464 + return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
3.465 + (name, map, reader);
3.466 + }
3.467 +
3.468 + template <typename Reader, typename Map>
3.469 + UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map,
3.470 + const Reader& reader = Reader()) {
3.471 + return _readMap<Reader, Map, typename SmartParameter<Map>::Type >
3.472 + (name, map, reader);
3.473 + }
3.474 +
3.475 + private:
3.476 +
3.477 + template <typename Reader, typename Map, typename MapParameter>
3.478 + UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
3.479 + const Reader& reader = Reader()) {
3.480 + if (readers.find(name) != readers.end()) {
3.481 + ErrorMessage msg;
3.482 + msg << "Multiple read rule for edge map: " << name;
3.483 + throw IOParameterError(msg.message());
3.484 + }
3.485 + readers.insert(
3.486 + make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
3.487 + return *this;
3.488 + }
3.489 +
3.490 + public:
3.491 +
3.492 + /// \brief Add a new undirected edge map skipper command for the reader.
3.493 + ///
3.494 + /// Add a new undirected edge map skipper command for the reader.
3.495 + template <typename Reader>
3.496 + UndirEdgeSetReader& skipUndirEdgeMap(std::string name,
3.497 + const Reader& reader = Reader()) {
3.498 + if (readers.find(name) != readers.end()) {
3.499 + ErrorMessage msg;
3.500 + msg << "Multiple read rule for node map: " << name;
3.501 + throw IOParameterError(msg.message());
3.502 + }
3.503 + readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
3.504 + return *this;
3.505 + }
3.506 +
3.507 + /// \brief Add a new directed edge map reader command for the reader.
3.508 + ///
3.509 + /// Add a new directed edge map reader command for the reader.
3.510 + template <typename Map>
3.511 + UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) {
3.512 + return _readDirMap<
3.513 + typename Traits::template Reader<typename Map::Value>, Map,
3.514 + typename SmartParameter<Map>::Type>(name, map);
3.515 + }
3.516 +
3.517 + template <typename Map>
3.518 + UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
3.519 + return _readDirMap<
3.520 + typename Traits::template Reader<typename Map::Value>, Map,
3.521 + typename SmartParameter<Map>::Type>(name, map);
3.522 + }
3.523 +
3.524 + /// \brief Add a new directed edge map reader command for the reader.
3.525 + ///
3.526 + /// Add a new directed edge map reader command for the reader.
3.527 + template <typename Reader, typename Map>
3.528 + UndirEdgeSetReader& readEdgeMap(std::string name, Map& map,
3.529 + const Reader& reader = Reader()) {
3.530 + return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
3.531 + (name, map, reader);
3.532 + }
3.533 +
3.534 + template <typename Reader, typename Map>
3.535 + UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map,
3.536 + const Reader& reader = Reader()) {
3.537 + return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
3.538 + (name, map, reader);
3.539 + }
3.540 +
3.541 + private:
3.542 +
3.543 + template <typename Reader, typename Map, typename MapParameter>
3.544 + UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
3.545 + const Reader& reader = Reader()) {
3.546 + readMap("+" + name,
3.547 + _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
3.548 + readMap("-" + name,
3.549 + _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
3.550 + return *this;
3.551 + }
3.552 +
3.553 + public:
3.554 +
3.555 + /// \brief Add a new directed edge map skipper command for the reader.
3.556 + ///
3.557 + /// Add a new directed edge map skipper command for the reader.
3.558 + template <typename Reader>
3.559 + UndirEdgeSetReader& skipEdgeMap(std::string name,
3.560 + const Reader& reader = Reader()) {
3.561 + skipMap("+" + name, reader);
3.562 + skipMap("-" + name, reader);
3.563 + return *this;
3.564 + }
3.565 +
3.566 + protected:
3.567 +
3.568 + /// \brief Gives back true when the SectionReader can process
3.569 + /// the section with the given header line.
3.570 + ///
3.571 + /// It gives back true when the header line starts with \c \@undiredgeset,
3.572 + /// and the header line's id and the edgeset's id are the same.
3.573 + virtual bool header(const std::string& line) {
3.574 + std::istringstream ls(line);
3.575 + std::string command;
3.576 + std::string name;
3.577 + ls >> command >> name;
3.578 + return command == "@undiredgeset" && name == id;
3.579 + }
3.580 +
3.581 + /// \brief Reader function of the section.
3.582 + ///
3.583 + /// It reads the content of the section.
3.584 + virtual void read(std::istream& is) {
3.585 + std::vector<ReaderBase<Item>* > index;
3.586 + std::string line;
3.587 +
3.588 + getline(is, line);
3.589 + std::istringstream ls(line);
3.590 + while (ls >> id) {
3.591 + typename MapReaders::iterator it = readers.find(id);
3.592 + if (it != readers.end()) {
3.593 + index.push_back(it->second);
3.594 + } else {
3.595 + index.push_back(&skipper);
3.596 + }
3.597 + if (id == "id" && inverter.get() == 0) {
3.598 + inverter.reset(index.back()->getInverter());
3.599 + index.back() = inverter.get();
3.600 + }
3.601 + }
3.602 + while (getline(is, line)) {
3.603 + std::istringstream ls(line);
3.604 + typename Graph::Node from = nodeIdReader->read(ls);
3.605 + typename Graph::Node to = nodeIdReader->read(ls);
3.606 + typename Graph::UndirEdge edge = graph.addEdge(from, to);
3.607 + for (int i = 0; i < (int)index.size(); ++i) {
3.608 + index[i]->read(ls, edge);
3.609 + }
3.610 + }
3.611 + }
3.612 +
3.613 + public:
3.614 +
3.615 + /// \brief Returns true if the edgeset can give back the edge by its id.
3.616 + ///
3.617 + /// Returns true if the edgeset can give back the undirected edge by its
3.618 + /// id. It is possible only if an "id" named map was read.
3.619 + bool isIdReader() const {
3.620 + return inverter.get() != 0;
3.621 + }
3.622 +
3.623 + /// \brief Gives back the undirected edge by its id.
3.624 + ///
3.625 + /// It reads an id from the stream and gives back which undirected edge
3.626 + /// belongs to it. It is possible only if there was read an "id" named map.
3.627 + Item readId(std::istream& is) const {
3.628 + return inverter->read(is);
3.629 + }
3.630 +
3.631 + private:
3.632 +
3.633 + typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
3.634 + MapReaders readers;
3.635 +
3.636 + typename SmartReference<Graph>::Type graph;
3.637 std::string id;
3.638 SkipReader<Item, DefaultSkipper> skipper;
3.639
3.640 @@ -945,7 +1329,7 @@
3.641 /// \brief Gives back true when the SectionReader can process
3.642 /// the section with the given header line.
3.643 ///
3.644 - /// It gives back true when the header line start with \c @nodes,
3.645 + /// It gives back true when the header line start with \c \@nodes,
3.646 /// and the header line's id and the reader's id are the same.
3.647 virtual bool header(const std::string& line) {
3.648 std::istringstream ls(line);
3.649 @@ -1002,7 +1386,7 @@
3.650 /// Constructor for EdgeReader. It creates the EdgeReader and
3.651 /// attach it into the given LemonReader. It will use the given
3.652 /// edge id reader to give back the edges. The reader will read the
3.653 - /// section only if the \c _id and the \c nodes_id are the same.
3.654 + /// section only if the \c _id and the \c edges_id are the same.
3.655 template <typename _IdReader>
3.656 EdgeReader(LemonReader& _reader, const _IdReader& _idReader,
3.657 const std::string& _id = std::string())
3.658 @@ -1036,7 +1420,100 @@
3.659 /// \brief Gives back true when the SectionReader can process
3.660 /// the section with the given header line.
3.661 ///
3.662 - /// It gives back true when the header line start with \c @edges,
3.663 + /// It gives back true when the header line start with \c \@edges,
3.664 + /// and the header line's id and the reader's id are the same.
3.665 + virtual bool header(const std::string& line) {
3.666 + std::istringstream ls(line);
3.667 + std::string command;
3.668 + std::string name;
3.669 + ls >> command >> name;
3.670 + return command == "@edges" && name == id;
3.671 + }
3.672 +
3.673 + /// \brief Reader function of the section.
3.674 + ///
3.675 + /// It reads the content of the section.
3.676 + virtual void read(std::istream& is) {
3.677 + std::string line;
3.678 + while (getline(is, line)) {
3.679 + std::istringstream ls(line);
3.680 + std::string id;
3.681 + ls >> id;
3.682 + typename ItemReaders::iterator it = readers.find(id);
3.683 + if (it != readers.end()) {
3.684 + *(it->second) = idReader->read(ls);
3.685 + }
3.686 + }
3.687 + }
3.688 +
3.689 + private:
3.690 +
3.691 + std::string id;
3.692 +
3.693 + typedef std::map<std::string, Item*> ItemReaders;
3.694 + ItemReaders readers;
3.695 + std::auto_ptr<IdReaderBase<Item> > idReader;
3.696 + };
3.697 +
3.698 + /// \ingroup io_group
3.699 + /// \brief SectionReader for reading labeled undirected edges.
3.700 + ///
3.701 + /// The undirected edges section's header line is \c \@undiredges
3.702 + /// \c undiredges_id, but the \c undiredges_id may be empty.
3.703 + ///
3.704 + /// Each line in the section contains the name of the undirected edge
3.705 + /// and then the undirected edge id.
3.706 + ///
3.707 + /// \relates LemonReader
3.708 + template <typename _Graph>
3.709 + class UndirEdgeReader : public CommonSectionReaderBase {
3.710 + typedef CommonSectionReaderBase Parent;
3.711 + typedef _Graph Graph;
3.712 + typedef typename Graph::UndirEdge Item;
3.713 + public:
3.714 +
3.715 + /// \brief Constructor.
3.716 + ///
3.717 + /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and
3.718 + /// attach it into the given LemonReader. It will use the given
3.719 + /// undirected edge id reader to give back the edges. The reader will
3.720 + /// read the section only if the \c _id and the \c undiredges_id are
3.721 + /// the same.
3.722 + template <typename _IdReader>
3.723 + UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader,
3.724 + const std::string& _id = std::string())
3.725 + : Parent(_reader), id(_id),
3.726 + idReader(new IdReader<typename Graph::UndirEdge, _IdReader>(_idReader))
3.727 + {}
3.728 +
3.729 + /// \brief Destructor.
3.730 + ///
3.731 + /// Destructor for UndirEdgeReader.
3.732 + virtual ~UndirEdgeReader() {}
3.733 + private:
3.734 + UndirEdgeReader(const UndirEdgeReader&);
3.735 + void operator=(const UndirEdgeReader&);
3.736 +
3.737 + public:
3.738 +
3.739 + /// \brief Add an undirected edge reader command for the UndirEdgeReader.
3.740 + ///
3.741 + /// Add an undirected edge reader command for the UndirEdgeReader.
3.742 + void readUndirEdge(const std::string& name, Item& item) {
3.743 + if (readers.find(name) != readers.end()) {
3.744 + ErrorMessage msg;
3.745 + msg << "Multiple read rule for edge: " << name;
3.746 + throw IOParameterError(msg.message());
3.747 + }
3.748 + readers.insert(make_pair(name, &item));
3.749 + }
3.750 +
3.751 + protected:
3.752 +
3.753 + /// \brief Gives back true when the SectionReader can process
3.754 + /// the section with the given header line.
3.755 + ///
3.756 + /// It gives back true when the header line start with \c \@edges,
3.757 /// and the header line's id and the reader's id are the same.
3.758 virtual bool header(const std::string& line) {
3.759 std::istringstream ls(line);
3.760 @@ -1141,7 +1618,7 @@
3.761 /// \brief Gives back true when the SectionReader can process
3.762 /// the section with the given header line.
3.763 ///
3.764 - /// It gives back true when the header line start with \c @attributes,
3.765 + /// It gives back true when the header line start with \c \@attributes,
3.766 /// and the header line's id and the attributeset's id are the same.
3.767 bool header(const std::string& line) {
3.768 std::istringstream ls(line);
3.769 @@ -1174,6 +1651,5 @@
3.770 Readers readers;
3.771 };
3.772
3.773 -
3.774 }
3.775 #endif
4.1 --- a/src/lemon/lemon_writer.h Sat May 14 17:37:33 2005 +0000
4.2 +++ b/src/lemon/lemon_writer.h Sat May 14 17:39:37 2005 +0000
4.3 @@ -31,7 +31,10 @@
4.4
4.5 #include <lemon/error.h>
4.6 #include <lemon/invalid.h>
4.7 +#include <lemon/graph_utils.h>
4.8 #include <lemon/bits/item_writer.h>
4.9 +#include <lemon/utility.h>
4.10 +#include <lemon/maps.h>
4.11
4.12
4.13 namespace lemon {
4.14 @@ -163,8 +166,6 @@
4.15 CommonSectionWriterBase(LemonWriter& _writer)
4.16 : Parent(_writer) {}
4.17
4.18 - // Writers
4.19 -
4.20 template <typename _Item>
4.21 class WriterBase {
4.22 public:
4.23 @@ -184,7 +185,7 @@
4.24 typedef typename Writer::Value Value;
4.25 typedef _Item Item;
4.26
4.27 - const Map& map;
4.28 + typename SmartConstReference<Map>::Type map;
4.29 Writer writer;
4.30
4.31 MapWriter(const Map& _map, const Writer& _writer)
4.32 @@ -306,8 +307,8 @@
4.33 ///
4.34 /// Add a new node map writer command for the writer.
4.35 template <typename Map>
4.36 - NodeSetWriter& writeMap(std::string name, const Map& map) {
4.37 - return writeMap<typename Traits::
4.38 + NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
4.39 + return writeNodeMap<typename Traits::
4.40 template Writer<typename Map::Value>, Map>(name, map);
4.41 }
4.42
4.43 @@ -315,8 +316,8 @@
4.44 ///
4.45 /// Add a new node map writer command for the writer.
4.46 template <typename Writer, typename Map>
4.47 - NodeSetWriter& writeMap(std::string name, const Map& map,
4.48 - const Writer& writer = Writer()) {
4.49 + NodeSetWriter& writeNodeMap(std::string name, const Map& map,
4.50 + const Writer& writer = Writer()) {
4.51 writers.push_back(
4.52 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
4.53 return *this;
4.54 @@ -394,15 +395,15 @@
4.55 WriterBase<Item>* idMap;
4.56 bool forceIdMap;
4.57
4.58 - const Graph& graph;
4.59 + typename SmartConstReference<Graph>::Type graph;
4.60 std::string id;
4.61
4.62 };
4.63
4.64 /// \ingroup io_group
4.65 - /// \brief SectionWriter for writing a graph's edgeset.
4.66 + /// \brief SectionWriter for writing a graph's edgesets.
4.67 ///
4.68 - /// The lemon format can store multiple graph edgesets with several maps.
4.69 + /// The lemon format can store multiple graph edgesets with several maps.
4.70 /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
4.71 /// \c edgeset_id may be empty.
4.72 ///
4.73 @@ -413,7 +414,7 @@
4.74 ///
4.75 /// If the edgeset contains an \c "id" named map then it will be regarded
4.76 /// as id map. This map should contain only unique values and when the
4.77 - /// \c writeId() member will be called with a edge it will write it's id.
4.78 + /// \c writeId() member will be called with an edge it will write it's id.
4.79 /// Otherwise if the \c _forceIdMap constructor parameter is true then
4.80 /// the id map will be the id in the graph.
4.81 ///
4.82 @@ -436,7 +437,7 @@
4.83 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
4.84 /// attach it into the given LemonWriter. It will write node ids by
4.85 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
4.86 - /// then the writer will write own id map when the user does not give
4.87 + /// then the writer will write own id map if the user does not give
4.88 /// "id" named map.
4.89 template <typename NodeIdWriter>
4.90 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
4.91 @@ -464,21 +465,21 @@
4.92
4.93 public:
4.94
4.95 - /// \brief Add a new node map writer command for the writer.
4.96 + /// \brief Add a new edge map writer command for the writer.
4.97 ///
4.98 - /// Add a new node map writer command for the writer.
4.99 + /// Add a new edge map writer command for the writer.
4.100 template <typename Map>
4.101 - EdgeSetWriter& writeMap(std::string name, const Map& map) {
4.102 - return writeMap<typename Traits::
4.103 + EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
4.104 + return writeEdgeMap<typename Traits::
4.105 template Writer<typename Map::Value>, Map>(name, map);
4.106 }
4.107
4.108 - /// \brief Add a new node map writer command for the writer.
4.109 + /// \brief Add a new edge map writer command for the writer.
4.110 ///
4.111 - /// Add a new node map writer command for the writer.
4.112 + /// Add a new edge map writer command for the writer.
4.113 template <typename Writer, typename Map>
4.114 - EdgeSetWriter& writeMap(std::string name, const Map& map,
4.115 - const Writer& writer = Writer()) {
4.116 + EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
4.117 + const Writer& writer = Writer()) {
4.118 writers.push_back(
4.119 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
4.120 return *this;
4.121 @@ -561,7 +562,203 @@
4.122 WriterBase<Item>* idMap;
4.123 bool forceIdMap;
4.124
4.125 - const Graph& graph;
4.126 + typename SmartConstReference<Graph>::Type graph;
4.127 + std::string id;
4.128 +
4.129 + std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter;
4.130 + };
4.131 +
4.132 + /// \ingroup io_group
4.133 + /// \brief SectionWriter for writing a undirected edgeset.
4.134 + ///
4.135 + /// The lemon format can store multiple undirected edgesets with several
4.136 + /// maps. The undirected edgeset section's header line is \c \@undiredgeset
4.137 + /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
4.138 + ///
4.139 + /// The first line of the section contains the names of the maps separated
4.140 + /// with white spaces. Each next lines describes an undirected edge in the
4.141 + /// edgeset. The line contains the two connected nodes' id and the mapped
4.142 + /// values for each undirected map.
4.143 + ///
4.144 + /// The section can handle the directed as a syntactical sugar. Two
4.145 + /// undirected edge map describes one directed edge map. This two maps
4.146 + /// are the forward map and the backward map and the names of this map
4.147 + /// is near the same just with a prefix \c '+' or \c '-' character
4.148 + /// difference.
4.149 + ///
4.150 + /// If the edgeset contains an \c "id" named map then it will be regarded
4.151 + /// as id map. This map should contain only unique values and when the
4.152 + /// \c writeId() member will be called with an undirected edge it will
4.153 + /// write it's id. Otherwise if the \c _forceIdMap constructor parameter
4.154 + /// is true then the id map will be the id in the graph.
4.155 + ///
4.156 + /// The undirected edgeset writer needs a node id writer to identify
4.157 + /// which nodes have to be connected. If a NodeSetWriter can write the
4.158 + /// nodes' id, it will be able to use with this class.
4.159 + ///
4.160 + /// \relates LemonWriter
4.161 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
4.162 + class UndirEdgeSetWriter : public CommonSectionWriterBase {
4.163 + typedef CommonSectionWriterBase Parent;
4.164 + public:
4.165 +
4.166 + typedef _Graph Graph;
4.167 + typedef _Traits Traits;
4.168 + typedef typename Graph::UndirEdge Item;
4.169 +
4.170 + /// \brief Constructor.
4.171 + ///
4.172 + /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
4.173 + /// and attach it into the given LemonWriter. It will write node ids by
4.174 + /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
4.175 + /// then the writer will write own id map if the user does not give
4.176 + /// "id" named map.
4.177 + template <typename NodeIdWriter>
4.178 + UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
4.179 + const NodeIdWriter& _nodeIdWriter,
4.180 + const std::string& _id = std::string(),
4.181 + bool _forceIdMap = true)
4.182 + : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
4.183 + graph(_graph), id(_id),
4.184 + nodeIdWriter(new IdWriter<typename Graph::Node, NodeIdWriter>
4.185 + (_nodeIdWriter)) {}
4.186 +
4.187 + /// \brief Destructor.
4.188 + ///
4.189 + /// Destructor for UndirEdgeSetWriter.
4.190 + virtual ~UndirEdgeSetWriter() {
4.191 + typename MapWriters::iterator it;
4.192 + for (it = writers.begin(); it != writers.end(); ++it) {
4.193 + delete it->second;
4.194 + }
4.195 + }
4.196 +
4.197 + private:
4.198 + UndirEdgeSetWriter(const UndirEdgeSetWriter&);
4.199 + void operator=(const UndirEdgeSetWriter&);
4.200 +
4.201 + public:
4.202 +
4.203 + /// \brief Add a new undirected edge map writer command for the writer.
4.204 + ///
4.205 + /// Add a new undirected map writer command for the writer.
4.206 + template <typename Map>
4.207 + UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
4.208 + return writeUndirEdgeMap<typename Traits::
4.209 + template Writer<typename Map::Value>, Map>(name, map);
4.210 + }
4.211 +
4.212 + /// \brief Add a new undirected map writer command for the writer.
4.213 + ///
4.214 + /// Add a new undirected map writer command for the writer.
4.215 + template <typename Writer, typename Map>
4.216 + UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map,
4.217 + const Writer& writer = Writer()) {
4.218 + writers.push_back(
4.219 + make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
4.220 + return *this;
4.221 + }
4.222 +
4.223 + /// \brief Add a new directed edge map writer command for the writer.
4.224 + ///
4.225 + /// Add a new directed map writer command for the writer.
4.226 + template <typename Map>
4.227 + UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
4.228 + writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
4.229 + writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
4.230 + return *this;
4.231 + }
4.232 +
4.233 + /// \brief Add a new directed map writer command for the writer.
4.234 + ///
4.235 + /// Add a new directed map writer command for the writer.
4.236 + template <typename Writer, typename Map>
4.237 + UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
4.238 + const Writer& writer = Writer()) {
4.239 + writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
4.240 + writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
4.241 + return *this;
4.242 + }
4.243 +
4.244 + protected:
4.245 +
4.246 + /// \brief The header of the section.
4.247 + ///
4.248 + /// It gives back the header of the section.
4.249 + virtual std::string header() {
4.250 + return "@undiredgeset " + id;
4.251 + }
4.252 +
4.253 + /// \brief Writer function of the section.
4.254 + ///
4.255 + /// Write the content of the section.
4.256 + virtual void write(std::ostream& os) {
4.257 + for (int i = 0; i < (int)writers.size(); ++i) {
4.258 + if (writers[i].first == "id") {
4.259 + idMap = writers[i].second;
4.260 + forceIdMap = false;
4.261 + break;
4.262 + }
4.263 + }
4.264 + os << "\t\t";
4.265 + if (forceIdMap) {
4.266 + os << "id\t";
4.267 + }
4.268 + for (int i = 0; i < (int)writers.size(); ++i) {
4.269 + os << writers[i].first << '\t';
4.270 + }
4.271 + os << std::endl;
4.272 + for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
4.273 + nodeIdWriter->write(os, graph.source(it));
4.274 + os << '\t';
4.275 + nodeIdWriter->write(os, graph.target(it));
4.276 + os << '\t';
4.277 + if (forceIdMap) {
4.278 + os << graph.id(it) << '\t';
4.279 + }
4.280 + for (int i = 0; i < (int)writers.size(); ++i) {
4.281 + writers[i].second->write(os, it);
4.282 + os << '\t';
4.283 + }
4.284 + os << std::endl;
4.285 + }
4.286 + }
4.287 +
4.288 + public:
4.289 +
4.290 + /// \brief Returns true if the undirected edgeset can write the ids of
4.291 + /// the edges.
4.292 + ///
4.293 + /// Returns true if the undirected edgeset can write the ids of the
4.294 + /// undirected edges. It is possible only if an "id" named map was
4.295 + /// written or the \c _forceIdMap constructor parameter was true.
4.296 + bool isIdWriter() const {
4.297 + return forceIdMap || idMap != 0;
4.298 + }
4.299 +
4.300 + /// \brief Write the id of the given undirected edge.
4.301 + ///
4.302 + /// It writes the id of the given undirected edge. If there was written
4.303 + /// an "id" named map then it will write the map value belongs to the
4.304 + /// undirected edge. Otherwise if the \c forceId parameter was true it
4.305 + /// will write its id in the graph.
4.306 + void writeId(std::ostream& os, const Item& item) const {
4.307 + if (forceIdMap) {
4.308 + os << graph.id(item);
4.309 + } else {
4.310 + idMap->write(os, item);
4.311 + }
4.312 + }
4.313 +
4.314 + private:
4.315 +
4.316 + typedef std::vector<std::pair<std::string, WriterBase<Item>*> > MapWriters;
4.317 + MapWriters writers;
4.318 +
4.319 + WriterBase<Item>* idMap;
4.320 + bool forceIdMap;
4.321 +
4.322 + typename SmartConstReference<Graph>::Type graph;
4.323 std::string id;
4.324
4.325 std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter;
4.326 @@ -617,7 +814,7 @@
4.327
4.328 /// \brief Header checking function.
4.329 ///
4.330 - /// It gives back true when the header line start with \c @nodes,
4.331 + /// It gives back true when the header line start with \c \@nodes,
4.332 /// and the header line's id and the writer's id are the same.
4.333 virtual std::string header() {
4.334 return "@nodes " + id;
4.335 @@ -644,7 +841,7 @@
4.336 };
4.337
4.338 /// \ingroup io_group
4.339 - /// \brief SectionWriter for writeing labeled edges.
4.340 + /// \brief SectionWriter for writing labeled edges.
4.341 ///
4.342 /// The edges section's header line is \c \@edges \c edges_id, but the
4.343 /// \c edges_id may be empty.
4.344 @@ -681,9 +878,9 @@
4.345
4.346 public:
4.347
4.348 - /// \brief Add an edge writer command for the NodeWriter.
4.349 + /// \brief Add an edge writer command for the EdgeWriter.
4.350 ///
4.351 - /// Add an edge writer command for the NodeWriter.
4.352 + /// Add an edge writer command for the EdgeWriter.
4.353 void writeEdge(const std::string& name, const Item& item) {
4.354 writers.push_back(make_pair(name, &item));
4.355 }
4.356 @@ -692,7 +889,85 @@
4.357
4.358 /// \brief Header checking function.
4.359 ///
4.360 - /// It gives back true when the header line start with \c @nodes,
4.361 + /// It gives back true when the header line start with \c \@edges,
4.362 + /// and the header line's id and the writer's id are the same.
4.363 + virtual std::string header() {
4.364 + return "@edges " + id;
4.365 + }
4.366 +
4.367 + /// \brief Writer function of the section.
4.368 + ///
4.369 + /// Write the content of the section.
4.370 + virtual void write(std::ostream& os) {
4.371 + for (int i = 0; i < (int)writers.size(); ++i) {
4.372 + os << writers[i].first << ' ';
4.373 + idWriter->write(os, *(writers[i].second));
4.374 + os << std::endl;
4.375 + }
4.376 + }
4.377 +
4.378 + private:
4.379 +
4.380 + std::string id;
4.381 +
4.382 + typedef std::vector<std::pair<std::string, const Item*> > ItemWriters;
4.383 + ItemWriters writers;
4.384 +
4.385 + std::auto_ptr<IdWriterBase<Item> > idWriter;
4.386 + };
4.387 +
4.388 + /// \ingroup io_group
4.389 + /// \brief SectionWriter for writing labeled undirected edges.
4.390 + ///
4.391 + /// The undirected edges section's header line is \c \@undiredges
4.392 + /// \c undiredges_id, but the \c undiredges_id may be empty.
4.393 + ///
4.394 + /// Each line in the section contains the label of the undirected edge and
4.395 + /// then the undirected edge id.
4.396 + ///
4.397 + /// \relates LemonWriter
4.398 + template <typename _Graph>
4.399 + class UndirEdgeWriter : public CommonSectionWriterBase {
4.400 + typedef CommonSectionWriterBase Parent;
4.401 + typedef _Graph Graph;
4.402 + typedef typename Graph::UndirEdge Item;
4.403 + public:
4.404 +
4.405 + /// \brief Constructor.
4.406 + ///
4.407 + /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
4.408 + /// attach it into the given LemonWriter. The given \c _IdWriter
4.409 + /// will write the undirected edges' id what can be an undirected
4.410 + /// edgeset writer.
4.411 + template <typename _IdWriter>
4.412 + UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
4.413 + const std::string& _id = std::string())
4.414 + : Parent(_writer), id(_id),
4.415 + idWriter(new IdWriter<typename Graph::UndirEdge, _IdWriter>
4.416 + (_idWriter)) {}
4.417 +
4.418 + /// \brief Destructor.
4.419 + ///
4.420 + /// Destructor for UndirEdgeWriter.
4.421 + virtual ~UndirEdgeWriter() {}
4.422 + private:
4.423 + UndirEdgeWriter(const UndirEdgeWriter&);
4.424 + void operator=(const UndirEdgeWriter&);
4.425 +
4.426 + public:
4.427 +
4.428 + /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
4.429 + ///
4.430 + /// Add an edge writer command for the UndirEdgeWriter.
4.431 + void writeUndirEdge(const std::string& name, const Item& item) {
4.432 + writers.push_back(make_pair(name, &item));
4.433 + }
4.434 +
4.435 + protected:
4.436 +
4.437 + /// \brief Header checking function.
4.438 + ///
4.439 + /// It gives back true when the header line start with \c \@undiredges,
4.440 /// and the header line's id and the writer's id are the same.
4.441 virtual std::string header() {
4.442 return "@edges " + id;