00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00022
00023 #ifndef LEMON_LEMON_WRITER_H
00024 #define LEMON_LEMON_WRITER_H
00025
00026 #include <iostream>
00027 #include <fstream>
00028 #include <string>
00029 #include <vector>
00030 #include <algorithm>
00031 #include <map>
00032 #include <memory>
00033
00034 #include <lemon/error.h>
00035 #include <lemon/invalid.h>
00036 #include <lemon/graph_utils.h>
00037 #include <lemon/bits/item_writer.h>
00038 #include <lemon/utility.h>
00039 #include <lemon/maps.h>
00040 #include <lemon/xy.h>
00041
00042 #include <lemon/concept_check.h>
00043 #include <lemon/concept/maps.h>
00044
00045
00046 namespace lemon {
00047
00048 namespace _writer_bits {
00049
00050 template <typename Item>
00051 class ItemLabelWriter {
00052 public:
00053
00054 bool isLabelWriter() { return true; }
00055
00056 void writeLabel(std::ostream&, const Item&) {}
00057
00058 template <class _ItemLabelWriter>
00059 struct Constraints {
00060 void constraints() {
00061 bool b = writer.isLabelWriter();
00062 ignore_unused_variable_warning(b);
00063 writer.writeLabel(os, item);
00064 }
00065 _ItemLabelWriter& writer;
00066 std::ostream& os;
00067 const Item& item;
00068 };
00069
00070 };
00071
00072 template <typename Item>
00073 class ItemWriter {
00074 public:
00075
00076 void write(std::ostream&, const Item&) {}
00077
00078 template <class _ItemWriter>
00079 struct Constraints {
00080 void constraints() {
00081 writer.write(os, item);
00082 }
00083 _ItemWriter& writer;
00084 std::ostream& os;
00085 const Item& item;
00086 };
00087
00088 };
00089
00090 template <typename Map>
00091 struct Ref { typedef const Map& Type; };
00092
00093 template <typename Graph, typename Map>
00094 class ForwardComposeMap {
00095 public:
00096 typedef typename Graph::UEdge Key;
00097 typedef typename Map::Value Value;
00098
00099 ForwardComposeMap(const Graph& _graph, const Map& _map)
00100 : graph(_graph), map(_map) {}
00101
00102 Value operator[](const Key& key) {
00103 return map[graph.direct(key, false)];
00104 }
00105
00106 private:
00107 typename Ref<Map>::Type map;
00108 const Graph& graph;
00109 };
00110
00111 template <typename Graph, typename Map>
00112 ForwardComposeMap<Graph, Map>
00113 forwardComposeMap(const Graph& graph, const Map& map) {
00114 return ForwardComposeMap<Graph, Map>(graph, map);
00115 }
00116
00117 template <typename Graph, typename Map>
00118 class BackwardComposeMap {
00119 public:
00120 typedef typename Graph::UEdge Key;
00121 typedef typename Map::Value Value;
00122
00123 BackwardComposeMap(const Graph& _graph, const Map& _map)
00124 : graph(_graph), map(_map) {}
00125
00126 Value operator[](const Key& key) {
00127 return map[graph.direct(key, false)];
00128 }
00129
00130 private:
00131 typename Ref<Map>::Type map;
00132 const Graph& graph;
00133 };
00134
00135 template <typename Graph, typename Map>
00136 BackwardComposeMap<Graph, Map>
00137 backwardComposeMap(const Graph& graph, const Map& map) {
00138 return BackwardComposeMap<Graph, Map>(graph, map);
00139 }
00140
00141 template <typename Graph, typename Map>
00142 struct Ref<ForwardComposeMap<Graph, Map> > {
00143 typedef ForwardComposeMap<Graph, Map> Type;
00144 };
00145
00146 template <typename Graph, typename Map>
00147 struct Ref<BackwardComposeMap<Graph, Map> > {
00148 typedef BackwardComposeMap<Graph, Map> Type;
00149 };
00150
00151 template <typename Map>
00152 struct Ref<XMap<Map> > {
00153 typedef XMap<Map> Type;
00154 };
00155 template <typename Map>
00156 struct Ref<ConstXMap<Map> > {
00157 typedef ConstXMap<Map> Type;
00158 };
00159
00160 template <typename Map>
00161 struct Ref<YMap<Map> > {
00162 typedef YMap<Map> Type;
00163 };
00164 template <typename Map>
00165 struct Ref<ConstYMap<Map> > {
00166 typedef ConstYMap<Map> Type;
00167 };
00168
00169
00170 template <typename _Item>
00171 class MapWriterBase {
00172 public:
00173 typedef _Item Item;
00174
00175 virtual ~MapWriterBase() {}
00176
00177 virtual void write(std::ostream& os, const Item& item) const = 0;
00178 };
00179
00180
00181 template <typename _Item, typename _Map, typename _Writer>
00182 class MapWriter : public MapWriterBase<_Item> {
00183 public:
00184 typedef _Map Map;
00185 typedef _Writer Writer;
00186 typedef typename Writer::Value Value;
00187 typedef _Item Item;
00188
00189 typename _writer_bits::Ref<Map>::Type map;
00190 Writer writer;
00191
00192 MapWriter(const Map& _map, const Writer& _writer)
00193 : map(_map), writer(_writer) {}
00194
00195 virtual ~MapWriter() {}
00196
00197 virtual void write(std::ostream& os, const Item& item) const {
00198 Value value = map[item];
00199 writer.write(os, value);
00200 }
00201
00202 };
00203
00204
00205 class ValueWriterBase {
00206 public:
00207 virtual ~ValueWriterBase() {}
00208 virtual void write(std::ostream&) = 0;
00209 };
00210
00211 template <typename _Value, typename _Writer>
00212 class ValueWriter : public ValueWriterBase {
00213 public:
00214 typedef _Value Value;
00215 typedef _Writer Writer;
00216
00217 ValueWriter(const Value& _value, const Writer& _writer)
00218 : value(_value), writer(_writer) {}
00219
00220 virtual void write(std::ostream& os) {
00221 writer.write(os, value);
00222 }
00223 private:
00224 const Value& value;
00225 Writer writer;
00226 };
00227
00228
00229 template <typename _Item>
00230 class LabelWriterBase {
00231 public:
00232 typedef _Item Item;
00233 virtual ~LabelWriterBase() {}
00234 virtual void write(std::ostream&, const Item&) const = 0;
00235 virtual bool isLabelWriter() const = 0;
00236 };
00237
00238 template <typename _Item, typename _BoxedLabelWriter>
00239 class LabelWriter : public LabelWriterBase<_Item> {
00240 public:
00241 typedef _Item Item;
00242 typedef _BoxedLabelWriter BoxedLabelWriter;
00243
00244 const BoxedLabelWriter& labelWriter;
00245
00246 LabelWriter(const BoxedLabelWriter& _labelWriter)
00247 : labelWriter(_labelWriter) {}
00248
00249 virtual void write(std::ostream& os, const Item& item) const {
00250 labelWriter.writeLabel(os, item);
00251 }
00252
00253 virtual bool isLabelWriter() const {
00254 return labelWriter.isLabelWriter();
00255 }
00256 };
00257
00258 }
00259
00287 class LemonWriter {
00288 public:
00289
00295 class SectionWriter {
00296 friend class LemonWriter;
00297 protected:
00302 SectionWriter(LemonWriter& writer) {
00303 writer.attach(*this);
00304 }
00305
00306 virtual ~SectionWriter() {}
00307
00311 virtual std::string header() = 0;
00312
00316 virtual void write(std::ostream& os) = 0;
00317 };
00318
00322 LemonWriter(std::ostream& _os)
00323 : os(&_os), own_os(false) {}
00324
00328 LemonWriter(const std::string& filename)
00329 : os(0), own_os(true) {
00330 os = new std::ofstream(filename.c_str());
00331 }
00332
00336 ~LemonWriter() {
00337 if (own_os) {
00338 delete os;
00339 }
00340 }
00341
00342 private:
00343 LemonWriter(const LemonWriter&);
00344 void operator=(const LemonWriter&);
00345
00346 void attach(SectionWriter& writer) {
00347 writers.push_back(&writer);
00348 }
00349
00350 public:
00351
00355 void run() {
00356 SectionWriters::iterator it;
00357 for (it = writers.begin(); it != writers.end(); ++it) {
00358 *os << (*it)->header() << std::endl;
00359 (*it)->write(*os);
00360 }
00361 *os << "@end" << std::endl;
00362 }
00363
00364
00365 private:
00366
00367 std::ostream* os;
00368 bool own_os;
00369
00370 typedef std::vector<SectionWriter*> SectionWriters;
00371 SectionWriters writers;
00372
00373 };
00374
00393 template <typename _Graph, typename _Traits = DefaultWriterTraits>
00394 class NodeSetWriter : public LemonWriter::SectionWriter {
00395 typedef LemonWriter::SectionWriter Parent;
00396 public:
00397
00398 typedef _Graph Graph;
00399 typedef _Traits Traits;
00400 typedef typename Graph::Node Node;
00401
00408 NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
00409 const std::string& _name = std::string(),
00410 bool _forceLabelMap = true)
00411 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
00412 graph(_graph), name(_name) {}
00413
00417 virtual ~NodeSetWriter() {
00418 typename MapWriters::iterator it;
00419 for (it = writers.begin(); it != writers.end(); ++it) {
00420 delete it->second;
00421 }
00422 }
00423
00424 private:
00425 NodeSetWriter(const NodeSetWriter&);
00426 void operator=(const NodeSetWriter&);
00427
00428 public:
00429
00433 template <typename Map>
00434 NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
00435 return writeNodeMap<typename Traits::
00436 template Writer<typename Map::Value>, Map>(name, map);
00437 }
00438
00442 template <typename Writer, typename Map>
00443 NodeSetWriter& writeNodeMap(std::string name, const Map& map,
00444 const Writer& writer = Writer()) {
00445 checkConcept<concept::ReadMap<Node, typename Map::Value>, Map>();
00446 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
00447 writers.push_back(
00448 make_pair(name, new _writer_bits::
00449 MapWriter<Node, Map, Writer>(map, writer)));
00450 return *this;
00451 }
00452
00453 protected:
00454
00458 virtual std::string header() {
00459 return "@nodeset " + name;
00460 }
00461
00465 virtual void write(std::ostream& os) {
00466 for (int i = 0; i < (int)writers.size(); ++i) {
00467 if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) {
00468 labelMap = writers[i].second;
00469 forceLabelMap = false;
00470 break;
00471 }
00472 }
00473 if (forceLabelMap) {
00474 os << "label\t";
00475 }
00476 for (int i = 0; i < (int)writers.size(); ++i) {
00477 os << writers[i].first << '\t';
00478 }
00479 os << std::endl;
00480 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
00481 if (forceLabelMap) {
00482 os << graph.id(it) << '\t';
00483 }
00484 for (int i = 0; i < (int)writers.size(); ++i) {
00485 writers[i].second->write(os, it);
00486 os << '\t';
00487 }
00488 os << std::endl;
00489 }
00490 }
00491
00492 public:
00493
00499 bool isLabelWriter() const {
00500 return labelMap != 0 || forceLabelMap;
00501 }
00502
00509 void writeLabel(std::ostream& os, const Node& item) const {
00510 if (forceLabelMap) {
00511 os << graph.id(item);
00512 } else {
00513 labelMap->write(os, item);
00514 }
00515 }
00516
00517 private:
00518
00519 typedef std::vector<std::pair<std::string, _writer_bits::
00520 MapWriterBase<Node>*> > MapWriters;
00521 MapWriters writers;
00522
00523 _writer_bits::MapWriterBase<Node>* labelMap;
00524 bool forceLabelMap;
00525
00526 const Graph& graph;
00527 std::string name;
00528
00529 };
00530
00554 template <typename _Graph, typename _Traits = DefaultWriterTraits>
00555 class EdgeSetWriter : public LemonWriter::SectionWriter {
00556 typedef LemonWriter::SectionWriter Parent;
00557 public:
00558
00559 typedef _Graph Graph;
00560 typedef _Traits Traits;
00561 typedef typename Graph::Node Node;
00562 typedef typename Graph::Edge Edge;
00563
00571 template <typename NodeLabelWriter>
00572 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
00573 const NodeLabelWriter& _nodeLabelWriter,
00574 const std::string& _name = std::string(),
00575 bool _forceLabelMap = true)
00576 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
00577 graph(_graph), name(_name) {
00578 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
00579 nodeLabelWriter.reset(new _writer_bits::
00580 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
00581 }
00582
00586 virtual ~EdgeSetWriter() {
00587 typename MapWriters::iterator it;
00588 for (it = writers.begin(); it != writers.end(); ++it) {
00589 delete it->second;
00590 }
00591 }
00592
00593 private:
00594 EdgeSetWriter(const EdgeSetWriter&);
00595 void operator=(const EdgeSetWriter&);
00596
00597 public:
00598
00602 template <typename Map>
00603 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
00604 return writeEdgeMap<typename Traits::
00605 template Writer<typename Map::Value>, Map>(name, map);
00606 }
00607
00611 template <typename Writer, typename Map>
00612 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
00613 const Writer& writer = Writer()) {
00614 checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
00615 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
00616 writers.push_back(
00617 make_pair(name, new _writer_bits::
00618 MapWriter<Edge, Map, Writer>(map, writer)));
00619 return *this;
00620 }
00621
00622 protected:
00623
00627 virtual std::string header() {
00628 return "@edgeset " + name;
00629 }
00630
00634 virtual void write(std::ostream& os) {
00635 if (!nodeLabelWriter->isLabelWriter()) {
00636 throw DataFormatError("Cannot find nodeset or label map");
00637 }
00638 for (int i = 0; i < (int)writers.size(); ++i) {
00639 if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) {
00640 labelMap = writers[i].second;
00641 forceLabelMap = false;
00642 break;
00643 }
00644 }
00645 os << "\t\t";
00646 if (forceLabelMap) {
00647 os << "label\t";
00648 }
00649 for (int i = 0; i < (int)writers.size(); ++i) {
00650 os << writers[i].first << '\t';
00651 }
00652 os << std::endl;
00653 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
00654 nodeLabelWriter->write(os, graph.source(it));
00655 os << '\t';
00656 nodeLabelWriter->write(os, graph.target(it));
00657 os << '\t';
00658 if (forceLabelMap) {
00659 os << graph.id(it) << '\t';
00660 }
00661 for (int i = 0; i < (int)writers.size(); ++i) {
00662 writers[i].second->write(os, it);
00663 os << '\t';
00664 }
00665 os << std::endl;
00666 }
00667 }
00668
00669 public:
00670
00676 bool isLabelWriter() const {
00677 return forceLabelMap || labelMap != 0;
00678 }
00679
00686 void writeLabel(std::ostream& os, const Edge& item) const {
00687 if (forceLabelMap) {
00688 os << graph.id(item);
00689 } else {
00690 labelMap->write(os, item);
00691 }
00692 }
00693
00694 private:
00695
00696 typedef std::vector<std::pair<std::string, _writer_bits::
00697 MapWriterBase<Edge>*> > MapWriters;
00698 MapWriters writers;
00699
00700 _writer_bits::MapWriterBase<Edge>* labelMap;
00701 bool forceLabelMap;
00702
00703 const Graph& graph;
00704 std::string name;
00705
00706 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
00707 };
00708
00738 template <typename _Graph, typename _Traits = DefaultWriterTraits>
00739 class UEdgeSetWriter : public LemonWriter::SectionWriter {
00740 typedef LemonWriter::SectionWriter Parent;
00741 public:
00742
00743 typedef _Graph Graph;
00744 typedef _Traits Traits;
00745 typedef typename Graph::Node Node;
00746 typedef typename Graph::Edge Edge;
00747 typedef typename Graph::UEdge UEdge;
00748
00756 template <typename NodeLabelWriter>
00757 UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
00758 const NodeLabelWriter& _nodeLabelWriter,
00759 const std::string& _name = std::string(),
00760 bool _forceLabelMap = true)
00761 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
00762 graph(_graph), name(_name) {
00763 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
00764 nodeLabelWriter.reset(new _writer_bits::
00765 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
00766 }
00767
00771 virtual ~UEdgeSetWriter() {
00772 typename MapWriters::iterator it;
00773 for (it = writers.begin(); it != writers.end(); ++it) {
00774 delete it->second;
00775 }
00776 }
00777
00778 private:
00779 UEdgeSetWriter(const UEdgeSetWriter&);
00780 void operator=(const UEdgeSetWriter&);
00781
00782 public:
00783
00787 template <typename Map>
00788 UEdgeSetWriter& writeUEdgeMap(std::string name, const Map& map) {
00789 return writeUEdgeMap<typename Traits::
00790 template Writer<typename Map::Value>, Map>(name, map);
00791 }
00792
00796 template <typename Writer, typename Map>
00797 UEdgeSetWriter& writeUEdgeMap(std::string name, const Map& map,
00798 const Writer& writer = Writer()) {
00799 checkConcept<concept::ReadMap<UEdge, typename Map::Value>, Map>();
00800 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
00801 writers.push_back(
00802 make_pair(name, new _writer_bits::
00803 MapWriter<UEdge, Map, Writer>(map, writer)));
00804 return *this;
00805 }
00806
00810 template <typename Map>
00811 UEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
00812 return writeEdgeMap<typename Traits::
00813 template Writer<typename Map::Value>, Map>(name, map);
00814 }
00815
00819 template <typename Writer, typename Map>
00820 UEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
00821 const Writer& writer = Writer()) {
00822 checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
00823 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
00824 writeUEdge("+" + name,
00825 _writer_bits::forwardComposeMap(graph, map), writer);
00826 writeUEdge("-" + name,
00827 _writer_bits::backwardComposeMap(graph, map), writer);
00828 return *this;
00829 }
00830
00831 protected:
00832
00836 virtual std::string header() {
00837 return "@uedgeset " + name;
00838 }
00839
00843 virtual void write(std::ostream& os) {
00844 if (!nodeLabelWriter->isLabelWriter()) {
00845 throw DataFormatError("Cannot find nodeset or label map");
00846 }
00847 for (int i = 0; i < (int)writers.size(); ++i) {
00848 if (writers[i].first == "label") {
00849 labelMap = writers[i].second;
00850 forceLabelMap = false;
00851 break;
00852 }
00853 }
00854 os << "\t\t";
00855 if (forceLabelMap) {
00856 os << "label\t";
00857 }
00858 for (int i = 0; i < (int)writers.size(); ++i) {
00859 os << writers[i].first << '\t';
00860 }
00861 os << std::endl;
00862 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
00863 nodeLabelWriter->write(os, graph.source(it));
00864 os << '\t';
00865 nodeLabelWriter->write(os, graph.target(it));
00866 os << '\t';
00867 if (forceLabelMap) {
00868 os << graph.id(it) << '\t';
00869 }
00870 for (int i = 0; i < (int)writers.size(); ++i) {
00871 writers[i].second->write(os, it);
00872 os << '\t';
00873 }
00874 os << std::endl;
00875 }
00876 }
00877
00878 public:
00879
00886 bool isLabelWriter() const {
00887 return forceLabelMap || labelMap != 0;
00888 }
00889
00896 void writeLabel(std::ostream& os, const UEdge& item) const {
00897 if (forceLabelMap) {
00898 os << graph.id(item);
00899 } else {
00900 labelMap->write(os, item);
00901 }
00902 }
00903
00911 void writeLabel(std::ostream& os, const Edge& item) const {
00912 if (graph.direction(item)) {
00913 os << "+ ";
00914 } else {
00915 os << "- ";
00916 }
00917 if (forceLabelMap) {
00918 os << graph.id(item);
00919 } else {
00920 labelMap->write(os, item);
00921 }
00922 }
00923
00924 private:
00925
00926 typedef std::vector<std::pair<std::string, _writer_bits::
00927 MapWriterBase<UEdge>*> > MapWriters;
00928 MapWriters writers;
00929
00930 _writer_bits::MapWriterBase<UEdge>* labelMap;
00931 bool forceLabelMap;
00932
00933 const Graph& graph;
00934 std::string name;
00935
00936 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
00937 };
00938
00949 template <typename _Graph>
00950 class NodeWriter : public LemonWriter::SectionWriter {
00951 typedef LemonWriter::SectionWriter Parent;
00952 typedef _Graph Graph;
00953 typedef typename Graph::Node Node;
00954 public:
00955
00961 template <typename _LabelWriter>
00962 NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
00963 const std::string& _name = std::string())
00964 : Parent(_writer), name(_name) {
00965 checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
00966 labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
00967 (_labelWriter));
00968 }
00969
00970
00974 virtual ~NodeWriter() {}
00975
00976 private:
00977 NodeWriter(const NodeWriter&);
00978 void operator=(const NodeWriter&);
00979
00980 public:
00981
00985 void writeNode(const std::string& name, const Node& item) {
00986 writers.push_back(make_pair(name, &item));
00987 }
00988
00989 protected:
00990
00994 virtual std::string header() {
00995 return "@nodes " + name;
00996 }
00997
01001 virtual void write(std::ostream& os) {
01002 if (!labelWriter->isLabelWriter()) {
01003 throw DataFormatError("Cannot find nodeset or label map");
01004 }
01005 for (int i = 0; i < (int)writers.size(); ++i) {
01006 os << writers[i].first << ' ';
01007 labelWriter->write(os, *(writers[i].second));
01008 os << std::endl;
01009 }
01010 }
01011
01012 private:
01013
01014 std::string name;
01015
01016 typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
01017 NodeWriters writers;
01018 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
01019 };
01020
01031 template <typename _Graph>
01032 class EdgeWriter : public LemonWriter::SectionWriter {
01033 typedef LemonWriter::SectionWriter Parent;
01034 typedef _Graph Graph;
01035 typedef typename Graph::Edge Edge;
01036 public:
01037
01043 template <typename _LabelWriter>
01044 EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
01045 const std::string& _name = std::string())
01046 : Parent(_writer), name(_name) {
01047 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
01048 labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
01049 }
01050
01054 virtual ~EdgeWriter() {}
01055 private:
01056 EdgeWriter(const EdgeWriter&);
01057 void operator=(const EdgeWriter&);
01058
01059 public:
01060
01064 void writeEdge(const std::string& name, const Edge& item) {
01065 writers.push_back(make_pair(name, &item));
01066 }
01067
01068 protected:
01069
01073 virtual std::string header() {
01074 return "@edges " + name;
01075 }
01076
01080 virtual void write(std::ostream& os) {
01081 if (!labelWriter->isLabelWriter()) {
01082 throw DataFormatError("Cannot find edgeset or label map");
01083 }
01084 for (int i = 0; i < (int)writers.size(); ++i) {
01085 os << writers[i].first << ' ';
01086 labelWriter->write(os, *(writers[i].second));
01087 os << std::endl;
01088 }
01089 }
01090
01091 private:
01092
01093 std::string name;
01094
01095 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
01096 EdgeWriters writers;
01097
01098 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
01099 };
01100
01111 template <typename _Graph>
01112 class UEdgeWriter : public LemonWriter::SectionWriter {
01113 typedef LemonWriter::SectionWriter Parent;
01114 typedef _Graph Graph;
01115 typedef typename Graph::Node Node;
01116 typedef typename Graph::Edge Edge;
01117 typedef typename Graph::UEdge UEdge;
01118 public:
01119
01126 template <typename _LabelWriter>
01127 UEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
01128 const std::string& _name = std::string())
01129 : Parent(_writer), name(_name) {
01130 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
01131 checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
01132 uEdgeLabelWriter.reset(new _writer_bits::
01133 LabelWriter<UEdge, _LabelWriter>(_labelWriter));
01134 edgeLabelWriter.reset(new _writer_bits::
01135 LabelWriter<Edge, _LabelWriter>(_labelWriter));
01136 }
01137
01141 virtual ~UEdgeWriter() {}
01142 private:
01143 UEdgeWriter(const UEdgeWriter&);
01144 void operator=(const UEdgeWriter&);
01145
01146 public:
01147
01151 void writeEdge(const std::string& name, const Edge& item) {
01152 edgeWriters.push_back(make_pair(name, &item));
01153 }
01154
01158 void writeUEdge(const std::string& name, const UEdge& item) {
01159 uEdgeWriters.push_back(make_pair(name, &item));
01160 }
01161
01162 protected:
01163
01167 virtual std::string header() {
01168 return "@uedges " + name;
01169 }
01170
01174 virtual void write(std::ostream& os) {
01175 if (!edgeLabelWriter->isLabelWriter()) {
01176 throw DataFormatError("Cannot find undirected edgeset or label map");
01177 }
01178 if (!uEdgeLabelWriter->isLabelWriter()) {
01179 throw DataFormatError("Cannot find undirected edgeset or label map");
01180 }
01181 for (int i = 0; i < (int)uEdgeWriters.size(); ++i) {
01182 os << uEdgeWriters[i].first << ' ';
01183 uEdgeLabelWriter->write(os, *(uEdgeWriters[i].second));
01184 os << std::endl;
01185 }
01186 for (int i = 0; i < (int)edgeWriters.size(); ++i) {
01187 os << edgeWriters[i].first << ' ';
01188 edgeLabelWriter->write(os, *(edgeWriters[i].second));
01189 os << std::endl;
01190 }
01191 }
01192
01193 private:
01194
01195 std::string name;
01196
01197 typedef std::vector<std::pair<std::string,
01198 const UEdge*> > UEdgeWriters;
01199 UEdgeWriters uEdgeWriters;
01200 std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > uEdgeLabelWriter;
01201
01202 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
01203 EdgeWriters edgeWriters;
01204 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
01205
01206 };
01207
01219 template <typename _Traits = DefaultWriterTraits>
01220 class AttributeWriter : public LemonWriter::SectionWriter {
01221 typedef LemonWriter::SectionWriter Parent;
01222 typedef _Traits Traits;
01223 public:
01228 AttributeWriter(LemonWriter& _writer,
01229 const std::string& _name = std::string())
01230 : Parent(_writer), name(_name) {}
01231
01235 virtual ~AttributeWriter() {
01236 typename Writers::iterator it;
01237 for (it = writers.begin(); it != writers.end(); ++it) {
01238 delete it->second;
01239 }
01240 }
01241
01242 private:
01243 AttributeWriter(const AttributeWriter&);
01244 void operator=(AttributeWriter&);
01245
01246 public:
01250 template <typename Value>
01251 AttributeWriter& writeAttribute(const std::string& name,
01252 const Value& value) {
01253 return
01254 writeAttribute<typename Traits::template Writer<Value> >(name, value);
01255 }
01256
01260 template <typename Writer, typename Value>
01261 AttributeWriter& writeAttribute(const std::string& name,
01262 const Value& value,
01263 const Writer& writer = Writer()) {
01264 checkConcept<_writer_bits::ItemWriter<Value>, Writer>();
01265 writers.push_back(make_pair(name, new _writer_bits::
01266 ValueWriter<Value, Writer>(value, writer)));
01267 return *this;
01268 }
01269
01270 protected:
01271
01275 std::string header() {
01276 return "@attributes " + name;
01277 }
01278
01282 void write(std::ostream& os) {
01283 typename Writers::iterator it;
01284 for (it = writers.begin(); it != writers.end(); ++it) {
01285 os << it->first << ' ';
01286 it->second->write(os);
01287 os << std::endl;
01288 }
01289 }
01290
01291 private:
01292 std::string name;
01293
01294 typedef std::vector<std::pair<std::string,
01295 _writer_bits::ValueWriterBase*> > Writers;
01296 Writers writers;
01297 };
01298
01299
01300 }
01301 #endif