Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

lemon_writer.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/lemon_writer.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
00014  *
00015  */
00016 
00020 
00021 #ifndef LEMON_LEMON_WRITER_H
00022 #define LEMON_LEMON_WRITER_H
00023 
00024 #include <iostream>
00025 #include <fstream>
00026 #include <string>
00027 #include <vector>
00028 #include <algorithm>
00029 #include <map>
00030 #include <memory>
00031 
00032 #include <lemon/error.h>
00033 #include <lemon/invalid.h>
00034 #include <lemon/graph_utils.h>
00035 #include <lemon/bits/item_writer.h>
00036 #include <lemon/utility.h>
00037 #include <lemon/maps.h>
00038 
00039 #include <lemon/concept_check.h>
00040 #include <lemon/concept/maps.h>
00041 
00042 
00043 namespace lemon {
00044 
00045   namespace _writer_bits {
00046     
00047     template <typename Item>
00048     class ItemIdWriter {
00049     public:
00050 
00051       bool isIdWriter() { return true; }
00052 
00053       void writeId(std::ostream&, const Item&) {}
00054       
00055       template <class _ItemIdWriter>
00056       struct Constraints {
00057         void constraints() {
00058           bool b = writer.isIdWriter();
00059           ignore_unused_variable_warning(b);
00060           writer.writeId(os, item);
00061         }
00062         _ItemIdWriter& writer;
00063         std::ostream& os;
00064         const Item& item;
00065       };
00066 
00067     };
00068 
00069     template <typename Item>
00070     class ItemWriter {
00071     public:
00072 
00073       void write(std::ostream&, const Item&) {}
00074       
00075       template <class _ItemWriter>
00076       struct Constraints {
00077         void constraints() {
00078           writer.write(os, item);
00079         }
00080         _ItemWriter& writer;
00081         std::ostream& os;
00082         const Item& item;
00083       };
00084 
00085     };
00086 
00087   }
00088 
00116   class LemonWriter {
00117   public:
00118 
00124     class SectionWriter {
00125       friend class LemonWriter;
00126     protected:
00131       SectionWriter(LemonWriter& writer) {
00132         writer.attach(*this);
00133       }
00134       
00135       virtual ~SectionWriter() {}
00136 
00140       virtual std::string header() = 0;
00141 
00145       virtual void write(std::ostream& os) = 0;
00146     };
00147 
00151     LemonWriter(std::ostream& _os) 
00152       : os(&_os), own_os(false) {}
00153 
00157     LemonWriter(const std::string& filename) 
00158       : os(0), own_os(true) {
00159       os = new std::ofstream(filename.c_str());
00160     }
00161 
00165     ~LemonWriter() {
00166       if (own_os) {
00167         delete os;
00168       }
00169     }
00170 
00171   private:
00172     LemonWriter(const LemonWriter&);
00173     void operator=(const LemonWriter&);
00174 
00175     void attach(SectionWriter& writer) {
00176       writers.push_back(&writer);
00177     }
00178 
00179   public:
00180 
00184     void run() {
00185       SectionWriters::iterator it;
00186       for (it = writers.begin(); it != writers.end(); ++it) {
00187         *os << (*it)->header() << std::endl;
00188         (*it)->write(*os);
00189       }
00190       *os << "@end" << std::endl;
00191     }
00192 
00193 
00194   private:
00195 
00196     std::ostream* os;
00197     bool own_os;
00198 
00199     typedef std::vector<SectionWriter*> SectionWriters;
00200     SectionWriters writers;
00201 
00202   };
00203 
00207   class CommonSectionWriterBase : public LemonWriter::SectionWriter {
00208     typedef LemonWriter::SectionWriter Parent;
00209   protected:
00210     
00215     CommonSectionWriterBase(LemonWriter& _writer) 
00216       : Parent(_writer) {}
00217 
00218     template <typename _Item>    
00219     class WriterBase {
00220     public:
00221       typedef _Item Item;
00222 
00223       virtual ~WriterBase() {}
00224 
00225       virtual void write(std::ostream& os, const Item& item) = 0;
00226     };
00227 
00228 
00229     template <typename _Item, typename _Map, typename _Writer>
00230     class MapWriter : public WriterBase<_Item> {
00231     public:
00232       typedef _Map Map;
00233       typedef _Writer Writer;
00234       typedef typename Writer::Value Value;
00235       typedef _Item Item;
00236       
00237       typename SmartConstReference<Map>::Type map;
00238       Writer writer;
00239 
00240       MapWriter(const Map& _map, const Writer& _writer) 
00241         : map(_map), writer(_writer) {}
00242 
00243       virtual ~MapWriter() {}
00244 
00245       virtual void write(std::ostream& os, const Item& item) {
00246         Value value = map[item];
00247         writer.write(os, value);
00248       }
00249 
00250     };
00251 
00252 
00253     class ValueWriterBase {
00254     public:
00255       virtual ~ValueWriterBase() {}
00256       virtual void write(std::ostream&) = 0;
00257     };
00258 
00259     template <typename _Value, typename _Writer>
00260     class ValueWriter : public ValueWriterBase {
00261     public:
00262       typedef _Value Value;
00263       typedef _Writer Writer;
00264 
00265       ValueWriter(const Value& _value, const Writer& _writer)
00266         : value(_value), writer(_writer) {}
00267 
00268       virtual void write(std::ostream& os) {
00269         writer.write(os, value);
00270       }
00271     private:
00272       const Value& value;
00273       Writer writer;
00274     };
00275     
00276 
00277     template <typename _Item>
00278     class IdWriterBase {
00279     public:
00280       typedef _Item Item;
00281       virtual ~IdWriterBase() {}
00282       virtual void write(std::ostream&, const Item&) const = 0;
00283       virtual bool isIdWriter() const = 0;
00284     };
00285 
00286     template <typename _Item, typename _BoxedIdWriter>
00287     class IdWriter : public IdWriterBase<_Item> {
00288     public:
00289       typedef _Item Item;
00290       typedef _BoxedIdWriter BoxedIdWriter;
00291 
00292       const BoxedIdWriter& idWriter;
00293 
00294       IdWriter(const BoxedIdWriter& _idWriter) 
00295         : idWriter(_idWriter) {}
00296 
00297       virtual void write(std::ostream& os, const Item& item) const {
00298         idWriter.writeId(os, item);
00299       }
00300 
00301       virtual bool isIdWriter() const {
00302         return idWriter.isIdWriter();
00303       }
00304     };
00305   };
00306 
00325   template <typename _Graph, typename _Traits = DefaultWriterTraits>
00326   class NodeSetWriter : public CommonSectionWriterBase {
00327     typedef CommonSectionWriterBase Parent;
00328   public:
00329 
00330     typedef _Graph Graph;
00331     typedef _Traits Traits;
00332     typedef typename Graph::Node Node;
00333 
00340     NodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
00341                   const std::string& _id = std::string(), 
00342                   bool _forceIdMap = true) 
00343       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), 
00344         graph(_graph), id(_id) {}
00345 
00349     virtual ~NodeSetWriter() {
00350       typename MapWriters::iterator it;
00351       for (it = writers.begin(); it != writers.end(); ++it) {
00352         delete it->second;
00353       }
00354     }
00355 
00356   private:
00357     NodeSetWriter(const NodeSetWriter&);
00358     void operator=(const NodeSetWriter&);
00359   
00360   public:
00361 
00365     template <typename Map>
00366     NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
00367       return writeNodeMap<typename Traits::
00368         template Writer<typename Map::Value>, Map>(name, map);
00369     }
00370 
00374     template <typename Writer, typename Map>
00375     NodeSetWriter& writeNodeMap(std::string name, const Map& map, 
00376                             const Writer& writer = Writer()) {
00377       checkConcept<concept::ReadMap<Node, typename Map::Value>, Map>();
00378       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
00379       writers.push_back(
00380         make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
00381       return *this;
00382     }
00383 
00384   protected:
00385 
00389     virtual std::string header() {
00390       return "@nodeset " + id;
00391     }
00392 
00396     virtual void write(std::ostream& os) {
00397       for (int i = 0; i < (int)writers.size(); ++i) {
00398         if (writers[i].first == "id") {
00399           idMap = writers[i].second;
00400           forceIdMap = false;
00401           break;
00402         }
00403       }
00404       if (forceIdMap) {
00405         os << "id\t";
00406       }
00407       for (int i = 0; i < (int)writers.size(); ++i) {
00408         os << writers[i].first << '\t';
00409       }
00410       os << std::endl;
00411       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
00412         if (forceIdMap) {
00413           os << graph.id(it) << '\t';
00414         }
00415         for (int i = 0; i < (int)writers.size(); ++i) {
00416           writers[i].second->write(os, it);
00417           os << '\t';
00418         }
00419         os << std::endl;
00420       }
00421     }
00422 
00423   public:
00424 
00430     bool isIdWriter() const {
00431       return idMap != 0 || forceIdMap;
00432     }
00433 
00440     void writeId(std::ostream& os, const Node& item) const {
00441       if (forceIdMap) {
00442         os << graph.id(item);
00443       } else {
00444         idMap->write(os, item);
00445       }
00446     }
00447 
00448   private:
00449 
00450     typedef std::vector<std::pair<std::string, WriterBase<Node>*> > MapWriters;
00451     MapWriters writers;
00452 
00453     WriterBase<Node>* idMap;
00454     bool forceIdMap;
00455    
00456     typename SmartConstReference<Graph>::Type graph;   
00457     std::string id;
00458 
00459   };
00460 
00484   template <typename _Graph, typename _Traits = DefaultWriterTraits>
00485   class EdgeSetWriter : public CommonSectionWriterBase {
00486     typedef CommonSectionWriterBase Parent;
00487   public:
00488 
00489     typedef _Graph Graph;
00490     typedef _Traits Traits;
00491     typedef typename Graph::Node Node;
00492     typedef typename Graph::Edge Edge;
00493 
00501     template <typename NodeIdWriter>
00502     EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
00503                   const NodeIdWriter& _nodeIdWriter, 
00504                   const std::string& _id = std::string(),
00505                   bool _forceIdMap = true)
00506       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
00507         graph(_graph), id(_id) {
00508       checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
00509       nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
00510     } 
00511 
00515     virtual ~EdgeSetWriter() {
00516       typename MapWriters::iterator it;
00517       for (it = writers.begin(); it != writers.end(); ++it) {
00518         delete it->second;
00519       }
00520     }
00521 
00522   private:
00523     EdgeSetWriter(const EdgeSetWriter&);
00524     void operator=(const EdgeSetWriter&);
00525 
00526   public:
00527 
00531     template <typename Map>
00532     EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
00533       return writeEdgeMap<typename Traits::
00534         template Writer<typename Map::Value>, Map>(name, map);
00535     }
00536 
00540     template <typename Writer, typename Map>
00541     EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
00542                             const Writer& writer = Writer()) {
00543       checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
00544       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
00545       writers.push_back(
00546         make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
00547       return *this;
00548     }
00549 
00550   protected:
00551 
00555     virtual std::string header() {
00556       return "@edgeset " + id;
00557     }
00558 
00562     virtual void write(std::ostream& os) {
00563       if (!nodeIdWriter->isIdWriter()) {
00564         throw DataFormatError("Cannot find nodeset or ID map");
00565       }
00566       for (int i = 0; i < (int)writers.size(); ++i) {
00567         if (writers[i].first == "id") {
00568           idMap = writers[i].second;
00569           forceIdMap = false;
00570           break;
00571         }
00572       }
00573       os << "\t\t";
00574       if (forceIdMap) {
00575         os << "id\t";
00576       }
00577       for (int i = 0; i < (int)writers.size(); ++i) {
00578         os << writers[i].first << '\t';
00579       }
00580       os << std::endl;
00581       for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
00582         nodeIdWriter->write(os, graph.source(it));
00583         os << '\t';
00584         nodeIdWriter->write(os, graph.target(it));
00585         os << '\t';
00586         if (forceIdMap) {
00587           os << graph.id(it) << '\t';
00588         }
00589         for (int i = 0; i < (int)writers.size(); ++i) {
00590           writers[i].second->write(os, it);
00591           os << '\t';
00592         }
00593         os << std::endl;
00594       }
00595     }
00596 
00597   public:
00598 
00604     bool isIdWriter() const {
00605       return forceIdMap || idMap != 0;
00606     }
00607 
00614     void writeId(std::ostream& os, const Edge& item) const {
00615       if (forceIdMap) {
00616         os << graph.id(item);
00617       } else {
00618         idMap->write(os, item);
00619       }
00620     } 
00621 
00622   private:
00623 
00624     typedef std::vector<std::pair<std::string, WriterBase<Edge>*> > MapWriters;
00625     MapWriters writers;
00626 
00627     WriterBase<Edge>* idMap;
00628     bool forceIdMap;
00629    
00630     typename SmartConstReference<Graph>::Type graph;   
00631     std::string id;
00632 
00633     std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
00634   };
00635 
00665   template <typename _Graph, typename _Traits = DefaultWriterTraits>
00666   class UndirEdgeSetWriter : public CommonSectionWriterBase {
00667     typedef CommonSectionWriterBase Parent;
00668   public:
00669 
00670     typedef _Graph Graph;
00671     typedef _Traits Traits;
00672     typedef typename Graph::Node Node;
00673     typedef typename Graph::Edge Edge;
00674     typedef typename Graph::UndirEdge UndirEdge;
00675 
00683     template <typename NodeIdWriter>
00684     UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
00685                        const NodeIdWriter& _nodeIdWriter, 
00686                        const std::string& _id = std::string(),
00687                        bool _forceIdMap = true)
00688       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
00689         graph(_graph), id(_id) {
00690       checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
00691       nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
00692     } 
00693 
00697     virtual ~UndirEdgeSetWriter() {
00698       typename MapWriters::iterator it;
00699       for (it = writers.begin(); it != writers.end(); ++it) {
00700         delete it->second;
00701       }
00702     }
00703 
00704   private:
00705     UndirEdgeSetWriter(const UndirEdgeSetWriter&);
00706     void operator=(const UndirEdgeSetWriter&);
00707 
00708   public:
00709 
00713     template <typename Map>
00714     UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
00715       return writeUndirEdgeMap<typename Traits::
00716         template Writer<typename Map::Value>, Map>(name, map);
00717     }
00718 
00722     template <typename Writer, typename Map>
00723     UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, 
00724                                           const Writer& writer = Writer()) {
00725       checkConcept<concept::ReadMap<UndirEdge, typename Map::Value>, Map>();
00726       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
00727       writers.push_back(
00728         make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
00729       return *this;
00730     }
00731 
00735     template <typename Map>
00736     UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
00737       return writeEdgeMap<typename Traits::
00738         template Writer<typename Map::Value>, Map>(name, map);
00739     }
00740 
00744     template <typename Writer, typename Map>
00745     UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
00746                                      const Writer& writer = Writer()) {
00747       checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
00748       checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
00749       writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
00750       writeUndirEdge("-" + name, composeMap(backwardMap(graph), map), writer);
00751       return *this;
00752     }
00753 
00754   protected:
00755 
00759     virtual std::string header() {
00760       return "@undiredgeset " + id;
00761     }
00762 
00766     virtual void write(std::ostream& os) {
00767       if (!nodeIdWriter->isIdWriter()) {
00768         throw DataFormatError("Cannot find nodeset or ID map");
00769       }
00770       for (int i = 0; i < (int)writers.size(); ++i) {
00771         if (writers[i].first == "id") {
00772           idMap = writers[i].second;
00773           forceIdMap = false;
00774           break;
00775         }
00776       }
00777       os << "\t\t";
00778       if (forceIdMap) {
00779         os << "id\t";
00780       }
00781       for (int i = 0; i < (int)writers.size(); ++i) {
00782         os << writers[i].first << '\t';
00783       }
00784       os << std::endl;
00785       for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
00786         nodeIdWriter->write(os, graph.source(it));
00787         os << '\t';
00788         nodeIdWriter->write(os, graph.target(it));
00789         os << '\t';
00790         if (forceIdMap) {
00791           os << graph.id(it) << '\t';
00792         }
00793         for (int i = 0; i < (int)writers.size(); ++i) {
00794           writers[i].second->write(os, it);
00795           os << '\t';
00796         }
00797         os << std::endl;
00798       }
00799     }
00800 
00801   public:
00802 
00809     bool isIdWriter() const {
00810       return forceIdMap || idMap != 0;
00811     }
00812 
00819     void writeId(std::ostream& os, const UndirEdge& item) const {
00820       if (forceIdMap) {
00821         os << graph.id(item);
00822       } else {
00823         idMap->write(os, item);
00824       }
00825     } 
00826 
00834     void writeId(std::ostream& os, const Edge& item) const {
00835       if (graph.forward(item)) {
00836         os << "+ ";
00837       } else {
00838         os << "- ";
00839       }
00840       if (forceIdMap) {
00841         os << graph.id(item);
00842       } else {
00843         idMap->write(os, item);
00844       }
00845     } 
00846 
00847   private:
00848 
00849     typedef std::vector<std::pair<std::string, 
00850                                   WriterBase<UndirEdge>*> > MapWriters;
00851     MapWriters writers;
00852 
00853     WriterBase<UndirEdge>* idMap;
00854     bool forceIdMap;
00855    
00856     typename SmartConstReference<Graph>::Type graph;   
00857     std::string id;
00858 
00859     std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
00860   };
00861 
00872   template <typename _Graph>
00873   class NodeWriter : public CommonSectionWriterBase {
00874     typedef CommonSectionWriterBase Parent;
00875     typedef _Graph Graph;
00876     typedef typename Graph::Node Node;
00877   public:
00878     
00884     template <typename _IdWriter>
00885     NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
00886                const std::string& _id = std::string()) 
00887       : Parent(_writer), id(_id) {
00888       checkConcept<_writer_bits::ItemIdWriter<Node>, _IdWriter>();
00889       idWriter.reset(new IdWriter<Node, _IdWriter>(_idWriter));
00890     }
00891 
00892 
00896     virtual ~NodeWriter() {}
00897 
00898   private:
00899     NodeWriter(const NodeWriter&);
00900     void operator=(const NodeWriter&);
00901 
00902   public:
00903 
00907     void writeNode(const std::string& name, const Node& item) {
00908       writers.push_back(make_pair(name, &item));
00909     }
00910 
00911   protected:
00912 
00917     virtual std::string header() {
00918       return "@nodes " + id;
00919     }
00920 
00924     virtual void write(std::ostream& os) {
00925       if (!idWriter->isIdWriter()) {
00926         throw DataFormatError("Cannot find nodeset or ID map");
00927       }
00928       for (int i = 0; i < (int)writers.size(); ++i) {
00929         os << writers[i].first << ' ';
00930         idWriter->write(os, *(writers[i].second));
00931         os << std::endl;
00932       }
00933     }
00934     
00935   private:
00936 
00937     std::string id;
00938 
00939     typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
00940     NodeWriters writers;
00941     std::auto_ptr<IdWriterBase<Node> > idWriter;
00942   };
00943 
00954   template <typename _Graph>
00955   class EdgeWriter : public CommonSectionWriterBase {
00956     typedef CommonSectionWriterBase Parent;
00957     typedef _Graph Graph;
00958     typedef typename Graph::Edge Edge;
00959   public:
00960     
00966     template <typename _IdWriter>
00967     EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
00968                const std::string& _id = std::string()) 
00969       : Parent(_writer), id(_id) {
00970       checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
00971       idWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
00972     }
00973 
00977     virtual ~EdgeWriter() {}
00978   private:
00979     EdgeWriter(const EdgeWriter&);
00980     void operator=(const EdgeWriter&);
00981 
00982   public:
00983 
00987     void writeEdge(const std::string& name, const Edge& item) {
00988       writers.push_back(make_pair(name, &item));
00989     }
00990 
00991   protected:
00992 
00997     virtual std::string header() {
00998       return "@edges " + id;
00999     }
01000 
01004     virtual void write(std::ostream& os) {
01005       if (!idWriter->isIdWriter()) {
01006         throw DataFormatError("Cannot find edgeset or ID map");
01007       }
01008       for (int i = 0; i < (int)writers.size(); ++i) {
01009         os << writers[i].first << ' ';
01010         idWriter->write(os, *(writers[i].second));
01011         os << std::endl;
01012       }
01013     }
01014     
01015   private:
01016 
01017     std::string id;
01018 
01019     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
01020     EdgeWriters writers;
01021 
01022     std::auto_ptr<IdWriterBase<Edge> > idWriter;
01023   };
01024 
01035   template <typename _Graph>
01036   class UndirEdgeWriter : public CommonSectionWriterBase {
01037     typedef CommonSectionWriterBase Parent;
01038     typedef _Graph Graph;
01039     typedef typename Graph::Node Node;
01040     typedef typename Graph::Edge Edge;
01041     typedef typename Graph::UndirEdge UndirEdge;
01042   public:
01043     
01050     template <typename _IdWriter>
01051     UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
01052                const std::string& _id = std::string()) 
01053       : Parent(_writer), id(_id) {
01054       checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
01055       checkConcept<_writer_bits::ItemIdWriter<UndirEdge>, _IdWriter>();
01056       undirEdgeIdWriter.reset(new IdWriter<UndirEdge, _IdWriter>(_idWriter));
01057       edgeIdWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
01058     }
01059 
01063     virtual ~UndirEdgeWriter() {}
01064   private:
01065     UndirEdgeWriter(const UndirEdgeWriter&);
01066     void operator=(const UndirEdgeWriter&);
01067 
01068   public:
01069 
01073     void writeEdge(const std::string& name, const Edge& item) {
01074       edgeWriters.push_back(make_pair(name, &item));
01075     }
01076 
01080     void writeUndirEdge(const std::string& name, const UndirEdge& item) {
01081       undirEdgeWriters.push_back(make_pair(name, &item));
01082     }
01083 
01084   protected:
01085 
01090     virtual std::string header() {
01091       return "@undiredges " + id;
01092     }
01093 
01097     virtual void write(std::ostream& os) {
01098       if (!edgeIdWriter->isIdWriter()) {
01099         throw DataFormatError("Cannot find undirected edgeset or ID map");
01100       }
01101       if (!undirEdgeIdWriter->isIdWriter()) {
01102         throw DataFormatError("Cannot find undirected edgeset or ID map");
01103       }
01104       for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
01105         os << undirEdgeWriters[i].first << ' ';
01106         undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));
01107         os << std::endl;
01108       }
01109       for (int i = 0; i < (int)edgeWriters.size(); ++i) {
01110         os << edgeWriters[i].first << ' ';
01111         edgeIdWriter->write(os, *(edgeWriters[i].second));
01112         os << std::endl;
01113       }
01114     }
01115     
01116   private:
01117 
01118     std::string id;
01119 
01120     typedef std::vector<std::pair<std::string, 
01121                                   const UndirEdge*> > UndirEdgeWriters;
01122     UndirEdgeWriters undirEdgeWriters;
01123     std::auto_ptr<IdWriterBase<UndirEdge> > undirEdgeIdWriter;
01124 
01125     typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
01126     EdgeWriters edgeWriters;
01127     std::auto_ptr<IdWriterBase<Edge> > edgeIdWriter;
01128 
01129   };
01130 
01142   template <typename _Traits = DefaultWriterTraits>
01143   class AttributeWriter : public CommonSectionWriterBase {
01144     typedef CommonSectionWriterBase Parent;
01145     typedef _Traits Traits; 
01146   public:
01151     AttributeWriter(LemonWriter& _writer, 
01152                     const std::string& _id = std::string()) 
01153       : Parent(_writer), id(_id) {}
01154 
01158     virtual ~AttributeWriter() {
01159       typename Writers::iterator it;
01160       for (it = writers.begin(); it != writers.end(); ++it) {
01161         delete it->second;
01162       }
01163     }
01164 
01165   private:
01166     AttributeWriter(const AttributeWriter&);
01167     void operator=(AttributeWriter&);
01168 
01169   public:
01173     template <typename Value>
01174     AttributeWriter& writeAttribute(const std::string& id, 
01175                                     const Value& value) {
01176       return 
01177         writeAttribute<typename Traits::template Writer<Value> >(id, value);
01178     }
01179 
01183     template <typename Writer, typename Value>
01184     AttributeWriter& writeAttribute(const std::string& name, 
01185                                     const Value& value,
01186                                     const Writer& writer = Writer()) {
01187       checkConcept<_writer_bits::ItemWriter<Value>, Writer>();
01188       writers.push_back(make_pair(name, new ValueWriter<Value, Writer>
01189                                (value, writer)));
01190       return *this;
01191     }
01192 
01193   protected:
01194 
01198     std::string header() {
01199       return "@attributes " + id;
01200     }
01201 
01205     void write(std::ostream& os) {
01206       typename Writers::iterator it;
01207       for (it = writers.begin(); it != writers.end(); ++it) {
01208         os << it->first << ' ';
01209         it->second->write(os);
01210         os << std::endl;
01211       }
01212     }    
01213 
01214   private:
01215     std::string id;
01216 
01217     typedef std::vector<std::pair<std::string, ValueWriterBase*> > Writers;
01218     Writers writers;  
01219   };
01220 
01221 
01222 }
01223 #endif

Generated on Sat Aug 27 14:14:53 2005 for LEMON by  doxygen 1.4.4