1.1 --- a/src/lemon/lemon_writer.h Sat May 14 17:37:33 2005 +0000
1.2 +++ b/src/lemon/lemon_writer.h Sat May 14 17:39:37 2005 +0000
1.3 @@ -31,7 +31,10 @@
1.4
1.5 #include <lemon/error.h>
1.6 #include <lemon/invalid.h>
1.7 +#include <lemon/graph_utils.h>
1.8 #include <lemon/bits/item_writer.h>
1.9 +#include <lemon/utility.h>
1.10 +#include <lemon/maps.h>
1.11
1.12
1.13 namespace lemon {
1.14 @@ -163,8 +166,6 @@
1.15 CommonSectionWriterBase(LemonWriter& _writer)
1.16 : Parent(_writer) {}
1.17
1.18 - // Writers
1.19 -
1.20 template <typename _Item>
1.21 class WriterBase {
1.22 public:
1.23 @@ -184,7 +185,7 @@
1.24 typedef typename Writer::Value Value;
1.25 typedef _Item Item;
1.26
1.27 - const Map& map;
1.28 + typename SmartConstReference<Map>::Type map;
1.29 Writer writer;
1.30
1.31 MapWriter(const Map& _map, const Writer& _writer)
1.32 @@ -306,8 +307,8 @@
1.33 ///
1.34 /// Add a new node map writer command for the writer.
1.35 template <typename Map>
1.36 - NodeSetWriter& writeMap(std::string name, const Map& map) {
1.37 - return writeMap<typename Traits::
1.38 + NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
1.39 + return writeNodeMap<typename Traits::
1.40 template Writer<typename Map::Value>, Map>(name, map);
1.41 }
1.42
1.43 @@ -315,8 +316,8 @@
1.44 ///
1.45 /// Add a new node map writer command for the writer.
1.46 template <typename Writer, typename Map>
1.47 - NodeSetWriter& writeMap(std::string name, const Map& map,
1.48 - const Writer& writer = Writer()) {
1.49 + NodeSetWriter& writeNodeMap(std::string name, const Map& map,
1.50 + const Writer& writer = Writer()) {
1.51 writers.push_back(
1.52 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
1.53 return *this;
1.54 @@ -394,15 +395,15 @@
1.55 WriterBase<Item>* idMap;
1.56 bool forceIdMap;
1.57
1.58 - const Graph& graph;
1.59 + typename SmartConstReference<Graph>::Type graph;
1.60 std::string id;
1.61
1.62 };
1.63
1.64 /// \ingroup io_group
1.65 - /// \brief SectionWriter for writing a graph's edgeset.
1.66 + /// \brief SectionWriter for writing a graph's edgesets.
1.67 ///
1.68 - /// The lemon format can store multiple graph edgesets with several maps.
1.69 + /// The lemon format can store multiple graph edgesets with several maps.
1.70 /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
1.71 /// \c edgeset_id may be empty.
1.72 ///
1.73 @@ -413,7 +414,7 @@
1.74 ///
1.75 /// If the edgeset contains an \c "id" named map then it will be regarded
1.76 /// as id map. This map should contain only unique values and when the
1.77 - /// \c writeId() member will be called with a edge it will write it's id.
1.78 + /// \c writeId() member will be called with an edge it will write it's id.
1.79 /// Otherwise if the \c _forceIdMap constructor parameter is true then
1.80 /// the id map will be the id in the graph.
1.81 ///
1.82 @@ -436,7 +437,7 @@
1.83 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
1.84 /// attach it into the given LemonWriter. It will write node ids by
1.85 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
1.86 - /// then the writer will write own id map when the user does not give
1.87 + /// then the writer will write own id map if the user does not give
1.88 /// "id" named map.
1.89 template <typename NodeIdWriter>
1.90 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
1.91 @@ -464,21 +465,21 @@
1.92
1.93 public:
1.94
1.95 - /// \brief Add a new node map writer command for the writer.
1.96 + /// \brief Add a new edge map writer command for the writer.
1.97 ///
1.98 - /// Add a new node map writer command for the writer.
1.99 + /// Add a new edge map writer command for the writer.
1.100 template <typename Map>
1.101 - EdgeSetWriter& writeMap(std::string name, const Map& map) {
1.102 - return writeMap<typename Traits::
1.103 + EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
1.104 + return writeEdgeMap<typename Traits::
1.105 template Writer<typename Map::Value>, Map>(name, map);
1.106 }
1.107
1.108 - /// \brief Add a new node map writer command for the writer.
1.109 + /// \brief Add a new edge map writer command for the writer.
1.110 ///
1.111 - /// Add a new node map writer command for the writer.
1.112 + /// Add a new edge map writer command for the writer.
1.113 template <typename Writer, typename Map>
1.114 - EdgeSetWriter& writeMap(std::string name, const Map& map,
1.115 - const Writer& writer = Writer()) {
1.116 + EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
1.117 + const Writer& writer = Writer()) {
1.118 writers.push_back(
1.119 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
1.120 return *this;
1.121 @@ -561,7 +562,203 @@
1.122 WriterBase<Item>* idMap;
1.123 bool forceIdMap;
1.124
1.125 - const Graph& graph;
1.126 + typename SmartConstReference<Graph>::Type graph;
1.127 + std::string id;
1.128 +
1.129 + std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter;
1.130 + };
1.131 +
1.132 + /// \ingroup io_group
1.133 + /// \brief SectionWriter for writing a undirected edgeset.
1.134 + ///
1.135 + /// The lemon format can store multiple undirected edgesets with several
1.136 + /// maps. The undirected edgeset section's header line is \c \@undiredgeset
1.137 + /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
1.138 + ///
1.139 + /// The first line of the section contains the names of the maps separated
1.140 + /// with white spaces. Each next lines describes an undirected edge in the
1.141 + /// edgeset. The line contains the two connected nodes' id and the mapped
1.142 + /// values for each undirected map.
1.143 + ///
1.144 + /// The section can handle the directed as a syntactical sugar. Two
1.145 + /// undirected edge map describes one directed edge map. This two maps
1.146 + /// are the forward map and the backward map and the names of this map
1.147 + /// is near the same just with a prefix \c '+' or \c '-' character
1.148 + /// difference.
1.149 + ///
1.150 + /// If the edgeset contains an \c "id" named map then it will be regarded
1.151 + /// as id map. This map should contain only unique values and when the
1.152 + /// \c writeId() member will be called with an undirected edge it will
1.153 + /// write it's id. Otherwise if the \c _forceIdMap constructor parameter
1.154 + /// is true then the id map will be the id in the graph.
1.155 + ///
1.156 + /// The undirected edgeset writer needs a node id writer to identify
1.157 + /// which nodes have to be connected. If a NodeSetWriter can write the
1.158 + /// nodes' id, it will be able to use with this class.
1.159 + ///
1.160 + /// \relates LemonWriter
1.161 + template <typename _Graph, typename _Traits = DefaultWriterTraits>
1.162 + class UndirEdgeSetWriter : public CommonSectionWriterBase {
1.163 + typedef CommonSectionWriterBase Parent;
1.164 + public:
1.165 +
1.166 + typedef _Graph Graph;
1.167 + typedef _Traits Traits;
1.168 + typedef typename Graph::UndirEdge Item;
1.169 +
1.170 + /// \brief Constructor.
1.171 + ///
1.172 + /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
1.173 + /// and attach it into the given LemonWriter. It will write node ids by
1.174 + /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
1.175 + /// then the writer will write own id map if the user does not give
1.176 + /// "id" named map.
1.177 + template <typename NodeIdWriter>
1.178 + UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
1.179 + const NodeIdWriter& _nodeIdWriter,
1.180 + const std::string& _id = std::string(),
1.181 + bool _forceIdMap = true)
1.182 + : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
1.183 + graph(_graph), id(_id),
1.184 + nodeIdWriter(new IdWriter<typename Graph::Node, NodeIdWriter>
1.185 + (_nodeIdWriter)) {}
1.186 +
1.187 + /// \brief Destructor.
1.188 + ///
1.189 + /// Destructor for UndirEdgeSetWriter.
1.190 + virtual ~UndirEdgeSetWriter() {
1.191 + typename MapWriters::iterator it;
1.192 + for (it = writers.begin(); it != writers.end(); ++it) {
1.193 + delete it->second;
1.194 + }
1.195 + }
1.196 +
1.197 + private:
1.198 + UndirEdgeSetWriter(const UndirEdgeSetWriter&);
1.199 + void operator=(const UndirEdgeSetWriter&);
1.200 +
1.201 + public:
1.202 +
1.203 + /// \brief Add a new undirected edge map writer command for the writer.
1.204 + ///
1.205 + /// Add a new undirected map writer command for the writer.
1.206 + template <typename Map>
1.207 + UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
1.208 + return writeUndirEdgeMap<typename Traits::
1.209 + template Writer<typename Map::Value>, Map>(name, map);
1.210 + }
1.211 +
1.212 + /// \brief Add a new undirected map writer command for the writer.
1.213 + ///
1.214 + /// Add a new undirected map writer command for the writer.
1.215 + template <typename Writer, typename Map>
1.216 + UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map,
1.217 + const Writer& writer = Writer()) {
1.218 + writers.push_back(
1.219 + make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
1.220 + return *this;
1.221 + }
1.222 +
1.223 + /// \brief Add a new directed edge map writer command for the writer.
1.224 + ///
1.225 + /// Add a new directed map writer command for the writer.
1.226 + template <typename Map>
1.227 + UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
1.228 + writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
1.229 + writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
1.230 + return *this;
1.231 + }
1.232 +
1.233 + /// \brief Add a new directed map writer command for the writer.
1.234 + ///
1.235 + /// Add a new directed map writer command for the writer.
1.236 + template <typename Writer, typename Map>
1.237 + UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
1.238 + const Writer& writer = Writer()) {
1.239 + writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
1.240 + writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
1.241 + return *this;
1.242 + }
1.243 +
1.244 + protected:
1.245 +
1.246 + /// \brief The header of the section.
1.247 + ///
1.248 + /// It gives back the header of the section.
1.249 + virtual std::string header() {
1.250 + return "@undiredgeset " + id;
1.251 + }
1.252 +
1.253 + /// \brief Writer function of the section.
1.254 + ///
1.255 + /// Write the content of the section.
1.256 + virtual void write(std::ostream& os) {
1.257 + for (int i = 0; i < (int)writers.size(); ++i) {
1.258 + if (writers[i].first == "id") {
1.259 + idMap = writers[i].second;
1.260 + forceIdMap = false;
1.261 + break;
1.262 + }
1.263 + }
1.264 + os << "\t\t";
1.265 + if (forceIdMap) {
1.266 + os << "id\t";
1.267 + }
1.268 + for (int i = 0; i < (int)writers.size(); ++i) {
1.269 + os << writers[i].first << '\t';
1.270 + }
1.271 + os << std::endl;
1.272 + for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
1.273 + nodeIdWriter->write(os, graph.source(it));
1.274 + os << '\t';
1.275 + nodeIdWriter->write(os, graph.target(it));
1.276 + os << '\t';
1.277 + if (forceIdMap) {
1.278 + os << graph.id(it) << '\t';
1.279 + }
1.280 + for (int i = 0; i < (int)writers.size(); ++i) {
1.281 + writers[i].second->write(os, it);
1.282 + os << '\t';
1.283 + }
1.284 + os << std::endl;
1.285 + }
1.286 + }
1.287 +
1.288 + public:
1.289 +
1.290 + /// \brief Returns true if the undirected edgeset can write the ids of
1.291 + /// the edges.
1.292 + ///
1.293 + /// Returns true if the undirected edgeset can write the ids of the
1.294 + /// undirected edges. It is possible only if an "id" named map was
1.295 + /// written or the \c _forceIdMap constructor parameter was true.
1.296 + bool isIdWriter() const {
1.297 + return forceIdMap || idMap != 0;
1.298 + }
1.299 +
1.300 + /// \brief Write the id of the given undirected edge.
1.301 + ///
1.302 + /// It writes the id of the given undirected edge. If there was written
1.303 + /// an "id" named map then it will write the map value belongs to the
1.304 + /// undirected edge. Otherwise if the \c forceId parameter was true it
1.305 + /// will write its id in the graph.
1.306 + void writeId(std::ostream& os, const Item& item) const {
1.307 + if (forceIdMap) {
1.308 + os << graph.id(item);
1.309 + } else {
1.310 + idMap->write(os, item);
1.311 + }
1.312 + }
1.313 +
1.314 + private:
1.315 +
1.316 + typedef std::vector<std::pair<std::string, WriterBase<Item>*> > MapWriters;
1.317 + MapWriters writers;
1.318 +
1.319 + WriterBase<Item>* idMap;
1.320 + bool forceIdMap;
1.321 +
1.322 + typename SmartConstReference<Graph>::Type graph;
1.323 std::string id;
1.324
1.325 std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter;
1.326 @@ -617,7 +814,7 @@
1.327
1.328 /// \brief Header checking function.
1.329 ///
1.330 - /// It gives back true when the header line start with \c @nodes,
1.331 + /// It gives back true when the header line start with \c \@nodes,
1.332 /// and the header line's id and the writer's id are the same.
1.333 virtual std::string header() {
1.334 return "@nodes " + id;
1.335 @@ -644,7 +841,7 @@
1.336 };
1.337
1.338 /// \ingroup io_group
1.339 - /// \brief SectionWriter for writeing labeled edges.
1.340 + /// \brief SectionWriter for writing labeled edges.
1.341 ///
1.342 /// The edges section's header line is \c \@edges \c edges_id, but the
1.343 /// \c edges_id may be empty.
1.344 @@ -681,9 +878,9 @@
1.345
1.346 public:
1.347
1.348 - /// \brief Add an edge writer command for the NodeWriter.
1.349 + /// \brief Add an edge writer command for the EdgeWriter.
1.350 ///
1.351 - /// Add an edge writer command for the NodeWriter.
1.352 + /// Add an edge writer command for the EdgeWriter.
1.353 void writeEdge(const std::string& name, const Item& item) {
1.354 writers.push_back(make_pair(name, &item));
1.355 }
1.356 @@ -692,7 +889,85 @@
1.357
1.358 /// \brief Header checking function.
1.359 ///
1.360 - /// It gives back true when the header line start with \c @nodes,
1.361 + /// It gives back true when the header line start with \c \@edges,
1.362 + /// and the header line's id and the writer's id are the same.
1.363 + virtual std::string header() {
1.364 + return "@edges " + id;
1.365 + }
1.366 +
1.367 + /// \brief Writer function of the section.
1.368 + ///
1.369 + /// Write the content of the section.
1.370 + virtual void write(std::ostream& os) {
1.371 + for (int i = 0; i < (int)writers.size(); ++i) {
1.372 + os << writers[i].first << ' ';
1.373 + idWriter->write(os, *(writers[i].second));
1.374 + os << std::endl;
1.375 + }
1.376 + }
1.377 +
1.378 + private:
1.379 +
1.380 + std::string id;
1.381 +
1.382 + typedef std::vector<std::pair<std::string, const Item*> > ItemWriters;
1.383 + ItemWriters writers;
1.384 +
1.385 + std::auto_ptr<IdWriterBase<Item> > idWriter;
1.386 + };
1.387 +
1.388 + /// \ingroup io_group
1.389 + /// \brief SectionWriter for writing labeled undirected edges.
1.390 + ///
1.391 + /// The undirected edges section's header line is \c \@undiredges
1.392 + /// \c undiredges_id, but the \c undiredges_id may be empty.
1.393 + ///
1.394 + /// Each line in the section contains the label of the undirected edge and
1.395 + /// then the undirected edge id.
1.396 + ///
1.397 + /// \relates LemonWriter
1.398 + template <typename _Graph>
1.399 + class UndirEdgeWriter : public CommonSectionWriterBase {
1.400 + typedef CommonSectionWriterBase Parent;
1.401 + typedef _Graph Graph;
1.402 + typedef typename Graph::UndirEdge Item;
1.403 + public:
1.404 +
1.405 + /// \brief Constructor.
1.406 + ///
1.407 + /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
1.408 + /// attach it into the given LemonWriter. The given \c _IdWriter
1.409 + /// will write the undirected edges' id what can be an undirected
1.410 + /// edgeset writer.
1.411 + template <typename _IdWriter>
1.412 + UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
1.413 + const std::string& _id = std::string())
1.414 + : Parent(_writer), id(_id),
1.415 + idWriter(new IdWriter<typename Graph::UndirEdge, _IdWriter>
1.416 + (_idWriter)) {}
1.417 +
1.418 + /// \brief Destructor.
1.419 + ///
1.420 + /// Destructor for UndirEdgeWriter.
1.421 + virtual ~UndirEdgeWriter() {}
1.422 + private:
1.423 + UndirEdgeWriter(const UndirEdgeWriter&);
1.424 + void operator=(const UndirEdgeWriter&);
1.425 +
1.426 + public:
1.427 +
1.428 + /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
1.429 + ///
1.430 + /// Add an edge writer command for the UndirEdgeWriter.
1.431 + void writeUndirEdge(const std::string& name, const Item& item) {
1.432 + writers.push_back(make_pair(name, &item));
1.433 + }
1.434 +
1.435 + protected:
1.436 +
1.437 + /// \brief Header checking function.
1.438 + ///
1.439 + /// It gives back true when the header line start with \c \@undiredges,
1.440 /// and the header line's id and the writer's id are the same.
1.441 virtual std::string header() {
1.442 return "@edges " + id;