lemon_writer.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  *
00003  * This file is a part of LEMON, a generic C++ optimization library
00004  *
00005  * Copyright (C) 2003-2006
00006  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00007  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00008  *
00009  * Permission to use, modify and distribute this software is granted
00010  * provided that this copyright notice appears in all copies. For
00011  * precise terms see the accompanying LICENSE file.
00012  *
00013  * This software is provided "AS IS" with no warranty of any kind,
00014  * express or implied, and with no claim as to its suitability for any
00015  * purpose.
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

Generated on Fri Feb 3 18:38:39 2006 for LEMON by  doxygen 1.4.6