1.1 --- a/src/lemon/lemon_writer.h Sat May 21 21:04:57 2005 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,1129 +0,0 @@
1.4 -/* -*- C++ -*-
1.5 - * src/lemon/lemon_writer.h - Part of LEMON, a generic C++ optimization library
1.6 - *
1.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.9 - *
1.10 - * Permission to use, modify and distribute this software is granted
1.11 - * provided that this copyright notice appears in all copies. For
1.12 - * precise terms see the accompanying LICENSE file.
1.13 - *
1.14 - * This software is provided "AS IS" with no warranty of any kind,
1.15 - * express or implied, and with no claim as to its suitability for any
1.16 - * purpose.
1.17 - *
1.18 - */
1.19 -
1.20 -///\ingroup io_group
1.21 -///\file
1.22 -///\brief Lemon Format writer.
1.23 -
1.24 -#ifndef LEMON_LEMON_WRITER_H
1.25 -#define LEMON_LEMON_WRITER_H
1.26 -
1.27 -#include <iostream>
1.28 -#include <fstream>
1.29 -#include <string>
1.30 -#include <vector>
1.31 -#include <algorithm>
1.32 -#include <map>
1.33 -#include <memory>
1.34 -
1.35 -#include <lemon/error.h>
1.36 -#include <lemon/invalid.h>
1.37 -#include <lemon/graph_utils.h>
1.38 -#include <lemon/bits/item_writer.h>
1.39 -#include <lemon/utility.h>
1.40 -#include <lemon/maps.h>
1.41 -
1.42 -
1.43 -namespace lemon {
1.44 -
1.45 - /// \ingroup io_group
1.46 - /// \brief Lemon Format writer class.
1.47 - ///
1.48 - /// The Lemon Format contains several sections. We do not want to
1.49 - /// determine what sections are in a lemon file we give only a framework
1.50 - /// to write a section oriented format.
1.51 - ///
1.52 - /// In the Lemon Format each section starts with a line contains a \c \@
1.53 - /// character on the first not white space position. This line is the
1.54 - /// header line of the section. Each next lines belong to this section
1.55 - /// while it does not starts with \c \@ character. This line can start a
1.56 - /// new section or if it can close the file with the \c \@end line.
1.57 - /// The file format ignore the empty lines and it may contain comments
1.58 - /// started with a \c # character to the end of the line.
1.59 - ///
1.60 - /// The framework provides an abstract LemonWriter::SectionWriter class
1.61 - /// what defines the interface of a SectionWriter. The SectionWriter
1.62 - /// has the \c header() member function what gives back the header of the
1.63 - /// section. After that it will be called the \c write() member which
1.64 - /// should write the content of the section.
1.65 - ///
1.66 - /// \relates GraphWriter
1.67 - /// \relates NodeSetWriter
1.68 - /// \relates EdgeSetWriter
1.69 - /// \relates NodesWriter
1.70 - /// \relates EdgesWriter
1.71 - /// \relates AttributeWriter
1.72 - class LemonWriter {
1.73 - public:
1.74 -
1.75 - /// \brief Abstract base class for writing a section.
1.76 - ///
1.77 - /// This class has an \c header() member function what gives back
1.78 - /// the header line of the section. The \c write() member should
1.79 - /// write the content of the section to the stream.
1.80 - class SectionWriter {
1.81 - friend class LemonWriter;
1.82 - protected:
1.83 - /// \brief Constructor for SectionWriter.
1.84 - ///
1.85 - /// Constructor for SectionWriter. It attach this writer to
1.86 - /// the given LemonWriter.
1.87 - SectionWriter(LemonWriter& writer) {
1.88 - writer.attach(*this);
1.89 - }
1.90 -
1.91 - /// \brief The header of section.
1.92 - ///
1.93 - /// It gives back the header of the section.
1.94 - virtual std::string header() = 0;
1.95 -
1.96 - /// \brief Writer function of the section.
1.97 - ///
1.98 - /// Write the content of the section.
1.99 - virtual void write(std::ostream& os) = 0;
1.100 - };
1.101 -
1.102 - /// \brief Constructor for LemonWriter.
1.103 - ///
1.104 - /// Constructor for LemonWriter which writes to the given stream.
1.105 - LemonWriter(std::ostream& _os)
1.106 - : os(&_os), own_os(false) {}
1.107 -
1.108 - /// \brief Constructor for LemonWriter.
1.109 - ///
1.110 - /// Constructor for LemonWriter which writes to the given file.
1.111 - LemonWriter(const std::string& filename)
1.112 - : os(0), own_os(true) {
1.113 - os = new std::ofstream(filename.c_str());
1.114 - }
1.115 -
1.116 - /// \brief Desctructor for LemonWriter.
1.117 - ///
1.118 - /// Desctructor for LemonWriter.
1.119 - ~LemonWriter() {
1.120 - if (own_os) {
1.121 - delete os;
1.122 - }
1.123 - }
1.124 -
1.125 - private:
1.126 - LemonWriter(const LemonWriter&);
1.127 - void operator=(const LemonWriter&);
1.128 -
1.129 - void attach(SectionWriter& writer) {
1.130 - writers.push_back(&writer);
1.131 - }
1.132 -
1.133 - public:
1.134 -
1.135 - /// \brief Executes the LemonWriter.
1.136 - ///
1.137 - /// It executes the LemonWriter.
1.138 - void run() {
1.139 - SectionWriters::iterator it;
1.140 - for (it = writers.begin(); it != writers.end(); ++it) {
1.141 - *os << (*it)->header() << std::endl;
1.142 - (*it)->write(*os);
1.143 - }
1.144 - *os << "@end" << std::endl;
1.145 - }
1.146 -
1.147 -
1.148 - private:
1.149 -
1.150 - std::ostream* os;
1.151 - bool own_os;
1.152 -
1.153 - typedef std::vector<SectionWriter*> SectionWriters;
1.154 - SectionWriters writers;
1.155 -
1.156 - };
1.157 -
1.158 - /// \brief Helper class for implementing the common SectionWriters.
1.159 - ///
1.160 - /// Helper class for implementing the common SectionWriters.
1.161 - class CommonSectionWriterBase : public LemonWriter::SectionWriter {
1.162 - typedef LemonWriter::SectionWriter Parent;
1.163 - protected:
1.164 -
1.165 - /// \brief Constructor for CommonSectionWriterBase.
1.166 - ///
1.167 - /// Constructor for CommonSectionWriterBase. It attach this writer to
1.168 - /// the given LemonWriter.
1.169 - CommonSectionWriterBase(LemonWriter& _writer)
1.170 - : Parent(_writer) {}
1.171 -
1.172 - template <typename _Item>
1.173 - class WriterBase {
1.174 - public:
1.175 - typedef _Item Item;
1.176 -
1.177 - virtual ~WriterBase() {}
1.178 -
1.179 - virtual void write(std::ostream& os, const Item& item) = 0;
1.180 - };
1.181 -
1.182 -
1.183 - template <typename _Item, typename _Map, typename _Writer>
1.184 - class MapWriter : public WriterBase<_Item> {
1.185 - public:
1.186 - typedef _Map Map;
1.187 - typedef _Writer Writer;
1.188 - typedef typename Writer::Value Value;
1.189 - typedef _Item Item;
1.190 -
1.191 - typename SmartConstReference<Map>::Type map;
1.192 - Writer writer;
1.193 -
1.194 - MapWriter(const Map& _map, const Writer& _writer)
1.195 - : map(_map), writer(_writer) {}
1.196 -
1.197 - virtual ~MapWriter() {}
1.198 -
1.199 - virtual void write(std::ostream& os, const Item& item) {
1.200 - Value value = map[item];
1.201 - writer.write(os, value);
1.202 - }
1.203 -
1.204 - };
1.205 -
1.206 -
1.207 - class ValueWriterBase {
1.208 - public:
1.209 - virtual void write(std::ostream&) = 0;
1.210 - };
1.211 -
1.212 - template <typename _Value, typename _Writer>
1.213 - class ValueWriter : public ValueWriterBase {
1.214 - public:
1.215 - typedef _Value Value;
1.216 - typedef _Writer Writer;
1.217 -
1.218 - ValueWriter(const Value& _value, const Writer& _writer)
1.219 - : value(_value), writer(_writer) {}
1.220 -
1.221 - virtual void write(std::ostream& os) {
1.222 - writer.write(os, value);
1.223 - }
1.224 - private:
1.225 - const Value& value;
1.226 - Writer writer;
1.227 - };
1.228 -
1.229 -
1.230 - template <typename _Item>
1.231 - class IdWriterBase {
1.232 - public:
1.233 - typedef _Item Item;
1.234 - virtual void write(std::ostream&, const Item&) const = 0;
1.235 - };
1.236 -
1.237 - template <typename _Item, typename _BoxedIdWriter>
1.238 - class IdWriter : public IdWriterBase<_Item> {
1.239 - public:
1.240 - typedef _Item Item;
1.241 - typedef _BoxedIdWriter BoxedIdWriter;
1.242 -
1.243 - const BoxedIdWriter& idWriter;
1.244 -
1.245 - IdWriter(const BoxedIdWriter& _idWriter)
1.246 - : idWriter(_idWriter) {}
1.247 -
1.248 - virtual void write(std::ostream& os, const Item& item) const {
1.249 - idWriter.writeId(os, item);
1.250 - }
1.251 - };
1.252 - };
1.253 -
1.254 - /// \ingroup io_group
1.255 - /// \brief SectionWriter for writing a graph's nodeset.
1.256 - ///
1.257 - /// The lemon format can store multiple graph nodesets with several maps.
1.258 - /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
1.259 - /// \c nodeset_id may be empty.
1.260 - ///
1.261 - /// The first line of the section contains the names of the maps separated
1.262 - /// with white spaces. Each next lines describes a node in the nodeset, and
1.263 - /// contains the mapped values for each map.
1.264 - ///
1.265 - /// If the nodeset contains an \c "id" named map then it will be regarded
1.266 - /// as id map. This map should contain only unique values and when the
1.267 - /// \c writeId() member will be called with a node it will write it's id.
1.268 - /// Otherwise if the \c _forceIdMap constructor parameter is true then
1.269 - /// the id map will be the id in the graph.
1.270 - ///
1.271 - /// \relates LemonWriter
1.272 - template <typename _Graph, typename _Traits = DefaultWriterTraits>
1.273 - class NodeSetWriter : public CommonSectionWriterBase {
1.274 - typedef CommonSectionWriterBase Parent;
1.275 - public:
1.276 -
1.277 - typedef _Graph Graph;
1.278 - typedef _Traits Traits;
1.279 - typedef typename Graph::Node Node;
1.280 -
1.281 - /// \brief Constructor.
1.282 - ///
1.283 - /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
1.284 - /// attach it into the given LemonWriter. If the \c _forceIdMap
1.285 - /// parameter is true then the writer will write own id map when
1.286 - /// the user does not give "id" named map.
1.287 - NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
1.288 - const std::string& _id = std::string(),
1.289 - bool _forceIdMap = true)
1.290 - : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
1.291 - graph(_graph), id(_id) {}
1.292 -
1.293 - /// \brief Destructor.
1.294 - ///
1.295 - /// Destructor for NodeSetWriter.
1.296 - virtual ~NodeSetWriter() {
1.297 - typename MapWriters::iterator it;
1.298 - for (it = writers.begin(); it != writers.end(); ++it) {
1.299 - delete it->second;
1.300 - }
1.301 - }
1.302 -
1.303 - private:
1.304 - NodeSetWriter(const NodeSetWriter&);
1.305 - void operator=(const NodeSetWriter&);
1.306 -
1.307 - public:
1.308 -
1.309 - /// \brief Add a new node map writer command for the writer.
1.310 - ///
1.311 - /// Add a new node map writer command for the writer.
1.312 - template <typename Map>
1.313 - NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
1.314 - return writeNodeMap<typename Traits::
1.315 - template Writer<typename Map::Value>, Map>(name, map);
1.316 - }
1.317 -
1.318 - /// \brief Add a new node map writer command for the writer.
1.319 - ///
1.320 - /// Add a new node map writer command for the writer.
1.321 - template <typename Writer, typename Map>
1.322 - NodeSetWriter& writeNodeMap(std::string name, const Map& map,
1.323 - const Writer& writer = Writer()) {
1.324 - writers.push_back(
1.325 - make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
1.326 - return *this;
1.327 - }
1.328 -
1.329 - protected:
1.330 -
1.331 - /// \brief The header of the section.
1.332 - ///
1.333 - /// It gives back the header of the section.
1.334 - virtual std::string header() {
1.335 - return "@nodeset " + id;
1.336 - }
1.337 -
1.338 - /// \brief Writer function of the section.
1.339 - ///
1.340 - /// Write the content of the section.
1.341 - virtual void write(std::ostream& os) {
1.342 - for (int i = 0; i < (int)writers.size(); ++i) {
1.343 - if (writers[i].first == "id") {
1.344 - idMap = writers[i].second;
1.345 - forceIdMap = false;
1.346 - break;
1.347 - }
1.348 - }
1.349 - if (forceIdMap) {
1.350 - os << "id\t";
1.351 - }
1.352 - for (int i = 0; i < (int)writers.size(); ++i) {
1.353 - os << writers[i].first << '\t';
1.354 - }
1.355 - os << std::endl;
1.356 - for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
1.357 - if (forceIdMap) {
1.358 - os << graph.id(it) << '\t';
1.359 - }
1.360 - for (int i = 0; i < (int)writers.size(); ++i) {
1.361 - writers[i].second->write(os, it);
1.362 - os << '\t';
1.363 - }
1.364 - os << std::endl;
1.365 - }
1.366 - }
1.367 -
1.368 - public:
1.369 -
1.370 - /// \brief Returns true if the nodeset can write the ids of the nodes.
1.371 - ///
1.372 - /// Returns true if the nodeset can write the ids of the nodes.
1.373 - /// It is possible only if an "id" named map was written or the
1.374 - /// \c _forceIdMap constructor parameter was true.
1.375 - bool isIdWriter() const {
1.376 - return idMap != 0 || forceIdMap;
1.377 - }
1.378 -
1.379 - /// \brief Write the id of the given node.
1.380 - ///
1.381 - /// It writes the id of the given node. If there was written an "id"
1.382 - /// named map then it will write the map value belongs to the node.
1.383 - /// Otherwise if the \c forceId parameter was true it will write
1.384 - /// its id in the graph.
1.385 - void writeId(std::ostream& os, const Node& item) const {
1.386 - if (forceIdMap) {
1.387 - os << graph.id(item);
1.388 - } else {
1.389 - idMap->write(os, item);
1.390 - }
1.391 - }
1.392 -
1.393 - private:
1.394 -
1.395 - typedef std::vector<std::pair<std::string, WriterBase<Node>*> > MapWriters;
1.396 - MapWriters writers;
1.397 -
1.398 - WriterBase<Node>* idMap;
1.399 - bool forceIdMap;
1.400 -
1.401 - typename SmartConstReference<Graph>::Type graph;
1.402 - std::string id;
1.403 -
1.404 - };
1.405 -
1.406 - /// \ingroup io_group
1.407 - /// \brief SectionWriter for writing a graph's edgesets.
1.408 - ///
1.409 - /// The lemon format can store multiple graph edgesets with several maps.
1.410 - /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
1.411 - /// \c edgeset_id may be empty.
1.412 - ///
1.413 - /// The first line of the section contains the names of the maps separated
1.414 - /// with white spaces. Each next lines describes a edge in the edgeset. The
1.415 - /// line contains the source and the target nodes' id and the mapped
1.416 - /// values for each map.
1.417 - ///
1.418 - /// If the edgeset contains an \c "id" named map then it will be regarded
1.419 - /// as id map. This map should contain only unique values and when the
1.420 - /// \c writeId() member will be called with an edge it will write it's id.
1.421 - /// Otherwise if the \c _forceIdMap constructor parameter is true then
1.422 - /// the id map will be the id in the graph.
1.423 - ///
1.424 - /// The edgeset writer needs a node id writer to identify which nodes
1.425 - /// have to be connected. If a NodeSetWriter can write the nodes' id,
1.426 - /// it will be able to use with this class.
1.427 - ///
1.428 - /// \relates LemonWriter
1.429 - template <typename _Graph, typename _Traits = DefaultWriterTraits>
1.430 - class EdgeSetWriter : public CommonSectionWriterBase {
1.431 - typedef CommonSectionWriterBase Parent;
1.432 - public:
1.433 -
1.434 - typedef _Graph Graph;
1.435 - typedef _Traits Traits;
1.436 - typedef typename Graph::Node Node;
1.437 - typedef typename Graph::Edge Edge;
1.438 -
1.439 - /// \brief Constructor.
1.440 - ///
1.441 - /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
1.442 - /// attach it into the given LemonWriter. It will write node ids by
1.443 - /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
1.444 - /// then the writer will write own id map if the user does not give
1.445 - /// "id" named map.
1.446 - template <typename NodeIdWriter>
1.447 - EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
1.448 - const NodeIdWriter& _nodeIdWriter,
1.449 - const std::string& _id = std::string(),
1.450 - bool _forceIdMap = true)
1.451 - : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
1.452 - graph(_graph), id(_id),
1.453 - nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
1.454 -
1.455 - /// \brief Destructor.
1.456 - ///
1.457 - /// Destructor for EdgeSetWriter.
1.458 - virtual ~EdgeSetWriter() {
1.459 - typename MapWriters::iterator it;
1.460 - for (it = writers.begin(); it != writers.end(); ++it) {
1.461 - delete it->second;
1.462 - }
1.463 - }
1.464 -
1.465 - private:
1.466 - EdgeSetWriter(const EdgeSetWriter&);
1.467 - void operator=(const EdgeSetWriter&);
1.468 -
1.469 - public:
1.470 -
1.471 - /// \brief Add a new edge map writer command for the writer.
1.472 - ///
1.473 - /// Add a new edge map writer command for the writer.
1.474 - template <typename Map>
1.475 - EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
1.476 - return writeEdgeMap<typename Traits::
1.477 - template Writer<typename Map::Value>, Map>(name, map);
1.478 - }
1.479 -
1.480 - /// \brief Add a new edge map writer command for the writer.
1.481 - ///
1.482 - /// Add a new edge map writer command for the writer.
1.483 - template <typename Writer, typename Map>
1.484 - EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
1.485 - const Writer& writer = Writer()) {
1.486 - writers.push_back(
1.487 - make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
1.488 - return *this;
1.489 - }
1.490 -
1.491 - protected:
1.492 -
1.493 - /// \brief The header of the section.
1.494 - ///
1.495 - /// It gives back the header of the section.
1.496 - virtual std::string header() {
1.497 - return "@edgeset " + id;
1.498 - }
1.499 -
1.500 - /// \brief Writer function of the section.
1.501 - ///
1.502 - /// Write the content of the section.
1.503 - virtual void write(std::ostream& os) {
1.504 - for (int i = 0; i < (int)writers.size(); ++i) {
1.505 - if (writers[i].first == "id") {
1.506 - idMap = writers[i].second;
1.507 - forceIdMap = false;
1.508 - break;
1.509 - }
1.510 - }
1.511 - os << "\t\t";
1.512 - if (forceIdMap) {
1.513 - os << "id\t";
1.514 - }
1.515 - for (int i = 0; i < (int)writers.size(); ++i) {
1.516 - os << writers[i].first << '\t';
1.517 - }
1.518 - os << std::endl;
1.519 - for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
1.520 - nodeIdWriter->write(os, graph.source(it));
1.521 - os << '\t';
1.522 - nodeIdWriter->write(os, graph.target(it));
1.523 - os << '\t';
1.524 - if (forceIdMap) {
1.525 - os << graph.id(it) << '\t';
1.526 - }
1.527 - for (int i = 0; i < (int)writers.size(); ++i) {
1.528 - writers[i].second->write(os, it);
1.529 - os << '\t';
1.530 - }
1.531 - os << std::endl;
1.532 - }
1.533 - }
1.534 -
1.535 - public:
1.536 -
1.537 - /// \brief Returns true if the edgeset can write the ids of the edges.
1.538 - ///
1.539 - /// Returns true if the edgeset can write the ids of the edges.
1.540 - /// It is possible only if an "id" named map was written or the
1.541 - /// \c _forceIdMap constructor parameter was true.
1.542 - bool isIdWriter() const {
1.543 - return forceIdMap || idMap != 0;
1.544 - }
1.545 -
1.546 - /// \brief Write the id of the given edge.
1.547 - ///
1.548 - /// It writes the id of the given edge. If there was written an "id"
1.549 - /// named map then it will write the map value belongs to the edge.
1.550 - /// Otherwise if the \c forceId parameter was true it will write
1.551 - /// its id in the graph.
1.552 - void writeId(std::ostream& os, const Edge& item) const {
1.553 - if (forceIdMap) {
1.554 - os << graph.id(item);
1.555 - } else {
1.556 - idMap->write(os, item);
1.557 - }
1.558 - }
1.559 -
1.560 - private:
1.561 -
1.562 - typedef std::vector<std::pair<std::string, WriterBase<Edge>*> > MapWriters;
1.563 - MapWriters writers;
1.564 -
1.565 - WriterBase<Edge>* idMap;
1.566 - bool forceIdMap;
1.567 -
1.568 - typename SmartConstReference<Graph>::Type graph;
1.569 - std::string id;
1.570 -
1.571 - std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
1.572 - };
1.573 -
1.574 - /// \ingroup io_group
1.575 - /// \brief SectionWriter for writing a undirected edgeset.
1.576 - ///
1.577 - /// The lemon format can store multiple undirected edgesets with several
1.578 - /// maps. The undirected edgeset section's header line is \c \@undiredgeset
1.579 - /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
1.580 - ///
1.581 - /// The first line of the section contains the names of the maps separated
1.582 - /// with white spaces. Each next lines describes an undirected edge in the
1.583 - /// edgeset. The line contains the two connected nodes' id and the mapped
1.584 - /// values for each undirected map.
1.585 - ///
1.586 - /// The section can handle the directed as a syntactical sugar. Two
1.587 - /// undirected edge map describes one directed edge map. This two maps
1.588 - /// are the forward map and the backward map and the names of this map
1.589 - /// is near the same just with a prefix \c '+' or \c '-' character
1.590 - /// difference.
1.591 - ///
1.592 - /// If the edgeset contains an \c "id" named map then it will be regarded
1.593 - /// as id map. This map should contain only unique values and when the
1.594 - /// \c writeId() member will be called with an undirected edge it will
1.595 - /// write it's id. Otherwise if the \c _forceIdMap constructor parameter
1.596 - /// is true then the id map will be the id in the graph.
1.597 - ///
1.598 - /// The undirected edgeset writer needs a node id writer to identify
1.599 - /// which nodes have to be connected. If a NodeSetWriter can write the
1.600 - /// nodes' id, it will be able to use with this class.
1.601 - ///
1.602 - /// \relates LemonWriter
1.603 - template <typename _Graph, typename _Traits = DefaultWriterTraits>
1.604 - class UndirEdgeSetWriter : public CommonSectionWriterBase {
1.605 - typedef CommonSectionWriterBase Parent;
1.606 - public:
1.607 -
1.608 - typedef _Graph Graph;
1.609 - typedef _Traits Traits;
1.610 - typedef typename Graph::Node Node;
1.611 - typedef typename Graph::Edge Edge;
1.612 - typedef typename Graph::UndirEdge UndirEdge;
1.613 -
1.614 - /// \brief Constructor.
1.615 - ///
1.616 - /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
1.617 - /// and attach it into the given LemonWriter. It will write node ids by
1.618 - /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
1.619 - /// then the writer will write own id map if the user does not give
1.620 - /// "id" named map.
1.621 - template <typename NodeIdWriter>
1.622 - UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
1.623 - const NodeIdWriter& _nodeIdWriter,
1.624 - const std::string& _id = std::string(),
1.625 - bool _forceIdMap = true)
1.626 - : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
1.627 - graph(_graph), id(_id),
1.628 - nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
1.629 -
1.630 - /// \brief Destructor.
1.631 - ///
1.632 - /// Destructor for UndirEdgeSetWriter.
1.633 - virtual ~UndirEdgeSetWriter() {
1.634 - typename MapWriters::iterator it;
1.635 - for (it = writers.begin(); it != writers.end(); ++it) {
1.636 - delete it->second;
1.637 - }
1.638 - }
1.639 -
1.640 - private:
1.641 - UndirEdgeSetWriter(const UndirEdgeSetWriter&);
1.642 - void operator=(const UndirEdgeSetWriter&);
1.643 -
1.644 - public:
1.645 -
1.646 - /// \brief Add a new undirected edge map writer command for the writer.
1.647 - ///
1.648 - /// Add a new undirected map writer command for the writer.
1.649 - template <typename Map>
1.650 - UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
1.651 - return writeUndirEdgeMap<typename Traits::
1.652 - template Writer<typename Map::Value>, Map>(name, map);
1.653 - }
1.654 -
1.655 - /// \brief Add a new undirected map writer command for the writer.
1.656 - ///
1.657 - /// Add a new undirected map writer command for the writer.
1.658 - template <typename Writer, typename Map>
1.659 - UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map,
1.660 - const Writer& writer = Writer()) {
1.661 - writers.push_back(
1.662 - make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
1.663 - return *this;
1.664 - }
1.665 -
1.666 - /// \brief Add a new directed edge map writer command for the writer.
1.667 - ///
1.668 - /// Add a new directed map writer command for the writer.
1.669 - template <typename Map>
1.670 - UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
1.671 - writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
1.672 - writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
1.673 - return *this;
1.674 - }
1.675 -
1.676 - /// \brief Add a new directed map writer command for the writer.
1.677 - ///
1.678 - /// Add a new directed map writer command for the writer.
1.679 - template <typename Writer, typename Map>
1.680 - UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
1.681 - const Writer& writer = Writer()) {
1.682 - writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
1.683 - writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
1.684 - return *this;
1.685 - }
1.686 -
1.687 - protected:
1.688 -
1.689 - /// \brief The header of the section.
1.690 - ///
1.691 - /// It gives back the header of the section.
1.692 - virtual std::string header() {
1.693 - return "@undiredgeset " + id;
1.694 - }
1.695 -
1.696 - /// \brief Writer function of the section.
1.697 - ///
1.698 - /// Write the content of the section.
1.699 - virtual void write(std::ostream& os) {
1.700 - for (int i = 0; i < (int)writers.size(); ++i) {
1.701 - if (writers[i].first == "id") {
1.702 - idMap = writers[i].second;
1.703 - forceIdMap = false;
1.704 - break;
1.705 - }
1.706 - }
1.707 - os << "\t\t";
1.708 - if (forceIdMap) {
1.709 - os << "id\t";
1.710 - }
1.711 - for (int i = 0; i < (int)writers.size(); ++i) {
1.712 - os << writers[i].first << '\t';
1.713 - }
1.714 - os << std::endl;
1.715 - for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
1.716 - nodeIdWriter->write(os, graph.source(it));
1.717 - os << '\t';
1.718 - nodeIdWriter->write(os, graph.target(it));
1.719 - os << '\t';
1.720 - if (forceIdMap) {
1.721 - os << graph.id(it) << '\t';
1.722 - }
1.723 - for (int i = 0; i < (int)writers.size(); ++i) {
1.724 - writers[i].second->write(os, it);
1.725 - os << '\t';
1.726 - }
1.727 - os << std::endl;
1.728 - }
1.729 - }
1.730 -
1.731 - public:
1.732 -
1.733 - /// \brief Returns true if the undirected edgeset can write the ids of
1.734 - /// the edges.
1.735 - ///
1.736 - /// Returns true if the undirected edgeset can write the ids of the
1.737 - /// undirected edges. It is possible only if an "id" named map was
1.738 - /// written or the \c _forceIdMap constructor parameter was true.
1.739 - bool isIdWriter() const {
1.740 - return forceIdMap || idMap != 0;
1.741 - }
1.742 -
1.743 - /// \brief Write the id of the given undirected edge.
1.744 - ///
1.745 - /// It writes the id of the given undirected edge. If there was written
1.746 - /// an "id" named map then it will write the map value belongs to the
1.747 - /// undirected edge. Otherwise if the \c forceId parameter was true it
1.748 - /// will write its id in the graph.
1.749 - void writeId(std::ostream& os, const UndirEdge& item) const {
1.750 - if (forceIdMap) {
1.751 - os << graph.id(item);
1.752 - } else {
1.753 - idMap->write(os, item);
1.754 - }
1.755 - }
1.756 -
1.757 - /// \brief Write the id of the given edge.
1.758 - ///
1.759 - /// It writes the id of the given edge. If there was written
1.760 - /// an "id" named map then it will write the map value belongs to the
1.761 - /// edge. Otherwise if the \c forceId parameter was true it
1.762 - /// will write its id in the graph. If the edge is forward map
1.763 - /// then its prefix character is \c '+' elsewhere \c '-'.
1.764 - void writeId(std::ostream& os, const Edge& item) const {
1.765 - if (graph.forward(item)) {
1.766 - os << "+ ";
1.767 - } else {
1.768 - os << "- ";
1.769 - }
1.770 - if (forceIdMap) {
1.771 - os << graph.id(item);
1.772 - } else {
1.773 - idMap->write(os, item);
1.774 - }
1.775 - }
1.776 -
1.777 - private:
1.778 -
1.779 - typedef std::vector<std::pair<std::string,
1.780 - WriterBase<UndirEdge>*> > MapWriters;
1.781 - MapWriters writers;
1.782 -
1.783 - WriterBase<UndirEdge>* idMap;
1.784 - bool forceIdMap;
1.785 -
1.786 - typename SmartConstReference<Graph>::Type graph;
1.787 - std::string id;
1.788 -
1.789 - std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
1.790 - };
1.791 -
1.792 - /// \ingroup io_group
1.793 - /// \brief SectionWriter for writing labeled nodes.
1.794 - ///
1.795 - /// The nodes section's header line is \c \@nodes \c nodes_id, but the
1.796 - /// \c nodes_id may be empty.
1.797 - ///
1.798 - /// Each line in the section contains the label of the node and
1.799 - /// then the node id.
1.800 - ///
1.801 - /// \relates LemonWriter
1.802 - template <typename _Graph>
1.803 - class NodeWriter : public CommonSectionWriterBase {
1.804 - typedef CommonSectionWriterBase Parent;
1.805 - typedef _Graph Graph;
1.806 - typedef typename Graph::Node Node;
1.807 - public:
1.808 -
1.809 - /// \brief Constructor.
1.810 - ///
1.811 - /// Constructor for NodeWriter. It creates the NodeWriter and
1.812 - /// attach it into the given LemonWriter. The given \c _IdWriter
1.813 - /// will write the nodes' id what can be a nodeset writer.
1.814 - template <typename _IdWriter>
1.815 - NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
1.816 - const std::string& _id = std::string())
1.817 - : Parent(_writer), id(_id),
1.818 - idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {}
1.819 -
1.820 - /// \brief Destructor.
1.821 - ///
1.822 - /// Destructor for NodeWriter.
1.823 - virtual ~NodeWriter() {}
1.824 -
1.825 - private:
1.826 - NodeWriter(const NodeWriter&);
1.827 - void operator=(const NodeWriter&);
1.828 -
1.829 - public:
1.830 -
1.831 - /// \brief Add a node writer command for the NodeWriter.
1.832 - ///
1.833 - /// Add a node writer command for the NodeWriter.
1.834 - void writeNode(const std::string& name, const Node& item) {
1.835 - writers.push_back(make_pair(name, &item));
1.836 - }
1.837 -
1.838 - protected:
1.839 -
1.840 - /// \brief Header checking function.
1.841 - ///
1.842 - /// It gives back true when the header line start with \c \@nodes,
1.843 - /// and the header line's id and the writer's id are the same.
1.844 - virtual std::string header() {
1.845 - return "@nodes " + id;
1.846 - }
1.847 -
1.848 - /// \brief Writer function of the section.
1.849 - ///
1.850 - /// Write the content of the section.
1.851 - virtual void write(std::ostream& os) {
1.852 - for (int i = 0; i < (int)writers.size(); ++i) {
1.853 - os << writers[i].first << ' ';
1.854 - idWriter->write(os, *(writers[i].second));
1.855 - os << std::endl;
1.856 - }
1.857 - }
1.858 -
1.859 - private:
1.860 -
1.861 - std::string id;
1.862 -
1.863 - typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
1.864 - NodeWriters writers;
1.865 - std::auto_ptr<IdWriterBase<Node> > idWriter;
1.866 - };
1.867 -
1.868 - /// \ingroup io_group
1.869 - /// \brief SectionWriter for writing labeled edges.
1.870 - ///
1.871 - /// The edges section's header line is \c \@edges \c edges_id, but the
1.872 - /// \c edges_id may be empty.
1.873 - ///
1.874 - /// Each line in the section contains the label of the edge and
1.875 - /// then the edge id.
1.876 - ///
1.877 - /// \relates LemonWriter
1.878 - template <typename _Graph>
1.879 - class EdgeWriter : public CommonSectionWriterBase {
1.880 - typedef CommonSectionWriterBase Parent;
1.881 - typedef _Graph Graph;
1.882 - typedef typename Graph::Edge Edge;
1.883 - public:
1.884 -
1.885 - /// \brief Constructor.
1.886 - ///
1.887 - /// Constructor for EdgeWriter. It creates the EdgeWriter and
1.888 - /// attach it into the given LemonWriter. The given \c _IdWriter
1.889 - /// will write the edges' id what can be a edgeset writer.
1.890 - template <typename _IdWriter>
1.891 - EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
1.892 - const std::string& _id = std::string())
1.893 - : Parent(_writer), id(_id),
1.894 - idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {}
1.895 -
1.896 - /// \brief Destructor.
1.897 - ///
1.898 - /// Destructor for EdgeWriter.
1.899 - virtual ~EdgeWriter() {}
1.900 - private:
1.901 - EdgeWriter(const EdgeWriter&);
1.902 - void operator=(const EdgeWriter&);
1.903 -
1.904 - public:
1.905 -
1.906 - /// \brief Add an edge writer command for the EdgeWriter.
1.907 - ///
1.908 - /// Add an edge writer command for the EdgeWriter.
1.909 - void writeEdge(const std::string& name, const Edge& item) {
1.910 - writers.push_back(make_pair(name, &item));
1.911 - }
1.912 -
1.913 - protected:
1.914 -
1.915 - /// \brief Header checking function.
1.916 - ///
1.917 - /// It gives back true when the header line start with \c \@edges,
1.918 - /// and the header line's id and the writer's id are the same.
1.919 - virtual std::string header() {
1.920 - return "@edges " + id;
1.921 - }
1.922 -
1.923 - /// \brief Writer function of the section.
1.924 - ///
1.925 - /// Write the content of the section.
1.926 - virtual void write(std::ostream& os) {
1.927 - for (int i = 0; i < (int)writers.size(); ++i) {
1.928 - os << writers[i].first << ' ';
1.929 - idWriter->write(os, *(writers[i].second));
1.930 - os << std::endl;
1.931 - }
1.932 - }
1.933 -
1.934 - private:
1.935 -
1.936 - std::string id;
1.937 -
1.938 - typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1.939 - EdgeWriters writers;
1.940 -
1.941 - std::auto_ptr<IdWriterBase<Edge> > idWriter;
1.942 - };
1.943 -
1.944 - /// \ingroup io_group
1.945 - /// \brief SectionWriter for writing labeled undirected edges.
1.946 - ///
1.947 - /// The undirected edges section's header line is \c \@undiredges
1.948 - /// \c undiredges_id, but the \c undiredges_id may be empty.
1.949 - ///
1.950 - /// Each line in the section contains the label of the undirected edge and
1.951 - /// then the undirected edge id.
1.952 - ///
1.953 - /// \relates LemonWriter
1.954 - template <typename _Graph>
1.955 - class UndirEdgeWriter : public CommonSectionWriterBase {
1.956 - typedef CommonSectionWriterBase Parent;
1.957 - typedef _Graph Graph;
1.958 - typedef typename Graph::Node Node;
1.959 - typedef typename Graph::Edge Edge;
1.960 - typedef typename Graph::UndirEdge UndirEdge;
1.961 - public:
1.962 -
1.963 - /// \brief Constructor.
1.964 - ///
1.965 - /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
1.966 - /// attach it into the given LemonWriter. The given \c _IdWriter
1.967 - /// will write the undirected edges' id what can be an undirected
1.968 - /// edgeset writer.
1.969 - template <typename _IdWriter>
1.970 - UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
1.971 - const std::string& _id = std::string())
1.972 - : Parent(_writer), id(_id),
1.973 - undirEdgeIdWriter(new IdWriter<UndirEdge, _IdWriter>(_idWriter)),
1.974 - edgeIdWriter(new IdWriter<Edge, _IdWriter>(_idWriter)) {}
1.975 -
1.976 - /// \brief Destructor.
1.977 - ///
1.978 - /// Destructor for UndirEdgeWriter.
1.979 - virtual ~UndirEdgeWriter() {}
1.980 - private:
1.981 - UndirEdgeWriter(const UndirEdgeWriter&);
1.982 - void operator=(const UndirEdgeWriter&);
1.983 -
1.984 - public:
1.985 -
1.986 - /// \brief Add an edge writer command for the UndirEdgeWriter.
1.987 - ///
1.988 - /// Add an edge writer command for the UndirEdgeWriter.
1.989 - void writeEdge(const std::string& name, const Edge& item) {
1.990 - edgeWriters.push_back(make_pair(name, &item));
1.991 - }
1.992 -
1.993 - /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
1.994 - ///
1.995 - /// Add an undirected edge writer command for the UndirEdgeWriter.
1.996 - void writeUndirEdge(const std::string& name, const UndirEdge& item) {
1.997 - undirEdgeWriters.push_back(make_pair(name, &item));
1.998 - }
1.999 -
1.1000 - protected:
1.1001 -
1.1002 - /// \brief Header checking function.
1.1003 - ///
1.1004 - /// It gives back true when the header line start with \c \@undiredges,
1.1005 - /// and the header line's id and the writer's id are the same.
1.1006 - virtual std::string header() {
1.1007 - return "@undiredges " + id;
1.1008 - }
1.1009 -
1.1010 - /// \brief Writer function of the section.
1.1011 - ///
1.1012 - /// Write the content of the section.
1.1013 - virtual void write(std::ostream& os) {
1.1014 - for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
1.1015 - os << undirEdgeWriters[i].first << ' ';
1.1016 - undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));
1.1017 - os << std::endl;
1.1018 - }
1.1019 - for (int i = 0; i < (int)edgeWriters.size(); ++i) {
1.1020 - os << edgeWriters[i].first << ' ';
1.1021 - edgeIdWriter->write(os, *(edgeWriters[i].second));
1.1022 - os << std::endl;
1.1023 - }
1.1024 - }
1.1025 -
1.1026 - private:
1.1027 -
1.1028 - std::string id;
1.1029 -
1.1030 - typedef std::vector<std::pair<std::string,
1.1031 - const UndirEdge*> > UndirEdgeWriters;
1.1032 - UndirEdgeWriters undirEdgeWriters;
1.1033 - std::auto_ptr<IdWriterBase<UndirEdge> > undirEdgeIdWriter;
1.1034 -
1.1035 - typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1.1036 - EdgeWriters edgeWriters;
1.1037 - std::auto_ptr<IdWriterBase<Edge> > edgeIdWriter;
1.1038 -
1.1039 - };
1.1040 -
1.1041 - /// \ingroup io_group
1.1042 - /// \brief SectionWriter for attributes.
1.1043 - ///
1.1044 - /// The lemon format can store multiple attribute set. Each set has
1.1045 - /// the header line \c \@attributes \c attributeset_id, but the
1.1046 - /// attributeset_id may be empty.
1.1047 - ///
1.1048 - /// The attributeset section contains several lines. Each of them starts
1.1049 - /// with the name of attribute and then the value.
1.1050 - ///
1.1051 - /// \relates LemonWriter
1.1052 - template <typename _Traits = DefaultWriterTraits>
1.1053 - class AttributeWriter : public CommonSectionWriterBase {
1.1054 - typedef CommonSectionWriterBase Parent;
1.1055 - typedef _Traits Traits;
1.1056 - public:
1.1057 - /// \brief Constructor.
1.1058 - ///
1.1059 - /// Constructor for AttributeWriter. It creates the AttributeWriter and
1.1060 - /// attach it into the given LemonWriter.
1.1061 - AttributeWriter(LemonWriter& _writer,
1.1062 - const std::string& _id = std::string())
1.1063 - : Parent(_writer), id(_id) {}
1.1064 -
1.1065 - /// \brief Destructor.
1.1066 - ///
1.1067 - /// Destructor for AttributeWriter.
1.1068 - virtual ~AttributeWriter() {
1.1069 - typename Writers::iterator it;
1.1070 - for (it = writers.begin(); it != writers.end(); ++it) {
1.1071 - delete it->second;
1.1072 - }
1.1073 - }
1.1074 -
1.1075 - private:
1.1076 - AttributeWriter(const AttributeWriter&);
1.1077 - void operator=(AttributeWriter&);
1.1078 -
1.1079 - public:
1.1080 - /// \brief Add an attribute writer command for the writer.
1.1081 - ///
1.1082 - /// Add an attribute writer command for the writer.
1.1083 - template <typename Value>
1.1084 - AttributeWriter& writeAttribute(const std::string& id,
1.1085 - const Value& value) {
1.1086 - return
1.1087 - writeAttribute<typename Traits::template Writer<Value> >(id, value);
1.1088 - }
1.1089 -
1.1090 - /// \brief Add an attribute writer command for the writer.
1.1091 - ///
1.1092 - /// Add an attribute writer command for the writer.
1.1093 - template <typename Writer, typename Value>
1.1094 - AttributeWriter& writeAttribute(const std::string& name,
1.1095 - const Value& value,
1.1096 - const Writer& writer = Writer()) {
1.1097 - writers.push_back(make_pair(name, new ValueWriter<Value, Writer>
1.1098 - (value, writer)));
1.1099 - return *this;
1.1100 - }
1.1101 -
1.1102 - protected:
1.1103 -
1.1104 - /// \brief The header of section.
1.1105 - ///
1.1106 - /// It gives back the header of the section.
1.1107 - std::string header() {
1.1108 - return "@attributes " + id;
1.1109 - }
1.1110 -
1.1111 - /// \brief Writer function of the section.
1.1112 - ///
1.1113 - /// Write the content of the section.
1.1114 - void write(std::ostream& os) {
1.1115 - typename Writers::iterator it;
1.1116 - for (it = writers.begin(); it != writers.end(); ++it) {
1.1117 - os << it->first << ' ';
1.1118 - it->second->write(os);
1.1119 - os << std::endl;
1.1120 - }
1.1121 - }
1.1122 -
1.1123 - private:
1.1124 - std::string id;
1.1125 -
1.1126 - typedef std::vector<std::pair<std::string, ValueWriterBase*> > Writers;
1.1127 - Writers writers;
1.1128 - };
1.1129 -
1.1130 -
1.1131 -}
1.1132 -#endif