3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
21 ///\brief Lemon Graph Format writer.
24 #ifndef LEMON_LGF_WRITER_H
25 #define LEMON_LGF_WRITER_H
36 #include <lemon/assert.h>
37 #include <lemon/graph_utils.h>
41 namespace _writer_bits {
43 template <typename Value>
44 struct DefaultConverter {
45 std::string operator()(const Value& value) {
46 std::ostringstream os;
53 bool operator<(const T&, const T&) {
54 throw DataFormatError("Label map is not comparable");
57 template <typename _Map>
61 typedef typename Map::Key Item;
67 MapLess(const Map& map) : _map(map) {}
69 bool operator()(const Item& left, const Item& right) {
70 return _map[left] < _map[right];
74 template <typename _Item>
75 class MapStorageBase {
81 virtual ~MapStorageBase() {}
83 virtual std::string get(const Item& item) = 0;
84 virtual void sort(std::vector<Item>&) = 0;
87 template <typename _Item, typename _Map,
88 typename _Converter = DefaultConverter<typename _Map::Value> >
89 class MapStorage : public MapStorageBase<_Item> {
92 typedef _Converter Converter;
100 MapStorage(const Map& map, const Converter& converter = Converter())
101 : _map(map), _converter(converter) {}
102 virtual ~MapStorage() {}
104 virtual std::string get(const Item& item) {
105 return _converter(_map[item]);
107 virtual void sort(std::vector<Item>& items) {
108 MapLess<Map> less(_map);
109 std::sort(items.begin(), items.end(), less);
113 class ValueStorageBase {
115 ValueStorageBase() {}
116 virtual ~ValueStorageBase() {}
118 virtual std::string get() = 0;
121 template <typename _Value, typename _Converter = DefaultConverter<_Value> >
122 class ValueStorage : public ValueStorageBase {
124 typedef _Value Value;
125 typedef _Converter Converter;
129 Converter _converter;
132 ValueStorage(const Value& value, const Converter& converter = Converter())
133 : _value(value), _converter(converter) {}
135 virtual std::string get() {
136 return _converter(_value);
140 template <typename Value>
141 struct MapLookUpConverter {
142 const std::map<Value, std::string>& _map;
144 MapLookUpConverter(const std::map<Value, std::string>& map)
147 std::string operator()(const Value& str) {
148 typename std::map<Value, std::string>::const_iterator it =
150 if (it == _map.end()) {
151 throw DataFormatError("Item not found");
157 bool isWhiteSpace(char c) {
158 return c == ' ' || c == '\t' || c == '\v' ||
159 c == '\n' || c == '\r' || c == '\f';
162 bool isEscaped(char c) {
163 return c == '\\' || c == '\"' || c == '\'' ||
164 c == '\a' || c == '\b';
167 static void writeEscape(std::ostream& os, char c) {
198 os << '\\' << std::oct << static_cast<int>(c);
206 bool requireEscape(const std::string& str) {
207 std::istringstream is(str);
210 if (isWhiteSpace(c) || isEscaped(c)) {
217 std::ostream& writeToken(std::ostream& os, const std::string& str) {
219 if (requireEscape(str)) {
221 for (std::string::const_iterator it = str.begin();
222 it != str.end(); ++it) {
223 writeEscape(os, *it);
235 template <typename _Digraph>
236 class DigraphWriter {
239 typedef _Digraph Digraph;
240 DIGRAPH_TYPEDEFS(Digraph);
250 std::string _nodes_caption;
251 std::string _arcs_caption;
252 std::string _attributes_caption;
254 typedef std::map<Node, std::string> NodeIndex;
255 NodeIndex _node_index;
256 typedef std::map<Arc, std::string> ArcIndex;
259 typedef std::vector<std::pair<std::string,
260 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
263 typedef std::vector<std::pair<std::string,
264 _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
267 typedef std::vector<std::pair<std::string,
268 _writer_bits::ValueStorageBase*> > Attributes;
269 Attributes _attributes;
277 DigraphWriter(std::ostream& is, Digraph& digraph)
278 : _os(&is), local_os(false), _digraph(digraph),
279 _skip_nodes(false), _skip_arcs(false) {}
282 DigraphWriter(const std::string& fn, Digraph& digraph)
283 : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
284 _skip_nodes(false), _skip_arcs(false) {}
287 DigraphWriter(const char* fn, Digraph& digraph)
288 : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
289 _skip_nodes(false), _skip_arcs(false) {}
291 DigraphWriter(DigraphWriter& other)
292 : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
293 _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
296 other.local_os = false;
298 _node_index.swap(other._node_index);
299 _arc_index.swap(other._arc_index);
301 _node_maps.swap(other._node_maps);
302 _arc_maps.swap(other._arc_maps);
303 _attributes.swap(other._attributes);
305 _nodes_caption = other._nodes_caption;
306 _arcs_caption = other._arcs_caption;
307 _attributes_caption = other._attributes_caption;
312 for (typename NodeMaps::iterator it = _node_maps.begin();
313 it != _node_maps.end(); ++it) {
317 for (typename ArcMaps::iterator it = _arc_maps.begin();
318 it != _arc_maps.end(); ++it) {
322 for (typename Attributes::iterator it = _attributes.begin();
323 it != _attributes.end(); ++it) {
334 DigraphWriter& operator=(const DigraphWriter&);
339 template <typename Map>
340 DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
341 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
342 _writer_bits::MapStorageBase<Node>* storage =
343 new _writer_bits::MapStorage<Node, Map>(map);
344 _node_maps.push_back(std::make_pair(caption, storage));
349 template <typename Map, typename Converter>
350 DigraphWriter& nodeMap(const std::string& caption, const Map& map,
351 const Converter& converter = Converter()) {
352 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
353 _writer_bits::MapStorageBase<Node>* storage =
354 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
355 _node_maps.push_back(std::make_pair(caption, storage));
360 template <typename Map>
361 DigraphWriter& arcMap(const std::string& caption, const Map& map) {
362 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
363 _writer_bits::MapStorageBase<Arc>* storage =
364 new _writer_bits::MapStorage<Arc, Map>(map);
365 _arc_maps.push_back(std::make_pair(caption, storage));
370 template <typename Map, typename Converter>
371 DigraphWriter& arcMap(const std::string& caption, const Map& map,
372 const Converter& converter = Converter()) {
373 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
374 _writer_bits::MapStorageBase<Arc>* storage =
375 new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
376 _arc_maps.push_back(std::make_pair(caption, storage));
381 template <typename Value>
382 DigraphWriter& attribute(const std::string& caption, const Value& value) {
383 _writer_bits::ValueStorageBase* storage =
384 new _writer_bits::ValueStorage<Value>(value);
385 _attributes.push_back(std::make_pair(caption, storage));
390 template <typename Value, typename Converter>
391 DigraphWriter& attribute(const std::string& caption, const Value& value,
392 const Converter& converter = Converter()) {
393 _writer_bits::ValueStorageBase* storage =
394 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
395 _attributes.push_back(std::make_pair(caption, storage));
400 DigraphWriter& node(const std::string& caption, const Node& node) {
401 typedef _writer_bits::MapLookUpConverter<Node> Converter;
402 Converter converter(_node_index);
403 _writer_bits::ValueStorageBase* storage =
404 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
405 _attributes.push_back(std::make_pair(caption, storage));
410 DigraphWriter& arc(const std::string& caption, const Arc& arc) {
411 typedef _writer_bits::MapLookUpConverter<Arc> Converter;
412 Converter converter(_arc_index);
413 _writer_bits::ValueStorageBase* storage =
414 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
415 _attributes.push_back(std::make_pair(caption, storage));
420 DigraphWriter& nodes(const std::string& caption) {
421 _nodes_caption = caption;
426 DigraphWriter& arcs(const std::string& caption) {
427 _arcs_caption = caption;
432 DigraphWriter& attributes(const std::string& caption) {
433 _attributes_caption = caption;
437 DigraphWriter& skipNodes() {
438 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
442 DigraphWriter& skipArcs() {
443 LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
450 _writer_bits::MapStorageBase<Node>* label = 0;
451 for (typename NodeMaps::iterator it = _node_maps.begin();
452 it != _node_maps.end(); ++it) {
453 if (it->first == "label") {
460 if (!_nodes_caption.empty()) {
461 *_os << ' ' << _nodes_caption;
466 *_os << "label" << '\t';
468 for (typename NodeMaps::iterator it = _node_maps.begin();
469 it != _node_maps.end(); ++it) {
470 *_os << it->first << '\t';
474 std::vector<Node> nodes;
475 for (NodeIt n(_digraph); n != INVALID; ++n) {
480 IdMap<Digraph, Node> id_map(_digraph);
481 _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
482 std::sort(nodes.begin(), nodes.end(), id_less);
487 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
490 std::ostringstream os;
491 os << _digraph.id(n);
492 _writer_bits::writeToken(*_os, os.str());
494 _node_index.insert(std::make_pair(n, os.str()));
496 for (typename NodeMaps::iterator it = _node_maps.begin();
497 it != _node_maps.end(); ++it) {
498 std::string value = it->second->get(n);
499 _writer_bits::writeToken(*_os, value);
500 if (it->first == "label") {
501 _node_index.insert(std::make_pair(n, value));
510 _writer_bits::MapStorageBase<Arc>* label = 0;
511 for (typename ArcMaps::iterator it = _arc_maps.begin();
512 it != _arc_maps.end(); ++it) {
513 if (it->first == "label") {
520 if (!_arcs_caption.empty()) {
521 *_os << ' ' << _arcs_caption;
525 *_os << '\t' << '\t';
527 *_os << "label" << '\t';
529 for (typename ArcMaps::iterator it = _arc_maps.begin();
530 it != _arc_maps.end(); ++it) {
531 *_os << it->first << '\t';
535 std::vector<Arc> arcs;
536 for (ArcIt n(_digraph); n != INVALID; ++n) {
541 IdMap<Digraph, Arc> id_map(_digraph);
542 _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
543 std::sort(arcs.begin(), arcs.end(), id_less);
548 for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
550 _writer_bits::writeToken(*_os, _node_index.
551 find(_digraph.source(a))->second);
553 _writer_bits::writeToken(*_os, _node_index.
554 find(_digraph.target(a))->second);
557 std::ostringstream os;
558 os << _digraph.id(a);
559 _writer_bits::writeToken(*_os, os.str());
561 _arc_index.insert(std::make_pair(a, os.str()));
563 for (typename ArcMaps::iterator it = _arc_maps.begin();
564 it != _arc_maps.end(); ++it) {
565 std::string value = it->second->get(a);
566 _writer_bits::writeToken(*_os, value);
567 if (it->first == "label") {
568 _arc_index.insert(std::make_pair(a, value));
576 void writeAttributes() {
577 if (_attributes.empty()) return;
578 *_os << "@attributes";
579 if (!_attributes_caption.empty()) {
580 *_os << ' ' << _attributes_caption;
583 for (typename Attributes::iterator it = _attributes.begin();
584 it != _attributes.end(); ++it) {
585 *_os << it->first << ' ';
586 _writer_bits::writeToken(*_os, it->second->get());
605 std::ostream& stream() {
610 template <typename Digraph>
611 DigraphWriter<Digraph> digraphWriter(std::istream& is, Digraph& digraph) {
612 return DigraphWriter<Digraph>(is, digraph);
615 template <typename Digraph>
616 DigraphWriter<Digraph> digraphWriter(const std::string& fn,
618 return DigraphWriter<Digraph>(fn, digraph);
621 template <typename Digraph>
622 DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
623 return DigraphWriter<Digraph>(fn, digraph);