COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lemon_writer.h @ 2476:059dcdda37c5

Last change on this file since 2476:059dcdda37c5 was 2467:2025a571895e, checked in by Balazs Dezso, 12 years ago

PathNodeIt?

PathWriter/Reader? structures
Distinict MapSet? readers and writers

File size: 61.5 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
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.
12 *
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
15 * purpose.
16 *
17 */
18
19///\ingroup lemon_io
20///\file
21///\brief Lemon Format writer.
22
23#ifndef LEMON_LEMON_WRITER_H
24#define LEMON_LEMON_WRITER_H
25
26#include <iostream>
27#include <fstream>
28#include <string>
29#include <vector>
30#include <algorithm>
31#include <map>
32#include <memory>
33
34#include <lemon/error.h>
35#include <lemon/bits/invalid.h>
36#include <lemon/graph_utils.h>
37#include <lemon/bits/item_writer.h>
38#include <lemon/bits/utility.h>
39#include <lemon/maps.h>
40#include <lemon/dim2.h>
41
42#include <lemon/concept_check.h>
43#include <lemon/concepts/maps.h>
44
45
46namespace lemon {
47
48  namespace _writer_bits {
49   
50    template <typename T>
51    bool operator<(T, T) {
52      throw DataFormatError("Label is not comparable");
53    }
54
55    template <typename T>
56    struct Less {
57      bool operator()(const T& p, const T& q) const {
58        return p < q;
59      }
60    };
61
62    template <typename Map>
63    struct ComposeLess {
64      ComposeLess(const Map& _map) : map(_map), less() {}
65
66      bool operator()(const typename Map::Key& p,
67                      const typename Map::Key& q) const {
68        return less(map[p], map[q]);
69      }
70      const Map& map;
71      Less<typename Map::Value> less;
72    };
73
74    template <typename UGraph, typename Map>
75    struct UEdgeComposeLess {
76      UEdgeComposeLess(const UGraph& _ugraph, const Map& _map)
77        : ugraph(_ugraph), map(_map), less() {}
78
79      bool operator()(const typename UGraph::Edge& p,
80                      const typename UGraph::Edge& q) const {
81        return p != q ? less(map[p], map[q]) :
82          (!ugraph.direction(p) && ugraph.direction(q));
83      }
84
85      const UGraph& ugraph;
86      const Map& map;
87      Less<typename Map::Value> less;
88    };
89
90    template <typename Item>
91    class ItemLabelWriter {
92    public:
93
94      bool isLabelWriter() { return true; }
95
96      void writeLabel(std::ostream&, const Item&) {}
97     
98      template <class _ItemLabelWriter>
99      struct Constraints {
100        void constraints() {
101          bool b = writer.isLabelWriter();
102          ignore_unused_variable_warning(b);
103          writer.writeLabel(os, item);
104        }
105        _ItemLabelWriter& writer;
106        std::ostream& os;
107        const Item& item;
108      };
109
110    };
111
112    template <typename Item>
113    class ItemWriter {
114    public:
115
116      void write(std::ostream&, const Item&) {}
117     
118      template <class _ItemWriter>
119      struct Constraints {
120        void constraints() {
121          writer.write(os, item);
122        }
123        _ItemWriter& writer;
124        std::ostream& os;
125        const Item& item;
126      };
127
128    };
129
130    template <typename Map>
131    struct Ref { typedef const Map& Type; };
132
133    template <typename Graph, typename Map>
134    class ForwardComposeMap {
135    public:
136      typedef typename Graph::UEdge Key;
137      typedef typename Map::Value Value;
138
139      ForwardComposeMap(const Graph& _graph, const Map& _map)
140        : graph(_graph), map(_map) {}
141     
142      Value operator[](const Key& key) const {
143        return map[graph.direct(key, true)];
144      }
145
146    private:
147      typename Ref<Map>::Type map;
148      const Graph& graph;
149    };
150
151    template <typename Graph, typename Map>
152    ForwardComposeMap<Graph, Map>
153    forwardComposeMap(const Graph& graph, const Map& map) {
154      return ForwardComposeMap<Graph, Map>(graph, map);
155    }
156
157    template <typename Graph, typename Map>
158    class BackwardComposeMap {
159    public:
160      typedef typename Graph::UEdge Key;
161      typedef typename Map::Value Value;
162
163      BackwardComposeMap(const Graph& _graph, const Map& _map)
164        : graph(_graph), map(_map) {}
165     
166      Value operator[](const Key& key) const {
167        return map[graph.direct(key, false)];
168      }
169
170    private:
171      typename Ref<Map>::Type map;
172      const Graph& graph;
173    };
174
175    template <typename Graph, typename Map>
176    BackwardComposeMap<Graph, Map>
177    backwardComposeMap(const Graph& graph, const Map& map) {
178      return BackwardComposeMap<Graph, Map>(graph, map);
179    }
180
181    template <typename Graph, typename Map>
182    struct Ref<ForwardComposeMap<Graph, Map> > {
183      typedef ForwardComposeMap<Graph, Map> Type;
184    };
185
186    template <typename Graph, typename Map>
187    struct Ref<BackwardComposeMap<Graph, Map> > {
188      typedef BackwardComposeMap<Graph, Map> Type;
189    };
190
191    template <typename Map>
192    struct Ref<dim2::XMap<Map> > {
193      typedef dim2::XMap<Map> Type;
194    };
195    template <typename Map>
196    struct Ref<dim2::ConstXMap<Map> > {
197      typedef dim2::ConstXMap<Map> Type;
198    };
199
200    template <typename Map>
201    struct Ref<dim2::YMap<Map> > {
202      typedef dim2::YMap<Map> Type;
203    };
204    template <typename Map>
205    struct Ref<dim2::ConstYMap<Map> > {
206      typedef dim2::ConstYMap<Map> Type;
207    };
208
209
210    template <typename _Item>   
211    class MapWriterBase {
212    public:
213      typedef _Item Item;
214
215      virtual ~MapWriterBase() {}
216
217      virtual void write(std::ostream& os, const Item& item) const = 0;
218      virtual void sort(std::vector<Item>&) const = 0;
219    };
220
221
222    template <typename _Item, typename _Map, typename _Writer>
223    class MapWriter : public MapWriterBase<_Item> {
224    public:
225      typedef _Map Map;
226      typedef _Writer Writer;
227      typedef typename Writer::Value Value;
228      typedef _Item Item;
229     
230      typename _writer_bits::Ref<Map>::Type map;
231      Writer writer;
232
233      MapWriter(const Map& _map, const Writer& _writer)
234        : map(_map), writer(_writer) {}
235
236      virtual ~MapWriter() {}
237
238      virtual void write(std::ostream& os, const Item& item) const {
239        Value value = map[item];
240        writer.write(os, value);
241      }
242
243      virtual void sort(std::vector<Item>& items) const {
244        ComposeLess<Map> less(map);
245        std::sort(items.begin(), items.end(), less);
246      }
247
248    };
249
250    template <typename _UGraph>   
251    class UEdgeMapWriterBase {
252    public:
253      typedef typename _UGraph::Edge Edge;
254      typedef typename _UGraph::UEdge UEdge;
255
256      typedef UEdge Item;
257
258      virtual ~UEdgeMapWriterBase() {}
259
260      virtual void write(std::ostream& os, const Item& item) const = 0;
261      virtual void sort(const _UGraph&, std::vector<Edge>&) const = 0;
262      virtual void sort(std::vector<UEdge>&) const = 0;
263    };
264
265
266    template <typename _UGraph, typename _Map, typename _Writer>
267    class UEdgeMapWriter : public UEdgeMapWriterBase<_UGraph> {
268    public:
269      typedef _Map Map;
270      typedef _Writer Writer;
271      typedef typename Writer::Value Value;
272
273      typedef typename _UGraph::Edge Edge;
274      typedef typename _UGraph::UEdge UEdge;
275      typedef UEdge Item;
276     
277      typename _writer_bits::Ref<Map>::Type map;
278      Writer writer;
279
280      UEdgeMapWriter(const Map& _map, const Writer& _writer)
281        : map(_map), writer(_writer) {}
282
283      virtual ~UEdgeMapWriter() {}
284
285      virtual void write(std::ostream& os, const Item& item) const {
286        Value value = map[item];
287        writer.write(os, value);
288      }
289
290      virtual void sort(const _UGraph& ugraph, std::vector<Edge>& items) const {
291        UEdgeComposeLess<_UGraph, Map> less(ugraph, map);
292        std::sort(items.begin(), items.end(), less);
293      }
294
295      virtual void sort(std::vector<UEdge>& items) const {
296        ComposeLess<Map> less(map);
297        std::sort(items.begin(), items.end(), less);
298      }
299
300    };
301
302
303    class ValueWriterBase {
304    public:
305      virtual ~ValueWriterBase() {}
306      virtual void write(std::ostream&) = 0;
307    };
308
309    template <typename _Value, typename _Writer>
310    class ValueWriter : public ValueWriterBase {
311    public:
312      typedef _Value Value;
313      typedef _Writer Writer;
314
315      ValueWriter(const Value& _value, const Writer& _writer)
316        : value(_value), writer(_writer) {}
317
318      virtual void write(std::ostream& os) {
319        writer.write(os, value);
320      }
321    private:
322      const Value& value;
323      Writer writer;
324    };
325   
326
327    template <typename _Item>
328    class LabelWriterBase {
329    public:
330      typedef _Item Item;
331      virtual ~LabelWriterBase() {}
332      virtual void write(std::ostream&, const Item&) const = 0;
333      virtual void sort(std::vector<Item>&) const = 0;
334      virtual bool isLabelWriter() const = 0;
335      virtual LabelWriterBase* clone() const = 0;
336    };
337
338    template <typename _Item, typename _BoxedLabelWriter>
339    class LabelWriter : public LabelWriterBase<_Item> {
340    public:
341      typedef _Item Item;
342      typedef _BoxedLabelWriter BoxedLabelWriter;
343
344      const BoxedLabelWriter& labelWriter;
345
346      LabelWriter(const BoxedLabelWriter& _labelWriter)
347        : labelWriter(_labelWriter) {}
348
349      virtual void write(std::ostream& os, const Item& item) const {
350        labelWriter.writeLabel(os, item);
351      }
352      virtual void sort(std::vector<Item>& items) const {
353        labelWriter.sortByLabel(items);
354      }
355
356      virtual bool isLabelWriter() const {
357        return labelWriter.isLabelWriter();
358      }
359
360      virtual LabelWriter* clone() const {
361        return new LabelWriter(labelWriter);
362      }
363    };
364
365  }
366
367  /// \ingroup lemon_io
368  /// \brief Lemon Format writer class.
369  ///
370  /// The Lemon Format contains several sections. We do not want to
371  /// determine what sections are in a lemon file we give only a framework
372  /// to write a section oriented format.
373  ///
374  /// In the Lemon Format each section starts with a line contains a \c \@
375  /// character on the first not white space position. This line is the
376  /// header line of the section. Each next lines belong to this section
377  /// while it does not starts with \c \@ character. This line can start a
378  /// new section or if it can close the file with the \c \@end line.
379  /// The file format ignore the empty lines and it may contain comments
380  /// started with a \c # character to the end of the line.
381  ///
382  /// The framework provides an abstract LemonWriter::SectionWriter class
383  /// what defines the interface of a SectionWriter. The SectionWriter
384  /// has the \c header() member function what gives back the header of the
385  /// section. After that it will be called the \c write() member which
386  /// should write the content of the section.
387  ///
388  /// \relates GraphWriter
389  /// \relates NodeSetWriter
390  /// \relates EdgeSetWriter
391  /// \relates NodesWriter
392  /// \relates EdgesWriter
393  /// \relates AttributeWriter
394  class LemonWriter {
395  public:
396
397    /// \brief Abstract base class for writing a section.
398    ///
399    /// This class has an \c header() member function what gives back
400    /// the header line of the section. The \c write() member should
401    /// write the content of the section to the stream.
402    class SectionWriter {
403      friend class LemonWriter;
404    protected:
405      /// \brief Constructor for SectionWriter.
406      ///
407      /// Constructor for SectionWriter. It attach this writer to
408      /// the given LemonWriter.
409      SectionWriter(LemonWriter& writer) {
410        writer.attach(*this);
411      }
412     
413      virtual ~SectionWriter() {}
414
415      /// \brief The header of section.
416      ///
417      /// It gives back the header of the section.
418      virtual std::string header() = 0;
419
420      /// \brief Writer function of the section.
421      ///
422      /// Write the content of the section.
423      virtual void write(std::ostream& os) = 0;
424     
425      /// \brief Gives back true when the section should be written.
426      ///
427      /// Gives back true when the section should be written.
428      virtual bool valid() { return true; }
429    };
430
431    /// \brief Constructor for LemonWriter.
432    ///
433    /// Constructor for LemonWriter which writes to the given stream.
434    LemonWriter(std::ostream& _os)
435      : os(&_os), own_os(false) {}
436
437    /// \brief Constructor for LemonWriter.
438    ///
439    /// Constructor for LemonWriter which writes to the given file.
440    LemonWriter(const std::string& filename)
441      : os(0), own_os(true) {
442      os = new std::ofstream(filename.c_str());
443    }
444
445    /// \brief Desctructor for LemonWriter.
446    ///
447    /// Desctructor for LemonWriter.
448    ~LemonWriter() {
449      if (own_os) {
450        delete os;
451      }
452    }
453
454  private:
455    LemonWriter(const LemonWriter&);
456    void operator=(const LemonWriter&);
457
458    void attach(SectionWriter& writer) {
459      writers.push_back(&writer);
460    }
461
462  public:
463
464    /// \brief Executes the LemonWriter.
465    ///
466    /// It executes the LemonWriter.
467    void run() {
468      SectionWriters::iterator it;
469      for (it = writers.begin(); it != writers.end(); ++it) {
470        if ((*it)->valid()) {
471          *os << (*it)->header() << std::endl;
472          (*it)->write(*os);
473        }
474      }
475      *os << "@end" << std::endl;
476    }
477
478
479  private:
480
481    std::ostream* os;
482    bool own_os;
483
484    typedef std::vector<SectionWriter*> SectionWriters;
485    SectionWriters writers;
486
487  };
488
489  /// \ingroup section_io
490  /// \brief SectionWriter for writing a graph's nodeset.
491  ///
492  /// The lemon format can store multiple graph nodesets with several maps.
493  /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but
494  /// the \c nodeset_name may be empty.
495  ///
496  /// The first line of the section contains the names of the maps separated
497  /// with white spaces. Each next lines describes a node in the nodeset, and
498  /// contains the mapped values for each map.
499  ///
500  /// If the nodeset contains an \c "label" named map then it will be regarded
501  /// as label map. This map should contain only unique values and when the
502  /// \c writeLabel() member will be called with a node it will write it's
503  /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
504  /// then the label map will be the id in the graph. In addition if the
505  /// the \c _forceSort is true then the writer will write the edges
506  /// sorted by the labels.
507  ///
508  /// \relates LemonWriter
509  template <typename _Graph, typename _Traits = DefaultWriterTraits>
510  class NodeSetWriter : public LemonWriter::SectionWriter {
511    typedef LemonWriter::SectionWriter Parent;
512  public:
513
514    typedef _Graph Graph;
515    typedef _Traits Traits;
516    typedef typename Graph::Node Node;
517
518    /// \brief Constructor.
519    ///
520    /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
521    /// attach it into the given LemonWriter. If the \c _forceLabelMap
522    /// parameter is true then the writer will write own label map when
523    /// the user does not give "label" named map. In addition if the
524    /// the \c _forceSort is true then the writer will write the edges
525    /// sorted by the labels.
526    NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
527                  const std::string& _name = std::string(),
528                  bool _forceLabelMap = true, bool _forceSort = true)
529      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
530        forceSort(_forceSort), graph(_graph), name(_name) {}
531
532    /// \brief Destructor.
533    ///
534    /// Destructor for NodeSetWriter.
535    virtual ~NodeSetWriter() {
536      typename MapWriters::iterator it;
537      for (it = writers.begin(); it != writers.end(); ++it) {
538        delete it->second;
539      }
540    }
541
542  private:
543    NodeSetWriter(const NodeSetWriter&);
544    void operator=(const NodeSetWriter&);
545 
546  public:
547
548    /// \brief Add a new node map writer command for the writer.
549    ///
550    /// Add a new node map writer command for the writer.
551    template <typename Map>
552    NodeSetWriter& writeNodeMap(std::string label, const Map& map) {
553      return writeNodeMap<typename Traits::
554        template Writer<typename Map::Value>, Map>(label, map);
555    }
556
557    /// \brief Add a new node map writer command for the writer.
558    ///
559    /// Add a new node map writer command for the writer.
560    template <typename ItemWriter, typename Map>
561    NodeSetWriter& writeNodeMap(std::string label, const Map& map,
562                            const ItemWriter& iw = ItemWriter()) {
563      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
564      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
565      writers.push_back(
566        make_pair(label, new _writer_bits::
567                  MapWriter<Node, Map, ItemWriter>(map, iw)));
568      return *this;
569    }
570
571  protected:
572
573    /// \brief The header of the section.
574    ///
575    /// It gives back the header of the section.
576    virtual std::string header() {
577      return "@nodeset " + name;
578    }
579
580    /// \brief  Writer function of the section.
581    ///
582    /// Write the content of the section.
583    virtual void write(std::ostream& os) {
584      for (int i = 0; i < int(writers.size()); ++i) {
585        if (writers[i].first == "label") {
586          labelMap = writers[i].second;
587          forceLabelMap = false;
588          break;
589        }
590      }
591      std::vector<Node> items;
592      for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
593        items.push_back(it);
594      }
595      if (forceSort) {
596        if (labelMap) {
597          labelMap->sort(items);
598        } else {
599          typedef IdMap<Graph, Node> Map;
600          Map map(graph);
601          _writer_bits::ComposeLess<Map> less(map);
602          std::sort(items.begin(), items.end(), less);
603        }
604      }
605      if (forceLabelMap) {
606        os << "label\t";
607      }
608      for (int i = 0; i < int(writers.size()); ++i) {
609        os << writers[i].first << '\t';
610      }
611      os << std::endl;
612      for (typename std::vector<Node>::iterator it = items.begin();
613           it != items.end(); ++it) {
614        if (forceLabelMap) {
615          os << graph.id(*it) << '\t';
616        }
617        for (int i = 0; i < int(writers.size()); ++i) {
618          writers[i].second->write(os, *it);
619          os << '\t';
620        }
621        os << std::endl;
622      }
623    }
624
625  public:
626
627    /// \brief Returns true if the nodeset can write the labels of the nodes.
628    ///
629    /// Returns true if the nodeset can write the labels of the nodes.
630    /// It is possible only if a "label" named map was written or the
631    /// \c _forceLabelMap constructor parameter was true.
632    bool isLabelWriter() const {
633      return labelMap != 0 || forceLabelMap;
634    }
635
636    /// \brief Write the label of the given node.
637    ///
638    /// It writes the label of the given node. If there was written a "label"
639    /// named map then it will write the map value belongs to the node.
640    /// Otherwise if the \c forceLabel parameter was true it will write
641    /// its label in the graph.
642    void writeLabel(std::ostream& os, const Node& item) const {
643      if (forceLabelMap) {
644        os << graph.id(item);
645      } else {
646        labelMap->write(os, item);
647      }
648    }
649
650    /// \brief Sorts the given node vector by label.
651    ///
652    /// Sorts the given node vector by label. If there was written an
653    /// "label" named map then the vector will be sorted by the values
654    /// of this map. Otherwise if the \c forceLabel parameter was true
655    /// it will be sorted by its id in the graph.
656    void sortByLabel(std::vector<Node>& nodes) const {
657      if (labelMap) {
658        labelMap->sort(nodes);
659      } else {
660        typedef IdMap<Graph, Node> Map;
661        Map map(graph);
662        _writer_bits::ComposeLess<Map> less(map);
663        std::sort(nodes.begin(), nodes.end(), less);
664      }
665    }
666
667  private:
668
669    typedef std::vector<std::pair<std::string, _writer_bits::
670                                  MapWriterBase<Node>*> > MapWriters;
671    MapWriters writers;
672
673    _writer_bits::MapWriterBase<Node>* labelMap;
674    bool forceLabelMap;
675    bool forceSort;
676   
677    const Graph& graph;   
678    std::string name;
679
680  };
681
682  /// \ingroup section_io
683  /// \brief SectionWriter for writing a graph's edgesets.
684  ///
685  /// The lemon format can store multiple graph edgesets with several maps.
686  /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but
687  /// the \c edgeset_name may be empty.
688  ///
689  /// The first line of the section contains the names of the maps separated
690  /// with white spaces. Each next lines describes a edge in the edgeset. The
691  /// line contains the source and the target nodes' label and the mapped
692  /// values for each map.
693  ///
694  /// If the edgeset contains an \c "label" named map then it will be regarded
695  /// as label map. This map should contain only unique values and when the
696  /// \c writeLabel() member will be called with an edge it will write it's
697  /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
698  /// then the label map will be the id in the graph. In addition if the
699  /// the \c _forceSort is true then the writer will write the edges
700  /// sorted by the labels.
701  ///
702  /// The edgeset writer needs a node label writer to identify which nodes
703  /// have to be connected. If a NodeSetWriter can write the nodes' label,
704  /// it will be able to use with this class.
705  ///
706  /// \relates LemonWriter
707  template <typename _Graph, typename _Traits = DefaultWriterTraits>
708  class EdgeSetWriter : public LemonWriter::SectionWriter {
709    typedef LemonWriter::SectionWriter Parent;
710  public:
711
712    typedef _Graph Graph;
713    typedef _Traits Traits;
714    typedef typename Graph::Node Node;
715    typedef typename Graph::Edge Edge;
716
717    /// \brief Constructor.
718    ///
719    /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter
720    /// and attach it into the given LemonWriter. It will write node
721    /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
722    /// parameter is true then the writer will write own label map if
723    /// the user does not give "label" named map. In addition if the
724    /// the \c _forceSort is true then the writer will write the
725    /// edges sorted by the labels.
726    template <typename NodeLabelWriter>
727    EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
728                  const NodeLabelWriter& _nodeLabelWriter,
729                  const std::string& _name = std::string(),
730                  bool _forceLabelMap = true, bool _forceSort = true)
731      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
732        forceSort(_forceSort), graph(_graph), name(_name) {
733      checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
734      nodeLabelWriter.reset(new _writer_bits::
735                         LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
736    }
737
738    /// \brief Destructor.
739    ///
740    /// Destructor for EdgeSetWriter.
741    virtual ~EdgeSetWriter() {
742      typename MapWriters::iterator it;
743      for (it = writers.begin(); it != writers.end(); ++it) {
744        delete it->second;
745      }
746    }
747
748  private:
749    EdgeSetWriter(const EdgeSetWriter&);
750    void operator=(const EdgeSetWriter&);
751
752  public:
753
754    /// \brief Add a new edge map writer command for the writer.
755    ///
756    /// Add a new edge map writer command for the writer.
757    template <typename Map>
758    EdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
759      return writeEdgeMap<typename Traits::
760        template Writer<typename Map::Value>, Map>(label, map);
761    }
762
763    /// \brief Add a new edge map writer command for the writer.
764    ///
765    /// Add a new edge map writer command for the writer.
766    template <typename ItemWriter, typename Map>
767    EdgeSetWriter& writeEdgeMap(std::string label, const Map& map,
768                            const ItemWriter& iw = ItemWriter()) {
769      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
770      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
771      writers.push_back(
772        make_pair(label, new _writer_bits::
773                  MapWriter<Edge, Map, ItemWriter>(map, iw)));
774      return *this;
775    }
776
777  protected:
778
779    /// \brief The header of the section.
780    ///
781    /// It gives back the header of the section.
782    virtual std::string header() {
783      return "@edgeset " + name;
784    }
785
786    /// \brief  Writer function of the section.
787    ///
788    /// Write the content of the section.
789    virtual void write(std::ostream& os) {
790      if (!nodeLabelWriter->isLabelWriter()) {
791        throw DataFormatError("Cannot find nodeset or label map");
792      }
793      for (int i = 0; i < int(writers.size()); ++i) {
794        if (writers[i].first == "label") {
795          labelMap = writers[i].second;
796          forceLabelMap = false;
797          break;
798        }
799      }
800      std::vector<Edge> items;
801      for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
802        items.push_back(it);
803      }
804      if (forceSort) {
805        if (labelMap) {
806          labelMap->sort(items);
807        } else {
808          typedef IdMap<Graph, Edge> Map;
809          Map map(graph);
810          _writer_bits::ComposeLess<Map> less(map);
811          std::sort(items.begin(), items.end(), less);
812        }
813      }
814      os << "\t\t";
815      if (forceLabelMap) {
816        os << "label\t";
817      }
818      for (int i = 0; i < int(writers.size()); ++i) {
819        os << writers[i].first << '\t';
820      }
821      os << std::endl;
822      for (typename std::vector<Edge>::iterator it = items.begin();
823           it != items.end(); ++it) {
824        nodeLabelWriter->write(os, graph.source(*it));
825        os << '\t';
826        nodeLabelWriter->write(os, graph.target(*it));
827        os << '\t';
828        if (forceLabelMap) {
829          os << graph.id(*it) << '\t';
830        }
831        for (int i = 0; i < int(writers.size()); ++i) {
832          writers[i].second->write(os, *it);
833          os << '\t';
834        }
835        os << std::endl;
836      }
837    }
838
839  public:
840
841    /// \brief Returns true if the edgeset can write the labels of the edges.
842    ///
843    /// Returns true if the edgeset can write the labels of the edges.
844    /// It is possible only if a "label" named map was written or the
845    /// \c _forceLabelMap constructor parameter was true.
846    bool isLabelWriter() const {
847      return forceLabelMap || labelMap != 0;
848    }
849
850    /// \brief Write the label of the given edge.
851    ///
852    /// It writes the label of the given edge. If there was written a "label"
853    /// named map then it will write the map value belongs to the edge.
854    /// Otherwise if the \c forceLabel parameter was true it will write
855    /// its label in the graph.
856    void writeLabel(std::ostream& os, const Edge& item) const {
857      if (forceLabelMap) {
858        os << graph.id(item);
859      } else {
860        labelMap->write(os, item);
861      }
862    }
863
864    /// \brief Sorts the given edge vector by label.
865    ///
866    /// Sorts the given edge vector by label. If there was written an
867    /// "label" named map then the vector will be sorted by the values
868    /// of this map. Otherwise if the \c forceLabel parameter was true
869    /// it will be sorted by its id in the graph.
870    void sortByLabel(std::vector<Edge>& edges) const {
871      if (labelMap) {
872        labelMap->sort(edges);
873      } else {
874        typedef IdMap<Graph, Edge> Map;
875        Map map(graph);
876        _writer_bits::ComposeLess<Map> less(map);
877        std::sort(edges.begin(), edges.end(), less);
878      }
879    }
880
881  private:
882
883    typedef std::vector<std::pair<std::string, _writer_bits::
884                                  MapWriterBase<Edge>*> > MapWriters;
885    MapWriters writers;
886
887    _writer_bits::MapWriterBase<Edge>* labelMap;
888    bool forceLabelMap;
889    bool forceSort;
890   
891    const Graph& graph;   
892    std::string name;
893
894    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
895  };
896
897  /// \ingroup section_io
898  /// \brief SectionWriter for writing a undirected edgeset.
899  ///
900  /// The lemon format can store multiple undirected edgesets with several
901  /// maps. The undirected edgeset section's header line is \c \@uedgeset
902  /// \c uedgeset_name, but the \c uedgeset_name may be empty.
903  ///
904  /// The first line of the section contains the names of the maps separated
905  /// with white spaces. Each next lines describes an undirected edge in the
906  /// edgeset. The line contains the two connected nodes' label and the mapped
907  /// values for each undirected map.
908  ///
909  /// The section can handle the directed as a syntactical sugar. Two
910  /// undirected edge map describes one directed edge map. This two maps
911  /// are the forward map and the backward map and the names of this map
912  /// is near the same just with a prefix \c '+' or \c '-' character
913  /// difference.
914  ///
915  /// If the edgeset contains an \c "label" named map then it will be
916  /// regarded as label map. This map should contain only unique
917  /// values and when the \c writeLabel() member will be called with
918  /// an undirected edge it will write it's label. Otherwise if the \c
919  /// _forceLabelMap constructor parameter is true then the label map
920  /// will be the id in the graph.  In addition if the the \c
921  /// _forceSort is true then the writer will write the edges sorted
922  /// by the labels.
923  ///
924  /// The undirected edgeset writer needs a node label writer to identify
925  /// which nodes have to be connected. If a NodeSetWriter can write the
926  /// nodes' label, it will be able to use with this class.
927  ///
928  /// \relates LemonWriter
929  template <typename _Graph, typename _Traits = DefaultWriterTraits>
930  class UEdgeSetWriter : public LemonWriter::SectionWriter {
931    typedef LemonWriter::SectionWriter Parent;
932  public:
933
934    typedef _Graph Graph;
935    typedef _Traits Traits;
936    typedef typename Graph::Node Node;
937    typedef typename Graph::Edge Edge;
938    typedef typename Graph::UEdge UEdge;
939
940    /// \brief Constructor.
941    ///
942    /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
943    /// and attach it into the given LemonWriter. It will write node
944    /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
945    /// parameter is true then the writer will write own label map if
946    /// the user does not give "label" named map. In addition if the
947    /// the \c _forceSort is true then the writer will write the
948    /// edges sorted by the labels.
949    template <typename NodeLabelWriter>
950    UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
951                       const NodeLabelWriter& _nodeLabelWriter,
952                       const std::string& _name = std::string(),
953                       bool _forceLabelMap = true, bool _forceSort = true)
954      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
955        forceSort(_forceSort), graph(_graph), name(_name) {
956      checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
957      nodeLabelWriter.reset(new _writer_bits::
958        LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
959    }
960
961    /// \brief Destructor.
962    ///
963    /// Destructor for UEdgeSetWriter.
964    virtual ~UEdgeSetWriter() {
965      typename MapWriters::iterator it;
966      for (it = writers.begin(); it != writers.end(); ++it) {
967        delete it->second;
968      }
969    }
970
971  private:
972    UEdgeSetWriter(const UEdgeSetWriter&);
973    void operator=(const UEdgeSetWriter&);
974
975  public:
976
977    /// \brief Add a new undirected edge map writer command for the writer.
978    ///
979    /// Add a new undirected map writer command for the writer.
980    template <typename Map>
981    UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map) {
982      return writeUEdgeMap<typename Traits::
983        template Writer<typename Map::Value>, Map>(label, map);
984    }
985
986    /// \brief Add a new undirected map writer command for the writer.
987    ///
988    /// Add a new undirected map writer command for the writer.
989    template <typename ItemWriter, typename Map>
990    UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map,
991                                  const ItemWriter& iw = ItemWriter()) {
992      checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
993      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
994      writers.push_back(
995        make_pair(label, new _writer_bits::
996                  UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
997      return *this;
998    }
999
1000    /// \brief Add a new directed edge map writer command for the writer.
1001    ///
1002    /// Add a new directed map writer command for the writer.
1003    template <typename Map>
1004    UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
1005      return writeEdgeMap<typename Traits::
1006        template Writer<typename Map::Value>, Map>(label, map);
1007    }
1008
1009    /// \brief Add a new directed map writer command for the writer.
1010    ///
1011    /// Add a new directed map writer command for the writer.
1012    template <typename ItemWriter, typename Map>
1013    UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map,
1014                                 const ItemWriter& iw = ItemWriter()) {
1015      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1016      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1017      writeUEdgeMap("+" + label,
1018                    _writer_bits::forwardComposeMap(graph, map), iw);
1019      writeUEdgeMap("-" + label,
1020                    _writer_bits::backwardComposeMap(graph, map), iw);
1021      return *this;
1022    }
1023
1024  protected:
1025
1026    /// \brief The header of the section.
1027    ///
1028    /// It gives back the header of the section.
1029    virtual std::string header() {
1030      return "@uedgeset " + name;
1031    }
1032
1033    /// \brief  Writer function of the section.
1034    ///
1035    /// Write the content of the section.
1036    virtual void write(std::ostream& os) {
1037      if (!nodeLabelWriter->isLabelWriter()) {
1038        throw DataFormatError("Cannot find nodeset or label map");
1039      }
1040      for (int i = 0; i < int(writers.size()); ++i) {
1041        if (writers[i].first == "label") {
1042          labelMap = writers[i].second;
1043          forceLabelMap = false;
1044          break;
1045        }
1046      }
1047      std::vector<UEdge> items;
1048      for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
1049        items.push_back(it);
1050      }
1051      if (forceSort) {
1052        if (labelMap) {
1053          labelMap->sort(items);
1054        } else {
1055          typedef IdMap<Graph, UEdge> Map;
1056          Map map(graph);
1057          _writer_bits::ComposeLess<Map> less(map);
1058          std::sort(items.begin(), items.end(), less);
1059        }
1060      }
1061      os << "\t\t";
1062      if (forceLabelMap) {
1063        os << "label\t";
1064      }
1065      for (int i = 0; i < int(writers.size()); ++i) {
1066        os << writers[i].first << '\t';
1067      }
1068      os << std::endl;
1069      for (typename std::vector<UEdge>::iterator it = items.begin();
1070           it != items.end(); ++it) {
1071        nodeLabelWriter->write(os, graph.source(*it));
1072        os << '\t';
1073        nodeLabelWriter->write(os, graph.target(*it));
1074        os << '\t';
1075        if (forceLabelMap) {
1076          os << graph.id(*it) << '\t';
1077        }
1078        for (int i = 0; i < int(writers.size()); ++i) {
1079          writers[i].second->write(os, *it);
1080          os << '\t';
1081        }
1082        os << std::endl;
1083      }
1084    }
1085
1086  public:
1087
1088    /// \brief Returns true if the undirected edgeset can write the labels of
1089    /// the edges.
1090    ///
1091    /// Returns true if the undirected edgeset can write the labels of the
1092    /// undirected edges. It is possible only if a "label" named map was
1093    /// written or the \c _forceLabelMap constructor parameter was true.
1094    bool isLabelWriter() const {
1095      return forceLabelMap || labelMap != 0;
1096    }
1097
1098    /// \brief Write the label of the given undirected edge.
1099    ///
1100    /// It writes the label of the given undirected edge. If there was written
1101    /// a "label" named map then it will write the map value belongs to the
1102    /// undirected edge. Otherwise if the \c forceLabel parameter was true it
1103    /// will write its id in the graph.
1104    void writeLabel(std::ostream& os, const UEdge& item) const {
1105      if (forceLabelMap) {
1106        os << graph.id(item);
1107      } else {
1108        labelMap->write(os, item);
1109      }
1110    }
1111
1112    /// \brief Write the label of the given edge.
1113    ///
1114    /// It writes the label of the given edge. If there was written
1115    /// a "label" named map then it will write the map value belongs to the
1116    /// edge. Otherwise if the \c forceLabel parameter was true it
1117    /// will write its id in the graph. If the edge is forward map
1118    /// then its prefix character is \c '+' elsewhere \c '-'.
1119    void writeLabel(std::ostream& os, const Edge& item) const {
1120      if (graph.direction(item)) {
1121        os << "+";
1122      } else {
1123        os << "-";
1124      }
1125      if (forceLabelMap) {
1126        os << graph.id(static_cast<const UEdge&>(item));
1127      } else {
1128        labelMap->write(os, item);
1129      }
1130    }
1131
1132    /// \brief Sorts the given undirected edge vector by label.
1133    ///
1134    /// Sorts the given undirected edge vector by label. If there was
1135    /// written a "label" named map then the vector will be sorted by
1136    /// the values of this map. Otherwise if the \c forceLabel
1137    /// parameter was true it will be sorted by its id in the graph.
1138    void sortByLabel(std::vector<UEdge>& uedges) const {
1139      if (labelMap) {
1140        labelMap->sort(uedges);
1141      } else {
1142        typedef IdMap<Graph, UEdge> Map;
1143        Map map(graph);
1144        _writer_bits::ComposeLess<Map> less(map);
1145        std::sort(uedges.begin(), uedges.end(), less);
1146      }
1147    }
1148
1149    /// \brief Sorts the given edge vector by label.
1150    ///
1151    /// Sorts the given edge vector by label. If there was written a
1152    /// "label" named map then the vector will be sorted by the values
1153    /// of this map. Otherwise if the \c forceLabel parameter was true
1154    /// it will be sorted by its id in the graph.
1155    void sortByLabel(std::vector<Edge>& edges) const {
1156      if (labelMap) {
1157        labelMap->sort(graph, edges);
1158      } else {
1159        typedef IdMap<Graph, Edge> Map;
1160        Map map(graph);
1161        _writer_bits::ComposeLess<Map> less(map);
1162        std::sort(edges.begin(), edges.end(), less);
1163      }
1164    }
1165
1166  private:
1167
1168    typedef std::vector<std::pair<std::string, _writer_bits::
1169                                  UEdgeMapWriterBase<Graph>*> > MapWriters;
1170    MapWriters writers;
1171
1172    _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
1173    bool forceLabelMap;
1174    bool forceSort;
1175   
1176    const Graph& graph;   
1177    std::string name;
1178
1179    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
1180  };
1181
1182  /// \ingroup section_io
1183  /// \brief SectionWriter for writing named nodes.
1184  ///
1185  /// The nodes section's header line is \c \@nodes \c nodes_name, but the
1186  /// \c nodes_name may be empty.
1187  ///
1188  /// Each line in the section contains the name of the node and
1189  /// then the node label.
1190  ///
1191  /// \relates LemonWriter
1192  template <typename _Graph>
1193  class NodeWriter : public LemonWriter::SectionWriter {
1194    typedef LemonWriter::SectionWriter Parent;
1195    typedef _Graph Graph;
1196    typedef typename Graph::Node Node;
1197  public:
1198   
1199    /// \brief Constructor.
1200    ///
1201    /// Constructor for NodeWriter. It creates the NodeWriter and
1202    /// attach it into the given LemonWriter. The given \c _LabelWriter
1203    /// will write the nodes' label what can be a nodeset writer.
1204    template <typename _LabelWriter>
1205    NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1206               const std::string& _name = std::string())
1207      : Parent(_writer), name(_name) {
1208      checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
1209      labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
1210                        (_labelWriter));
1211    }
1212
1213
1214    /// \brief Destructor.
1215    ///
1216    /// Destructor for NodeWriter.
1217    virtual ~NodeWriter() {}
1218
1219  private:
1220    NodeWriter(const NodeWriter&);
1221    void operator=(const NodeWriter&);
1222
1223  public:
1224
1225    /// \brief Add a node writer command for the NodeWriter.
1226    ///
1227    /// Add a node writer command for the NodeWriter.
1228    void writeNode(std::string label, const Node& item) {
1229      writers.push_back(make_pair(label, &item));
1230    }
1231
1232  protected:
1233
1234    /// \brief The header of the section.
1235    ///
1236    /// It gives back the header of the section.
1237    virtual std::string header() {
1238      return "@nodes " + name;
1239    }
1240
1241    /// \brief  Writer function of the section.
1242    ///
1243    /// Write the content of the section.
1244    virtual void write(std::ostream& os) {
1245      if (!labelWriter->isLabelWriter()) {
1246        throw DataFormatError("Cannot find nodeset or label map");
1247      }
1248      for (int i = 0; i < int(writers.size()); ++i) {
1249        os << writers[i].first << ' ';
1250        labelWriter->write(os, *(writers[i].second));
1251        os << std::endl;
1252      }
1253    }
1254
1255    /// \brief Gives back true when the section should be written.
1256    ///
1257    /// Gives back true when the section should be written.
1258    virtual bool valid() { return !writers.empty(); }
1259   
1260  private:
1261
1262    std::string name;
1263
1264    typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
1265    NodeWriters writers;
1266    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1267  };
1268
1269  /// \ingroup section_io
1270  /// \brief SectionWriter for writing named edges.
1271  ///
1272  /// The edges section's header line is \c \@edges \c edges_name, but the
1273  /// \c edges_name may be empty.
1274  ///
1275  /// Each line in the section contains the name of the edge and
1276  /// then the edge label.
1277  ///
1278  /// \relates LemonWriter
1279  template <typename _Graph>
1280  class EdgeWriter : public LemonWriter::SectionWriter {
1281    typedef LemonWriter::SectionWriter Parent;
1282    typedef _Graph Graph;
1283    typedef typename Graph::Edge Edge;
1284  public:
1285   
1286    /// \brief Constructor.
1287    ///
1288    /// Constructor for EdgeWriter. It creates the EdgeWriter and
1289    /// attach it into the given LemonWriter. The given \c _LabelWriter
1290    /// will write the edges' label what can be a edgeset writer.
1291    template <typename _LabelWriter>
1292    EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1293               const std::string& _name = std::string())
1294      : Parent(_writer), name(_name) {
1295      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1296      labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
1297    }
1298
1299    /// \brief Destructor.
1300    ///
1301    /// Destructor for EdgeWriter.
1302    virtual ~EdgeWriter() {}
1303  private:
1304    EdgeWriter(const EdgeWriter&);
1305    void operator=(const EdgeWriter&);
1306
1307  public:
1308
1309    /// \brief Add an edge writer command for the EdgeWriter.
1310    ///
1311    /// Add an edge writer command for the EdgeWriter.
1312    void writeEdge(std::string label, const Edge& item) {
1313      writers.push_back(make_pair(label, &item));
1314    }
1315
1316  protected:
1317
1318    /// \brief The header of the section.
1319    ///
1320    /// It gives back the header of the section.
1321    virtual std::string header() {
1322      return "@edges " + name;
1323    }
1324
1325    /// \brief  Writer function of the section.
1326    ///
1327    /// Write the content of the section.
1328    virtual void write(std::ostream& os) {
1329      if (!labelWriter->isLabelWriter()) {
1330        throw DataFormatError("Cannot find edgeset or label map");
1331      }
1332      for (int i = 0; i < int(writers.size()); ++i) {
1333        os << writers[i].first << ' ';
1334        labelWriter->write(os, *(writers[i].second));
1335        os << std::endl;
1336      }
1337    }
1338
1339    /// \brief Gives back true when the section should be written.
1340    ///
1341    /// Gives back true when the section should be written.
1342    virtual bool valid() { return !writers.empty(); }
1343   
1344  private:
1345
1346    std::string name;
1347
1348    typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1349    EdgeWriters writers;
1350
1351    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
1352  };
1353
1354
1355  /// \ingroup section_io
1356  /// \brief SectionWriter for writing named undirected edges.
1357  ///
1358  /// The undirected edges section's header line is \c \@uedges
1359  /// \c uedges_name, but the \c uedges_name may be empty.
1360  ///
1361  /// Each line in the section contains the name of the undirected edge and
1362  /// then the undirected edge label.
1363  ///
1364  /// \relates LemonWriter
1365  template <typename _Graph>
1366  class UEdgeWriter : public LemonWriter::SectionWriter {
1367    typedef LemonWriter::SectionWriter Parent;
1368    typedef _Graph Graph;
1369    typedef typename Graph::Node Node;
1370    typedef typename Graph::Edge Edge;
1371    typedef typename Graph::UEdge UEdge;
1372  public:
1373   
1374    /// \brief Constructor.
1375    ///
1376    /// Constructor for UEdgeWriter. It creates the UEdgeWriter and
1377    /// attach it into the given LemonWriter. The given \c _LabelWriter
1378    /// will write the undirected edges' label what can be an undirected
1379    /// edgeset writer.
1380    template <typename _LabelWriter>
1381    UEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1382               const std::string& _name = std::string())
1383      : Parent(_writer), name(_name) {
1384      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1385      checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
1386      uEdgeLabelWriter.reset(new _writer_bits::
1387                              LabelWriter<UEdge, _LabelWriter>(_labelWriter));
1388      edgeLabelWriter.reset(new _writer_bits::
1389                         LabelWriter<Edge, _LabelWriter>(_labelWriter));
1390    }
1391
1392    /// \brief Destructor.
1393    ///
1394    /// Destructor for UEdgeWriter.
1395    virtual ~UEdgeWriter() {}
1396  private:
1397    UEdgeWriter(const UEdgeWriter&);
1398    void operator=(const UEdgeWriter&);
1399
1400  public:
1401
1402    /// \brief Add an edge writer command for the UEdgeWriter.
1403    ///
1404    /// Add an edge writer command for the UEdgeWriter.
1405    void writeEdge(std::string label, const Edge& item) {
1406      edgeWriters.push_back(make_pair(label, &item));
1407    }
1408
1409    /// \brief Add an undirected edge writer command for the UEdgeWriter.
1410    ///
1411    /// Add an undirected edge writer command for the UEdgeWriter.
1412    void writeUEdge(std::string label, const UEdge& item) {
1413      uEdgeWriters.push_back(make_pair(label, &item));
1414    }
1415
1416  protected:
1417
1418    /// \brief The header of the section.
1419    ///
1420    /// It gives back the header of the section.
1421    virtual std::string header() {
1422      return "@uedges " + name;
1423    }
1424
1425    /// \brief  Writer function of the section.
1426    ///
1427    /// Write the content of the section.
1428    virtual void write(std::ostream& os) {
1429      if (!edgeLabelWriter->isLabelWriter()) {
1430        throw DataFormatError("Cannot find undirected edgeset or label map");
1431      }
1432      if (!uEdgeLabelWriter->isLabelWriter()) {
1433        throw DataFormatError("Cannot find undirected edgeset or label map");
1434      }
1435      for (int i = 0; i < int(uEdgeWriters.size()); ++i) {
1436        os << uEdgeWriters[i].first << ' ';
1437        uEdgeLabelWriter->write(os, *(uEdgeWriters[i].second));
1438        os << std::endl;
1439      }
1440      for (int i = 0; i < int(edgeWriters.size()); ++i) {
1441        os << edgeWriters[i].first << ' ';
1442        edgeLabelWriter->write(os, *(edgeWriters[i].second));
1443        os << std::endl;
1444      }
1445    }
1446
1447    /// \brief Gives back true when the section should be written.
1448    ///
1449    /// Gives back true when the section should be written.
1450    virtual bool valid() {
1451      return !uEdgeWriters.empty() || !edgeWriters.empty();
1452    }
1453   
1454  private:
1455
1456    std::string name;
1457
1458    typedef std::vector<std::pair<std::string,
1459                                  const UEdge*> > UEdgeWriters;
1460    UEdgeWriters uEdgeWriters;
1461    std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > uEdgeLabelWriter;
1462
1463    typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1464    EdgeWriters edgeWriters;
1465    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
1466
1467  };
1468
1469  /// \ingroup section_io
1470  /// \brief SectionWriter for writing extra node maps.
1471  ///
1472  /// The lemon format can store maps in the nodeset. This class let
1473  /// you make distinict section to store maps. The main purpose of
1474  /// this class is a logical separation of some maps. The other
1475  /// useful application could be to store paths in node maps.
1476  ///
1477  /// The first line of the section contains the names of the maps
1478  /// separated with white spaces. Each next line describes an item
1479  /// in the itemset, and contains in the first column the label of
1480  /// the item and then the mapped values for each map.
1481  ///
1482  /// \relates LemonWriter
1483  template <typename _Graph, typename _Traits = DefaultWriterTraits>
1484  class NodeMapWriter : public LemonWriter::SectionWriter {
1485    typedef LemonWriter::SectionWriter Parent;
1486  public:
1487
1488    typedef _Graph Graph;
1489    typedef _Traits Traits;
1490    typedef typename Graph::Node Node;
1491
1492    /// \brief Constructor.
1493    ///
1494    /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
1495    /// attach it into the given LemonWriter. If the the
1496    /// \c _forceSort is true then the writer will write the edges
1497    /// sorted by the labels.
1498    template <typename _LabelWriter>
1499    NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
1500                 const _LabelWriter& _labelWriter,
1501                 const std::string& _name = std::string(),
1502                 bool _forceSort = true)
1503      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1504      checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
1505      labelWriter.reset(new _writer_bits::LabelWriter<Node,
1506                        _LabelWriter>(_labelWriter));
1507    }
1508
1509    /// \brief Destructor.
1510    ///
1511    /// Destructor for NodeMapWriter.
1512    virtual ~NodeMapWriter() {
1513      typename MapWriters::iterator it;
1514      for (it = writers.begin(); it != writers.end(); ++it) {
1515        delete it->second;
1516      }
1517    }
1518
1519  private:
1520    NodeMapWriter(const NodeMapWriter&);
1521    void operator=(const NodeMapWriter&);
1522 
1523  public:
1524
1525    /// \brief Add a new node map writer command for the writer.
1526    ///
1527    /// Add a new node map writer command for the writer.
1528    template <typename Map>
1529    NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
1530      return writeNodeMap<typename Traits::
1531        template Writer<typename Map::Value>, Map>(label, map);
1532    }
1533
1534    /// \brief Add a new node map writer command for the writer.
1535    ///
1536    /// Add a new node map writer command for the writer.
1537    template <typename ItemWriter, typename Map>
1538    NodeMapWriter& writeNodeMap(std::string label, const Map& map,
1539                           const ItemWriter& iw = ItemWriter()) {
1540      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1541      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1542      writers.push_back(
1543        make_pair(label, new _writer_bits::
1544                  MapWriter<Node, Map, ItemWriter>(map, iw)));
1545      return *this;
1546    }
1547
1548  protected:
1549
1550    /// \brief The header of the section.
1551    ///
1552    /// It gives back the header of the section.
1553    virtual std::string header() {
1554      return "@nodemaps " + name;
1555    }
1556
1557    /// \brief  Writer function of the section.
1558    ///
1559    /// Write the content of the section.
1560    virtual void write(std::ostream& os) {
1561      std::vector<Node> nodes;
1562      for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
1563        nodes.push_back(it);
1564      }
1565      if (forceSort) {
1566        labelWriter->sort(nodes);
1567      }
1568      os << '\t';
1569      for (int i = 0; i < int(writers.size()); ++i) {
1570        os << writers[i].first << '\t';
1571      }
1572      os << std::endl;
1573      for (typename std::vector<Node>::iterator it = nodes.begin();
1574           it != nodes.end(); ++it) {
1575
1576        labelWriter->write(os, *it); os << '\t';
1577        for (int i = 0; i < int(writers.size()); ++i) {
1578          writers[i].second->write(os, *it);
1579          os << '\t';
1580        }
1581        os << std::endl;
1582      }
1583    }
1584
1585
1586  private:
1587
1588    typedef std::vector<std::pair<std::string, _writer_bits::
1589                                  MapWriterBase<Node>*> > MapWriters;
1590    MapWriters writers;
1591
1592    _writer_bits::MapWriterBase<Node>* labelMap;
1593
1594    const Graph& graph;   
1595    std::string name;
1596    bool forceSort;
1597
1598    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1599  };
1600
1601  /// \ingroup section_io
1602  /// \brief SectionWriter for writing extra edge maps.
1603  ///
1604  /// The lemon format can store maps in the edgeset. This class let
1605  /// you make distinict section to store maps. The main purpose of
1606  /// this class is a logical separation of some maps. The other
1607  /// useful application could be to store paths in edge maps.
1608  ///
1609  /// The first line of the section contains the names of the maps
1610  /// separated with white spaces. Each next line describes an item
1611  /// in the itemset, and contains in the first column the label of
1612  /// the item and then the mapped values for each map.
1613  ///
1614  /// \relates LemonWriter
1615  template <typename _Graph, typename _Traits = DefaultWriterTraits>
1616  class EdgeMapWriter : public LemonWriter::SectionWriter {
1617    typedef LemonWriter::SectionWriter Parent;
1618  public:
1619
1620    typedef _Graph Graph;
1621    typedef _Traits Traits;
1622    typedef typename Graph::Edge Edge;
1623
1624    /// \brief Constructor.
1625    ///
1626    /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
1627    /// attach it into the given LemonWriter. If the the
1628    /// \c _forceSort is true then the writer will write the edges
1629    /// sorted by the labels.
1630    template <typename _LabelWriter>
1631    EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
1632                 const _LabelWriter& _labelWriter,
1633                 const std::string& _name = std::string(),
1634                 bool _forceSort = true)
1635      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1636      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1637      labelWriter.reset(new _writer_bits::LabelWriter<Edge,
1638                        _LabelWriter>(_labelWriter));
1639    }
1640
1641    /// \brief Destructor.
1642    ///
1643    /// Destructor for EdgeMapWriter.
1644    virtual ~EdgeMapWriter() {
1645      typename MapWriters::iterator it;
1646      for (it = writers.begin(); it != writers.end(); ++it) {
1647        delete it->second;
1648      }
1649    }
1650
1651  private:
1652    EdgeMapWriter(const EdgeMapWriter&);
1653    void operator=(const EdgeMapWriter&);
1654 
1655  public:
1656
1657    /// \brief Add a new edge map writer command for the writer.
1658    ///
1659    /// Add a new edge map writer command for the writer.
1660    template <typename Map>
1661    EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
1662      return writeEdgeMap<typename Traits::
1663        template Writer<typename Map::Value>, Map>(label, map);
1664    }
1665
1666    /// \brief Add a new edge map writer command for the writer.
1667    ///
1668    /// Add a new edge map writer command for the writer.
1669    template <typename ItemWriter, typename Map>
1670    EdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
1671                                const ItemWriter& iw = ItemWriter()) {
1672      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1673      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1674      writers.push_back(
1675        make_pair(label, new _writer_bits::
1676                  MapWriter<Edge, Map, ItemWriter>(map, iw)));
1677      return *this;
1678    }
1679
1680  protected:
1681
1682    /// \brief The header of the section.
1683    ///
1684    /// It gives back the header of the section.
1685    virtual std::string header() {
1686      return "@edgemaps " + name;
1687    }
1688
1689    /// \brief  Writer function of the section.
1690    ///
1691    /// Write the content of the section.
1692    virtual void write(std::ostream& os) {
1693      std::vector<Edge> edges;
1694      for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
1695        edges.push_back(it);
1696      }
1697      if (forceSort) {
1698        labelWriter->sort(edges);
1699      }
1700      os << '\t';
1701      for (int i = 0; i < int(writers.size()); ++i) {
1702        os << writers[i].first << '\t';
1703      }
1704      os << std::endl;
1705      for (typename std::vector<Edge>::iterator it = edges.begin();
1706           it != edges.end(); ++it) {
1707
1708        labelWriter->write(os, *it); os << '\t';
1709        for (int i = 0; i < int(writers.size()); ++i) {
1710          writers[i].second->write(os, *it);
1711          os << '\t';
1712        }
1713        os << std::endl;
1714      }
1715    }
1716
1717
1718  private:
1719
1720    typedef std::vector<std::pair<std::string, _writer_bits::
1721                                  MapWriterBase<Edge>*> > MapWriters;
1722    MapWriters writers;
1723
1724    _writer_bits::MapWriterBase<Edge>* labelMap;
1725
1726    const Graph& graph;   
1727    std::string name;
1728    bool forceSort;
1729
1730    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
1731  };
1732
1733  /// \ingroup section_io
1734  /// \brief SectionWriter for writing extra undirected edge maps.
1735  ///
1736  /// The lemon format can store maps in the uedgeset. This class let
1737  /// you make distinict section to store maps. The main purpose of
1738  /// this class is a logical separation of some maps. The other
1739  /// useful application could be to store paths in undirected edge
1740  /// maps.
1741  ///
1742  /// The first line of the section contains the names of the maps
1743  /// separated with white spaces. Each next line describes an item
1744  /// in the itemset, and contains in the first column the label of
1745  /// the item and then the mapped values for each map.
1746  ///
1747  /// \relates LemonWriter
1748  template <typename _Graph, typename _Traits = DefaultWriterTraits>
1749  class UEdgeMapWriter : public LemonWriter::SectionWriter {
1750    typedef LemonWriter::SectionWriter Parent;
1751  public:
1752
1753    typedef _Graph Graph;
1754    typedef _Traits Traits;
1755    typedef typename Graph::UEdge UEdge;
1756    typedef typename Graph::Edge Edge;
1757
1758    /// \brief Constructor.
1759    ///
1760    /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
1761    /// attach it into the given LemonWriter. If the the
1762    /// \c _forceSort is true then the writer will write the uedges
1763    /// sorted by the labels.
1764    template <typename _LabelWriter>
1765    UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
1766                 const _LabelWriter& _labelWriter,
1767                 const std::string& _name = std::string(),
1768                 bool _forceSort = true)
1769      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1770      checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
1771      labelWriter.reset(new _writer_bits::LabelWriter<UEdge,
1772                            _LabelWriter>(_labelWriter));
1773    }
1774
1775    /// \brief Destructor.
1776    ///
1777    /// Destructor for UEdgeMapWriter.
1778    virtual ~UEdgeMapWriter() {
1779      typename MapWriters::iterator it;
1780      for (it = writers.begin(); it != writers.end(); ++it) {
1781        delete it->second;
1782      }
1783    }
1784
1785  private:
1786    UEdgeMapWriter(const UEdgeMapWriter&);
1787    void operator=(const UEdgeMapWriter&);
1788 
1789  public:
1790
1791    /// \brief Add a new undirected edge map writer command for the writer.
1792    ///
1793    /// Add a new undirected edge map writer command for the writer.
1794    template <typename Map>
1795    UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
1796      return writeUEdgeMap<typename Traits::
1797        template Writer<typename Map::Value>, Map>(label, map);
1798    }
1799
1800    /// \brief Add a new undirected edge map writer command for the writer.
1801    ///
1802    /// Add a new undirected edge map writer command for the writer.
1803    template <typename ItemWriter, typename Map>
1804    UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map,
1805                           const ItemWriter& iw = ItemWriter()) {
1806      checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
1807      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1808      writers.push_back(
1809        make_pair(label, new _writer_bits::
1810                  MapWriter<UEdge, Map, ItemWriter>(map, iw)));
1811      return *this;
1812    }
1813
1814    /// \brief Add a new directed edge map writer command for the writer.
1815    ///
1816    /// Add a new directed map writer command for the writer.
1817    template <typename Map>
1818    UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
1819      return writeEdgeMap<typename Traits::
1820        template Writer<typename Map::Value>, Map>(label, map);
1821    }
1822
1823    /// \brief Add a new directed map writer command for the writer.
1824    ///
1825    /// Add a new directed map writer command for the writer.
1826    template <typename ItemWriter, typename Map>
1827    UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
1828                                 const ItemWriter& iw = ItemWriter()) {
1829      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1830      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1831      writeUEdgeMap("+" + label,
1832                    _writer_bits::forwardComposeMap(graph, map), iw);
1833      writeUEdgeMap("-" + label,
1834                    _writer_bits::backwardComposeMap(graph, map), iw);
1835      return *this;
1836    }
1837
1838  protected:
1839
1840    /// \brief The header of the section.
1841    ///
1842    /// It gives back the header of the section.
1843    virtual std::string header() {
1844      return "@uedgemaps " + name;
1845    }
1846
1847    /// \brief  Writer function of the section.
1848    ///
1849    /// Write the content of the section.
1850    virtual void write(std::ostream& os) {
1851      std::vector<UEdge> uedges;
1852      for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
1853        uedges.push_back(it);
1854      }
1855      if (forceSort) {
1856        labelWriter->sort(uedges);
1857      }
1858      os << '\t';
1859      for (int i = 0; i < int(writers.size()); ++i) {
1860        os << writers[i].first << '\t';
1861      }
1862      os << std::endl;
1863      for (typename std::vector<UEdge>::iterator it = uedges.begin();
1864           it != uedges.end(); ++it) {
1865
1866        labelWriter->write(os, *it); os << '\t';
1867        for (int i = 0; i < int(writers.size()); ++i) {
1868          writers[i].second->write(os, *it);
1869          os << '\t';
1870        }
1871        os << std::endl;
1872      }
1873    }
1874
1875
1876  private:
1877
1878    typedef std::vector<std::pair<std::string, _writer_bits::
1879                                  MapWriterBase<UEdge>*> > MapWriters;
1880    MapWriters writers;
1881
1882    _writer_bits::MapWriterBase<UEdge>* labelMap;
1883
1884    const Graph& graph;   
1885    std::string name;
1886    bool forceSort;
1887
1888    std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
1889  };
1890
1891
1892  /// \ingroup section_io
1893  /// \brief SectionWriter for attributes.
1894  ///
1895  /// The lemon format can store multiple attribute set. Each set has
1896  /// the header line \c \@attributes \c attributes_name, but the
1897  /// attributeset_name may be empty.
1898  ///
1899  /// The attributeset section contains several lines. Each of them starts
1900  /// with the name of attribute and then the value.
1901  ///
1902  /// \relates LemonWriter
1903  template <typename _Traits = DefaultWriterTraits>
1904  class AttributeWriter : public LemonWriter::SectionWriter {
1905    typedef LemonWriter::SectionWriter Parent;
1906    typedef _Traits Traits;
1907  public:
1908    /// \brief Constructor.
1909    ///
1910    /// Constructor for AttributeWriter. It creates the AttributeWriter and
1911    /// attach it into the given LemonWriter.
1912    AttributeWriter(LemonWriter& _writer,
1913                    const std::string& _name = std::string())
1914      : Parent(_writer), name(_name) {}
1915
1916    /// \brief Destructor.
1917    ///
1918    /// Destructor for AttributeWriter.
1919    virtual ~AttributeWriter() {
1920      typename Writers::iterator it;
1921      for (it = writers.begin(); it != writers.end(); ++it) {
1922        delete it->second;
1923      }
1924    }
1925
1926  private:
1927    AttributeWriter(const AttributeWriter&);
1928    void operator=(AttributeWriter&);
1929
1930  public:
1931    /// \brief Add an attribute writer command for the writer.
1932    ///
1933    /// Add an attribute writer command for the writer.
1934    template <typename Value>
1935    AttributeWriter& writeAttribute(std::string label,
1936                                    const Value& value) {
1937      return
1938        writeAttribute<typename Traits::template Writer<Value> >(label, value);
1939    }
1940
1941    /// \brief Add an attribute writer command for the writer.
1942    ///
1943    /// Add an attribute writer command for the writer.
1944    template <typename ItemWriter, typename Value>
1945    AttributeWriter& writeAttribute(std::string label, const Value& value,
1946                                    const ItemWriter& iw = ItemWriter()) {
1947      checkConcept<_writer_bits::ItemWriter<Value>, ItemWriter>();
1948      writers.push_back(make_pair(label, new _writer_bits::
1949                                  ValueWriter<Value, ItemWriter>(value, iw)));
1950      return *this;
1951    }
1952
1953  protected:
1954
1955    /// \brief The header of section.
1956    ///
1957    /// It gives back the header of the section.
1958    std::string header() {
1959      return "@attributes " + name;
1960    }
1961
1962    /// \brief  Writer function of the section.
1963    ///
1964    /// Write the content of the section.
1965    void write(std::ostream& os) {
1966      typename Writers::iterator it;
1967      for (it = writers.begin(); it != writers.end(); ++it) {
1968        os << it->first << ' ';
1969        it->second->write(os);
1970        os << std::endl;
1971      }
1972    }   
1973
1974    /// \brief Gives back true when the section should be written.
1975    ///
1976    /// Gives back true when the section should be written.
1977    virtual bool valid() { return !writers.empty(); }
1978
1979  private:
1980    std::string name;
1981
1982    typedef std::vector<std::pair<std::string,
1983                                  _writer_bits::ValueWriterBase*> > Writers;
1984    Writers writers; 
1985  };
1986
1987
1988}
1989#endif
Note: See TracBrowser for help on using the repository browser.