COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lemon_writer.h @ 2502:9c23c3762bc5

Last change on this file since 2502:9c23c3762bc5 was 2502:9c23c3762bc5, checked in by Balazs Dezso, 12 years ago

BpUGraphReader and Writer

File size: 71.0 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      const Graph& graph;
148      typename Ref<Map>::Type map;
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      const Graph& graph;
172      typename Ref<Map>::Type map;
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 nodes
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 bipartite graph's nodeset.
684  ///
685  /// The lemon format can store multiple bipartite graph nodesets
686  /// with several maps.  The nodeset section's header line is \c
687  /// \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_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 node in the nodeset, and
691  /// contains the mapped values for each map.
692  ///
693  /// If the nodeset contains an \c "label" named map then it will be regarded
694  /// as label map. This map should contain only unique values and when the
695  /// \c writeLabel() member will be called with a node it will write it's
696  /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
697  /// then the label map will be the id in the graph. In addition if the
698  /// the \c _forceSort is true then the writer will write the edges
699  /// sorted by the labels.
700  ///
701  /// \relates LemonWriter
702  template <typename _Graph, typename _Traits = DefaultWriterTraits>
703  class BpNodeSetWriter : public LemonWriter::SectionWriter {
704    typedef LemonWriter::SectionWriter Parent;
705  public:
706
707    typedef _Graph Graph;
708    typedef _Traits Traits;
709    typedef typename Graph::Node Node;
710
711    /// \brief Constructor.
712    ///
713    /// Constructor for BpNodeSetWriter. It creates the BpNodeSetWriter and
714    /// attach it into the given LemonWriter. If the \c _forceLabelMap
715    /// parameter is true then the writer will write own label map when
716    /// the user does not give "label" named map. In addition if the
717    /// the \c _forceSort is true then the writer will write the nodes
718    /// sorted by the labels.
719    BpNodeSetWriter(LemonWriter& _writer, const Graph& _graph,
720                  const std::string& _name = std::string(),
721                  bool _forceLabelMap = true, bool _forceSort = true)
722      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
723        forceSort(_forceSort), graph(_graph), name(_name) {}
724
725    /// \brief Destructor.
726    ///
727    /// Destructor for BpNodeSetWriter.
728    virtual ~BpNodeSetWriter() {
729      typename MapWriters::iterator it;
730      for (it = writers.begin(); it != writers.end(); ++it) {
731        delete it->second;
732      }
733    }
734
735  private:
736    BpNodeSetWriter(const BpNodeSetWriter&);
737    void operator=(const BpNodeSetWriter&);
738 
739  public:
740
741    /// \brief Add a new A-node map writer command for the writer.
742    ///
743    /// Add a new A-node map writer command for the writer.
744    template <typename Map>
745    BpNodeSetWriter& writeANodeMap(std::string label, const Map& map) {
746      return writeANodeMap<typename Traits::
747        template Writer<typename Map::Value>, Map>(label, map);
748    }
749
750    /// \brief Add a new A-node map writer command for the writer.
751    ///
752    /// Add a new A-node map writer command for the writer.
753    template <typename ItemWriter, typename Map>
754    BpNodeSetWriter& writeANodeMap(std::string label, const Map& map,
755                                   const ItemWriter& iw = ItemWriter()) {
756      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
757      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
758      if (label == "label") {
759        throw IoParameterError("Label cannot be A-node map");
760      }
761      awriters.push_back(make_pair(label, new _writer_bits::
762                                   MapWriter<Node, Map, ItemWriter>(map, iw)));
763      return *this;
764    }
765
766    /// \brief Add a new B-node map writer command for the writer.
767    ///
768    /// Add a new B-node map writer command for the writer.
769    template <typename Map>
770    BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map) {
771      return writeBNodeMap<typename Traits::
772        template Writer<typename Map::Value>, Map>(label, map);
773    }
774
775    /// \brief Add a new B-node map writer command for the writer.
776    ///
777    /// Add a new B-node map writer command for the writer.
778    template <typename ItemWriter, typename Map>
779    BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map,
780                                   const ItemWriter& iw = ItemWriter()) {
781      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
782      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
783      if (label == "label") {
784        throw IoParameterError("Label cannot be B-node map");
785      }
786      bwriters.push_back(make_pair(label, new _writer_bits::
787                                   MapWriter<Node, Map, ItemWriter>(map, iw)));
788      return *this;
789    }
790
791    /// \brief Add a new node map writer command for the writer.
792    ///
793    /// Add a new node map writer command for the writer.
794    template <typename Map>
795    BpNodeSetWriter& writeNodeMap(std::string label, const Map& map) {
796      return writeNodeMap<typename Traits::
797        template Writer<typename Map::Value>, Map>(label, map);
798    }
799
800    /// \brief Add a new node map writer command for the writer.
801    ///
802    /// Add a new node map writer command for the writer.
803    template <typename ItemWriter, typename Map>
804    BpNodeSetWriter& writeNodeMap(std::string label, const Map& map,
805                                  const ItemWriter& iw = ItemWriter()) {
806      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
807      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
808      writers.push_back(make_pair(label, new _writer_bits::
809                                  MapWriter<Node, Map, ItemWriter>(map, iw)));
810      return *this;
811    }
812
813  protected:
814
815    /// \brief The header of the section.
816    ///
817    /// It gives back the header of the section.
818    virtual std::string header() {
819      return "@bpnodeset " + name;
820    }
821
822    /// \brief Writer function of the section.
823    ///
824    /// Write the content of the section.
825    virtual void write(std::ostream& os) {
826      for (int i = 0; i < int(writers.size()); ++i) {
827        if (writers[i].first == "label") {
828          labelMap = writers[i].second;
829          forceLabelMap = false;
830          break;
831        }
832      }
833      {
834        os << "&anodeset ";
835        std::vector<Node> items;
836        for (typename Graph::ANodeIt it(graph); it != INVALID; ++it) {
837          items.push_back(it);
838        }
839        if (forceSort) {
840          if (labelMap) {
841            labelMap->sort(items);
842          } else {
843            typedef IdMap<Graph, Node> Map;
844            Map map(graph);
845            _writer_bits::ComposeLess<Map> less(map);
846            std::sort(items.begin(), items.end(), less);
847          }
848        }
849        if (forceLabelMap) {
850          os << "label\t";
851        }
852        for (int i = 0; i < int(writers.size()); ++i) {
853          os << writers[i].first << '\t';
854        }
855        for (int i = 0; i < int(awriters.size()); ++i) {
856          os << awriters[i].first << '\t';
857        }
858        os << std::endl;
859        for (typename std::vector<Node>::iterator it = items.begin();
860             it != items.end(); ++it) {
861          if (forceLabelMap) {
862            os << graph.id(*it) << '\t';
863          }
864          for (int i = 0; i < int(writers.size()); ++i) {
865            writers[i].second->write(os, *it);
866            os << '\t';
867          }
868          for (int i = 0; i < int(awriters.size()); ++i) {
869            awriters[i].second->write(os, *it);
870            os << '\t';
871          }
872          os << std::endl;
873        }
874      }
875      {
876        os << "&bnodeset ";
877        std::vector<Node> items;
878        for (typename Graph::BNodeIt it(graph); it != INVALID; ++it) {
879          items.push_back(it);
880        }
881        if (forceSort) {
882          if (labelMap) {
883            labelMap->sort(items);
884          } else {
885            typedef IdMap<Graph, Node> Map;
886            Map map(graph);
887            _writer_bits::ComposeLess<Map> less(map);
888            std::sort(items.begin(), items.end(), less);
889          }
890        }
891        if (forceLabelMap) {
892          os << "label\t";
893        }
894        for (int i = 0; i < int(writers.size()); ++i) {
895          os << writers[i].first << '\t';
896        }
897        for (int i = 0; i < int(bwriters.size()); ++i) {
898          os << bwriters[i].first << '\t';
899        }
900        os << std::endl;
901        for (typename std::vector<Node>::iterator it = items.begin();
902             it != items.end(); ++it) {
903          if (forceLabelMap) {
904            os << graph.id(*it) << '\t';
905          }
906          for (int i = 0; i < int(writers.size()); ++i) {
907            writers[i].second->write(os, *it);
908            os << '\t';
909          }
910          for (int i = 0; i < int(bwriters.size()); ++i) {
911            bwriters[i].second->write(os, *it);
912            os << '\t';
913          }
914          os << std::endl;
915        }
916      }
917    }
918
919  public:
920
921    /// \brief Returns true if the nodeset can write the labels of the nodes.
922    ///
923    /// Returns true if the nodeset can write the labels of the nodes.
924    /// It is possible only if a "label" named map was written or the
925    /// \c _forceLabelMap constructor parameter was true.
926    bool isLabelWriter() const {
927      return labelMap != 0 || forceLabelMap;
928    }
929
930    /// \brief Write the label of the given node.
931    ///
932    /// It writes the label of the given node. If there was written a "label"
933    /// named map then it will write the map value belongs to the node.
934    /// Otherwise if the \c forceLabel parameter was true it will write
935    /// its label in the graph.
936    void writeLabel(std::ostream& os, const Node& item) const {
937      if (forceLabelMap) {
938        os << graph.id(item);
939      } else {
940        labelMap->write(os, item);
941      }
942    }
943
944    /// \brief Sorts the given node vector by label.
945    ///
946    /// Sorts the given node vector by label. If there was written an
947    /// "label" named map then the vector will be sorted by the values
948    /// of this map. Otherwise if the \c forceLabel parameter was true
949    /// it will be sorted by its id in the graph.
950    void sortByLabel(std::vector<Node>& nodes) const {
951      if (labelMap) {
952        labelMap->sort(nodes);
953      } else {
954        typedef IdMap<Graph, Node> Map;
955        Map map(graph);
956        _writer_bits::ComposeLess<Map> less(map);
957        std::sort(nodes.begin(), nodes.end(), less);
958      }
959    }
960
961  private:
962
963    typedef std::vector<std::pair<std::string, _writer_bits::
964                                  MapWriterBase<Node>*> > MapWriters;
965    MapWriters awriters, bwriters, writers;
966   
967    _writer_bits::MapWriterBase<Node>* labelMap;
968    bool forceLabelMap;
969    bool forceSort;
970   
971    const Graph& graph;   
972    std::string name;
973
974  };
975
976  /// \ingroup section_io
977  /// \brief SectionWriter for writing a graph's edgesets.
978  ///
979  /// The lemon format can store multiple graph edgesets with several maps.
980  /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but
981  /// the \c edgeset_name may be empty.
982  ///
983  /// The first line of the section contains the names of the maps separated
984  /// with white spaces. Each next lines describes a edge in the edgeset. The
985  /// line contains the source and the target nodes' label and the mapped
986  /// values for each map.
987  ///
988  /// If the edgeset contains an \c "label" named map then it will be regarded
989  /// as label map. This map should contain only unique values and when the
990  /// \c writeLabel() member will be called with an edge it will write it's
991  /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
992  /// then the label map will be the id in the graph. In addition if the
993  /// the \c _forceSort is true then the writer will write the edges
994  /// sorted by the labels.
995  ///
996  /// The edgeset writer needs a node label writer to identify which nodes
997  /// have to be connected. If a NodeSetWriter can write the nodes' label,
998  /// it will be able to use with this class.
999  ///
1000  /// \relates LemonWriter
1001  template <typename _Graph, typename _Traits = DefaultWriterTraits>
1002  class EdgeSetWriter : public LemonWriter::SectionWriter {
1003    typedef LemonWriter::SectionWriter Parent;
1004  public:
1005
1006    typedef _Graph Graph;
1007    typedef _Traits Traits;
1008    typedef typename Graph::Node Node;
1009    typedef typename Graph::Edge Edge;
1010
1011    /// \brief Constructor.
1012    ///
1013    /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter
1014    /// and attach it into the given LemonWriter. It will write node
1015    /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
1016    /// parameter is true then the writer will write own label map if
1017    /// the user does not give "label" named map. In addition if the
1018    /// the \c _forceSort is true then the writer will write the
1019    /// edges sorted by the labels.
1020    template <typename NodeLabelWriter>
1021    EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
1022                  const NodeLabelWriter& _nodeLabelWriter,
1023                  const std::string& _name = std::string(),
1024                  bool _forceLabelMap = true, bool _forceSort = true)
1025      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
1026        forceSort(_forceSort), graph(_graph), name(_name) {
1027      checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
1028      nodeLabelWriter.reset(new _writer_bits::
1029                         LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
1030    }
1031
1032    /// \brief Destructor.
1033    ///
1034    /// Destructor for EdgeSetWriter.
1035    virtual ~EdgeSetWriter() {
1036      typename MapWriters::iterator it;
1037      for (it = writers.begin(); it != writers.end(); ++it) {
1038        delete it->second;
1039      }
1040    }
1041
1042  private:
1043    EdgeSetWriter(const EdgeSetWriter&);
1044    void operator=(const EdgeSetWriter&);
1045
1046  public:
1047
1048    /// \brief Add a new edge map writer command for the writer.
1049    ///
1050    /// Add a new edge map writer command for the writer.
1051    template <typename Map>
1052    EdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
1053      return writeEdgeMap<typename Traits::
1054        template Writer<typename Map::Value>, Map>(label, map);
1055    }
1056
1057    /// \brief Add a new edge map writer command for the writer.
1058    ///
1059    /// Add a new edge map writer command for the writer.
1060    template <typename ItemWriter, typename Map>
1061    EdgeSetWriter& writeEdgeMap(std::string label, const Map& map,
1062                            const ItemWriter& iw = ItemWriter()) {
1063      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1064      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1065      writers.push_back(
1066        make_pair(label, new _writer_bits::
1067                  MapWriter<Edge, Map, ItemWriter>(map, iw)));
1068      return *this;
1069    }
1070
1071  protected:
1072
1073    /// \brief The header of the section.
1074    ///
1075    /// It gives back the header of the section.
1076    virtual std::string header() {
1077      return "@edgeset " + name;
1078    }
1079
1080    /// \brief  Writer function of the section.
1081    ///
1082    /// Write the content of the section.
1083    virtual void write(std::ostream& os) {
1084      if (!nodeLabelWriter->isLabelWriter()) {
1085        throw DataFormatError("Cannot find nodeset or label map");
1086      }
1087      for (int i = 0; i < int(writers.size()); ++i) {
1088        if (writers[i].first == "label") {
1089          labelMap = writers[i].second;
1090          forceLabelMap = false;
1091          break;
1092        }
1093      }
1094      std::vector<Edge> items;
1095      for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
1096        items.push_back(it);
1097      }
1098      if (forceSort) {
1099        if (labelMap) {
1100          labelMap->sort(items);
1101        } else {
1102          typedef IdMap<Graph, Edge> Map;
1103          Map map(graph);
1104          _writer_bits::ComposeLess<Map> less(map);
1105          std::sort(items.begin(), items.end(), less);
1106        }
1107      }
1108      os << "\t\t";
1109      if (forceLabelMap) {
1110        os << "label\t";
1111      }
1112      for (int i = 0; i < int(writers.size()); ++i) {
1113        os << writers[i].first << '\t';
1114      }
1115      os << std::endl;
1116      for (typename std::vector<Edge>::iterator it = items.begin();
1117           it != items.end(); ++it) {
1118        nodeLabelWriter->write(os, graph.source(*it));
1119        os << '\t';
1120        nodeLabelWriter->write(os, graph.target(*it));
1121        os << '\t';
1122        if (forceLabelMap) {
1123          os << graph.id(*it) << '\t';
1124        }
1125        for (int i = 0; i < int(writers.size()); ++i) {
1126          writers[i].second->write(os, *it);
1127          os << '\t';
1128        }
1129        os << std::endl;
1130      }
1131    }
1132
1133  public:
1134
1135    /// \brief Returns true if the edgeset can write the labels of the edges.
1136    ///
1137    /// Returns true if the edgeset can write the labels of the edges.
1138    /// It is possible only if a "label" named map was written or the
1139    /// \c _forceLabelMap constructor parameter was true.
1140    bool isLabelWriter() const {
1141      return forceLabelMap || labelMap != 0;
1142    }
1143
1144    /// \brief Write the label of the given edge.
1145    ///
1146    /// It writes the label of the given edge. If there was written a "label"
1147    /// named map then it will write the map value belongs to the edge.
1148    /// Otherwise if the \c forceLabel parameter was true it will write
1149    /// its label in the graph.
1150    void writeLabel(std::ostream& os, const Edge& item) const {
1151      if (forceLabelMap) {
1152        os << graph.id(item);
1153      } else {
1154        labelMap->write(os, item);
1155      }
1156    }
1157
1158    /// \brief Sorts the given edge vector by label.
1159    ///
1160    /// Sorts the given edge vector by label. If there was written an
1161    /// "label" named map then the vector will be sorted by the values
1162    /// of this map. Otherwise if the \c forceLabel parameter was true
1163    /// it will be sorted by its id in the graph.
1164    void sortByLabel(std::vector<Edge>& edges) const {
1165      if (labelMap) {
1166        labelMap->sort(edges);
1167      } else {
1168        typedef IdMap<Graph, Edge> Map;
1169        Map map(graph);
1170        _writer_bits::ComposeLess<Map> less(map);
1171        std::sort(edges.begin(), edges.end(), less);
1172      }
1173    }
1174
1175  private:
1176
1177    typedef std::vector<std::pair<std::string, _writer_bits::
1178                                  MapWriterBase<Edge>*> > MapWriters;
1179    MapWriters writers;
1180
1181    _writer_bits::MapWriterBase<Edge>* labelMap;
1182    bool forceLabelMap;
1183    bool forceSort;
1184   
1185    const Graph& graph;   
1186    std::string name;
1187
1188    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
1189  };
1190
1191  /// \ingroup section_io
1192  /// \brief SectionWriter for writing a undirected edgeset.
1193  ///
1194  /// The lemon format can store multiple undirected edgesets with several
1195  /// maps. The undirected edgeset section's header line is \c \@uedgeset
1196  /// \c uedgeset_name, but the \c uedgeset_name may be empty.
1197  ///
1198  /// The first line of the section contains the names of the maps separated
1199  /// with white spaces. Each next lines describes an undirected edge in the
1200  /// edgeset. The line contains the two connected nodes' label and the mapped
1201  /// values for each undirected map.
1202  ///
1203  /// The section can handle the directed as a syntactical sugar. Two
1204  /// undirected edge map describes one directed edge map. This two maps
1205  /// are the forward map and the backward map and the names of this map
1206  /// is near the same just with a prefix \c '+' or \c '-' character
1207  /// difference.
1208  ///
1209  /// If the edgeset contains an \c "label" named map then it will be
1210  /// regarded as label map. This map should contain only unique
1211  /// values and when the \c writeLabel() member will be called with
1212  /// an undirected edge it will write it's label. Otherwise if the \c
1213  /// _forceLabelMap constructor parameter is true then the label map
1214  /// will be the id in the graph.  In addition if the the \c
1215  /// _forceSort is true then the writer will write the edges sorted
1216  /// by the labels.
1217  ///
1218  /// The undirected edgeset writer needs a node label writer to identify
1219  /// which nodes have to be connected. If a NodeSetWriter can write the
1220  /// nodes' label, it will be able to use with this class.
1221  ///
1222  /// \relates LemonWriter
1223  template <typename _Graph, typename _Traits = DefaultWriterTraits>
1224  class UEdgeSetWriter : public LemonWriter::SectionWriter {
1225    typedef LemonWriter::SectionWriter Parent;
1226  public:
1227
1228    typedef _Graph Graph;
1229    typedef _Traits Traits;
1230    typedef typename Graph::Node Node;
1231    typedef typename Graph::Edge Edge;
1232    typedef typename Graph::UEdge UEdge;
1233
1234    /// \brief Constructor.
1235    ///
1236    /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
1237    /// and attach it into the given LemonWriter. It will write node
1238    /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
1239    /// parameter is true then the writer will write own label map if
1240    /// the user does not give "label" named map. In addition if the
1241    /// the \c _forceSort is true then the writer will write the
1242    /// edges sorted by the labels.
1243    template <typename NodeLabelWriter>
1244    UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
1245                       const NodeLabelWriter& _nodeLabelWriter,
1246                       const std::string& _name = std::string(),
1247                       bool _forceLabelMap = true, bool _forceSort = true)
1248      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
1249        forceSort(_forceSort), graph(_graph), name(_name) {
1250      checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
1251      nodeLabelWriter.reset(new _writer_bits::
1252        LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
1253    }
1254
1255    /// \brief Destructor.
1256    ///
1257    /// Destructor for UEdgeSetWriter.
1258    virtual ~UEdgeSetWriter() {
1259      typename MapWriters::iterator it;
1260      for (it = writers.begin(); it != writers.end(); ++it) {
1261        delete it->second;
1262      }
1263    }
1264
1265  private:
1266    UEdgeSetWriter(const UEdgeSetWriter&);
1267    void operator=(const UEdgeSetWriter&);
1268
1269  public:
1270
1271    /// \brief Add a new undirected edge map writer command for the writer.
1272    ///
1273    /// Add a new undirected map writer command for the writer.
1274    template <typename Map>
1275    UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map) {
1276      return writeUEdgeMap<typename Traits::
1277        template Writer<typename Map::Value>, Map>(label, map);
1278    }
1279
1280    /// \brief Add a new undirected map writer command for the writer.
1281    ///
1282    /// Add a new undirected map writer command for the writer.
1283    template <typename ItemWriter, typename Map>
1284    UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map,
1285                                  const ItemWriter& iw = ItemWriter()) {
1286      checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
1287      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1288      writers.push_back(
1289        make_pair(label, new _writer_bits::
1290                  UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
1291      return *this;
1292    }
1293
1294    /// \brief Add a new directed edge map writer command for the writer.
1295    ///
1296    /// Add a new directed map writer command for the writer.
1297    template <typename Map>
1298    UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
1299      return writeEdgeMap<typename Traits::
1300        template Writer<typename Map::Value>, Map>(label, map);
1301    }
1302
1303    /// \brief Add a new directed map writer command for the writer.
1304    ///
1305    /// Add a new directed map writer command for the writer.
1306    template <typename ItemWriter, typename Map>
1307    UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map,
1308                                 const ItemWriter& iw = ItemWriter()) {
1309      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1310      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1311      writeUEdgeMap("+" + label,
1312                    _writer_bits::forwardComposeMap(graph, map), iw);
1313      writeUEdgeMap("-" + label,
1314                    _writer_bits::backwardComposeMap(graph, map), iw);
1315      return *this;
1316    }
1317
1318  protected:
1319
1320    /// \brief The header of the section.
1321    ///
1322    /// It gives back the header of the section.
1323    virtual std::string header() {
1324      return "@uedgeset " + name;
1325    }
1326
1327    /// \brief  Writer function of the section.
1328    ///
1329    /// Write the content of the section.
1330    virtual void write(std::ostream& os) {
1331      if (!nodeLabelWriter->isLabelWriter()) {
1332        throw DataFormatError("Cannot find nodeset or label map");
1333      }
1334      for (int i = 0; i < int(writers.size()); ++i) {
1335        if (writers[i].first == "label") {
1336          labelMap = writers[i].second;
1337          forceLabelMap = false;
1338          break;
1339        }
1340      }
1341      std::vector<UEdge> items;
1342      for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
1343        items.push_back(it);
1344      }
1345      if (forceSort) {
1346        if (labelMap) {
1347          labelMap->sort(items);
1348        } else {
1349          typedef IdMap<Graph, UEdge> Map;
1350          Map map(graph);
1351          _writer_bits::ComposeLess<Map> less(map);
1352          std::sort(items.begin(), items.end(), less);
1353        }
1354      }
1355      os << "\t\t";
1356      if (forceLabelMap) {
1357        os << "label\t";
1358      }
1359      for (int i = 0; i < int(writers.size()); ++i) {
1360        os << writers[i].first << '\t';
1361      }
1362      os << std::endl;
1363      for (typename std::vector<UEdge>::iterator it = items.begin();
1364           it != items.end(); ++it) {
1365        nodeLabelWriter->write(os, graph.source(*it));
1366        os << '\t';
1367        nodeLabelWriter->write(os, graph.target(*it));
1368        os << '\t';
1369        if (forceLabelMap) {
1370          os << graph.id(*it) << '\t';
1371        }
1372        for (int i = 0; i < int(writers.size()); ++i) {
1373          writers[i].second->write(os, *it);
1374          os << '\t';
1375        }
1376        os << std::endl;
1377      }
1378    }
1379
1380  public:
1381
1382    /// \brief Returns true if the undirected edgeset can write the labels of
1383    /// the edges.
1384    ///
1385    /// Returns true if the undirected edgeset can write the labels of the
1386    /// undirected edges. It is possible only if a "label" named map was
1387    /// written or the \c _forceLabelMap constructor parameter was true.
1388    bool isLabelWriter() const {
1389      return forceLabelMap || labelMap != 0;
1390    }
1391
1392    /// \brief Write the label of the given undirected edge.
1393    ///
1394    /// It writes the label of the given undirected edge. If there was written
1395    /// a "label" named map then it will write the map value belongs to the
1396    /// undirected edge. Otherwise if the \c forceLabel parameter was true it
1397    /// will write its id in the graph.
1398    void writeLabel(std::ostream& os, const UEdge& item) const {
1399      if (forceLabelMap) {
1400        os << graph.id(item);
1401      } else {
1402        labelMap->write(os, item);
1403      }
1404    }
1405
1406    /// \brief Write the label of the given edge.
1407    ///
1408    /// It writes the label of the given edge. If there was written
1409    /// a "label" named map then it will write the map value belongs to the
1410    /// edge. Otherwise if the \c forceLabel parameter was true it
1411    /// will write its id in the graph. If the edge is forward map
1412    /// then its prefix character is \c '+' elsewhere \c '-'.
1413    void writeLabel(std::ostream& os, const Edge& item) const {
1414      if (graph.direction(item)) {
1415        os << "+";
1416      } else {
1417        os << "-";
1418      }
1419      if (forceLabelMap) {
1420        os << graph.id(static_cast<const UEdge&>(item));
1421      } else {
1422        labelMap->write(os, item);
1423      }
1424    }
1425
1426    /// \brief Sorts the given undirected edge vector by label.
1427    ///
1428    /// Sorts the given undirected edge vector by label. If there was
1429    /// written a "label" named map then the vector will be sorted by
1430    /// the values of this map. Otherwise if the \c forceLabel
1431    /// parameter was true it will be sorted by its id in the graph.
1432    void sortByLabel(std::vector<UEdge>& uedges) const {
1433      if (labelMap) {
1434        labelMap->sort(uedges);
1435      } else {
1436        typedef IdMap<Graph, UEdge> Map;
1437        Map map(graph);
1438        _writer_bits::ComposeLess<Map> less(map);
1439        std::sort(uedges.begin(), uedges.end(), less);
1440      }
1441    }
1442
1443    /// \brief Sorts the given edge vector by label.
1444    ///
1445    /// Sorts the given edge vector by label. If there was written a
1446    /// "label" named map then the vector will be sorted by the values
1447    /// of this map. Otherwise if the \c forceLabel parameter was true
1448    /// it will be sorted by its id in the graph.
1449    void sortByLabel(std::vector<Edge>& edges) const {
1450      if (labelMap) {
1451        labelMap->sort(graph, edges);
1452      } else {
1453        typedef IdMap<Graph, Edge> Map;
1454        Map map(graph);
1455        _writer_bits::ComposeLess<Map> less(map);
1456        std::sort(edges.begin(), edges.end(), less);
1457      }
1458    }
1459
1460  private:
1461
1462    typedef std::vector<std::pair<std::string, _writer_bits::
1463                                  UEdgeMapWriterBase<Graph>*> > MapWriters;
1464    MapWriters writers;
1465
1466    _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
1467    bool forceLabelMap;
1468    bool forceSort;
1469   
1470    const Graph& graph;   
1471    std::string name;
1472
1473    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
1474  };
1475
1476  /// \ingroup section_io
1477  /// \brief SectionWriter for writing named nodes.
1478  ///
1479  /// The nodes section's header line is \c \@nodes \c nodes_name, but the
1480  /// \c nodes_name may be empty.
1481  ///
1482  /// Each line in the section contains the name of the node and
1483  /// then the node label.
1484  ///
1485  /// \relates LemonWriter
1486  template <typename _Graph>
1487  class NodeWriter : public LemonWriter::SectionWriter {
1488    typedef LemonWriter::SectionWriter Parent;
1489    typedef _Graph Graph;
1490    typedef typename Graph::Node Node;
1491  public:
1492   
1493    /// \brief Constructor.
1494    ///
1495    /// Constructor for NodeWriter. It creates the NodeWriter and
1496    /// attach it into the given LemonWriter. The given \c _LabelWriter
1497    /// will write the nodes' label what can be a nodeset writer.
1498    template <typename _LabelWriter>
1499    NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1500               const std::string& _name = std::string())
1501      : Parent(_writer), name(_name) {
1502      checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
1503      labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
1504                        (_labelWriter));
1505    }
1506
1507
1508    /// \brief Destructor.
1509    ///
1510    /// Destructor for NodeWriter.
1511    virtual ~NodeWriter() {}
1512
1513  private:
1514    NodeWriter(const NodeWriter&);
1515    void operator=(const NodeWriter&);
1516
1517  public:
1518
1519    /// \brief Add a node writer command for the NodeWriter.
1520    ///
1521    /// Add a node writer command for the NodeWriter.
1522    void writeNode(std::string label, const Node& item) {
1523      writers.push_back(make_pair(label, &item));
1524    }
1525
1526  protected:
1527
1528    /// \brief The header of the section.
1529    ///
1530    /// It gives back the header of the section.
1531    virtual std::string header() {
1532      return "@nodes " + name;
1533    }
1534
1535    /// \brief  Writer function of the section.
1536    ///
1537    /// Write the content of the section.
1538    virtual void write(std::ostream& os) {
1539      if (!labelWriter->isLabelWriter()) {
1540        throw DataFormatError("Cannot find nodeset or label map");
1541      }
1542      for (int i = 0; i < int(writers.size()); ++i) {
1543        os << writers[i].first << ' ';
1544        labelWriter->write(os, *(writers[i].second));
1545        os << std::endl;
1546      }
1547    }
1548
1549    /// \brief Gives back true when the section should be written.
1550    ///
1551    /// Gives back true when the section should be written.
1552    virtual bool valid() { return !writers.empty(); }
1553   
1554  private:
1555
1556    std::string name;
1557
1558    typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
1559    NodeWriters writers;
1560    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1561  };
1562
1563  /// \ingroup section_io
1564  /// \brief SectionWriter for writing named edges.
1565  ///
1566  /// The edges section's header line is \c \@edges \c edges_name, but the
1567  /// \c edges_name may be empty.
1568  ///
1569  /// Each line in the section contains the name of the edge and
1570  /// then the edge label.
1571  ///
1572  /// \relates LemonWriter
1573  template <typename _Graph>
1574  class EdgeWriter : public LemonWriter::SectionWriter {
1575    typedef LemonWriter::SectionWriter Parent;
1576    typedef _Graph Graph;
1577    typedef typename Graph::Edge Edge;
1578  public:
1579   
1580    /// \brief Constructor.
1581    ///
1582    /// Constructor for EdgeWriter. It creates the EdgeWriter and
1583    /// attach it into the given LemonWriter. The given \c _LabelWriter
1584    /// will write the edges' label what can be a edgeset writer.
1585    template <typename _LabelWriter>
1586    EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1587               const std::string& _name = std::string())
1588      : Parent(_writer), name(_name) {
1589      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1590      labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
1591    }
1592
1593    /// \brief Destructor.
1594    ///
1595    /// Destructor for EdgeWriter.
1596    virtual ~EdgeWriter() {}
1597  private:
1598    EdgeWriter(const EdgeWriter&);
1599    void operator=(const EdgeWriter&);
1600
1601  public:
1602
1603    /// \brief Add an edge writer command for the EdgeWriter.
1604    ///
1605    /// Add an edge writer command for the EdgeWriter.
1606    void writeEdge(std::string label, const Edge& item) {
1607      writers.push_back(make_pair(label, &item));
1608    }
1609
1610  protected:
1611
1612    /// \brief The header of the section.
1613    ///
1614    /// It gives back the header of the section.
1615    virtual std::string header() {
1616      return "@edges " + name;
1617    }
1618
1619    /// \brief  Writer function of the section.
1620    ///
1621    /// Write the content of the section.
1622    virtual void write(std::ostream& os) {
1623      if (!labelWriter->isLabelWriter()) {
1624        throw DataFormatError("Cannot find edgeset or label map");
1625      }
1626      for (int i = 0; i < int(writers.size()); ++i) {
1627        os << writers[i].first << ' ';
1628        labelWriter->write(os, *(writers[i].second));
1629        os << std::endl;
1630      }
1631    }
1632
1633    /// \brief Gives back true when the section should be written.
1634    ///
1635    /// Gives back true when the section should be written.
1636    virtual bool valid() { return !writers.empty(); }
1637   
1638  private:
1639
1640    std::string name;
1641
1642    typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1643    EdgeWriters writers;
1644
1645    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
1646  };
1647
1648
1649  /// \ingroup section_io
1650  /// \brief SectionWriter for writing named undirected edges.
1651  ///
1652  /// The undirected edges section's header line is \c \@uedges
1653  /// \c uedges_name, but the \c uedges_name may be empty.
1654  ///
1655  /// Each line in the section contains the name of the undirected edge and
1656  /// then the undirected edge label.
1657  ///
1658  /// \relates LemonWriter
1659  template <typename _Graph>
1660  class UEdgeWriter : public LemonWriter::SectionWriter {
1661    typedef LemonWriter::SectionWriter Parent;
1662    typedef _Graph Graph;
1663    typedef typename Graph::Node Node;
1664    typedef typename Graph::Edge Edge;
1665    typedef typename Graph::UEdge UEdge;
1666  public:
1667   
1668    /// \brief Constructor.
1669    ///
1670    /// Constructor for UEdgeWriter. It creates the UEdgeWriter and
1671    /// attach it into the given LemonWriter. The given \c _LabelWriter
1672    /// will write the undirected edges' label what can be an undirected
1673    /// edgeset writer.
1674    template <typename _LabelWriter>
1675    UEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1676               const std::string& _name = std::string())
1677      : Parent(_writer), name(_name) {
1678      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1679      checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
1680      uEdgeLabelWriter.reset(new _writer_bits::
1681                              LabelWriter<UEdge, _LabelWriter>(_labelWriter));
1682      edgeLabelWriter.reset(new _writer_bits::
1683                         LabelWriter<Edge, _LabelWriter>(_labelWriter));
1684    }
1685
1686    /// \brief Destructor.
1687    ///
1688    /// Destructor for UEdgeWriter.
1689    virtual ~UEdgeWriter() {}
1690  private:
1691    UEdgeWriter(const UEdgeWriter&);
1692    void operator=(const UEdgeWriter&);
1693
1694  public:
1695
1696    /// \brief Add an edge writer command for the UEdgeWriter.
1697    ///
1698    /// Add an edge writer command for the UEdgeWriter.
1699    void writeEdge(std::string label, const Edge& item) {
1700      edgeWriters.push_back(make_pair(label, &item));
1701    }
1702
1703    /// \brief Add an undirected edge writer command for the UEdgeWriter.
1704    ///
1705    /// Add an undirected edge writer command for the UEdgeWriter.
1706    void writeUEdge(std::string label, const UEdge& item) {
1707      uEdgeWriters.push_back(make_pair(label, &item));
1708    }
1709
1710  protected:
1711
1712    /// \brief The header of the section.
1713    ///
1714    /// It gives back the header of the section.
1715    virtual std::string header() {
1716      return "@uedges " + name;
1717    }
1718
1719    /// \brief  Writer function of the section.
1720    ///
1721    /// Write the content of the section.
1722    virtual void write(std::ostream& os) {
1723      if (!edgeLabelWriter->isLabelWriter()) {
1724        throw DataFormatError("Cannot find undirected edgeset or label map");
1725      }
1726      if (!uEdgeLabelWriter->isLabelWriter()) {
1727        throw DataFormatError("Cannot find undirected edgeset or label map");
1728      }
1729      for (int i = 0; i < int(uEdgeWriters.size()); ++i) {
1730        os << uEdgeWriters[i].first << ' ';
1731        uEdgeLabelWriter->write(os, *(uEdgeWriters[i].second));
1732        os << std::endl;
1733      }
1734      for (int i = 0; i < int(edgeWriters.size()); ++i) {
1735        os << edgeWriters[i].first << ' ';
1736        edgeLabelWriter->write(os, *(edgeWriters[i].second));
1737        os << std::endl;
1738      }
1739    }
1740
1741    /// \brief Gives back true when the section should be written.
1742    ///
1743    /// Gives back true when the section should be written.
1744    virtual bool valid() {
1745      return !uEdgeWriters.empty() || !edgeWriters.empty();
1746    }
1747   
1748  private:
1749
1750    std::string name;
1751
1752    typedef std::vector<std::pair<std::string,
1753                                  const UEdge*> > UEdgeWriters;
1754    UEdgeWriters uEdgeWriters;
1755    std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > uEdgeLabelWriter;
1756
1757    typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1758    EdgeWriters edgeWriters;
1759    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
1760
1761  };
1762
1763  /// \ingroup section_io
1764  /// \brief SectionWriter for writing extra node maps.
1765  ///
1766  /// The lemon format can store maps in the nodeset. This class let
1767  /// you make distinict section to store maps. The main purpose of
1768  /// this class is a logical separation of some maps. The other
1769  /// useful application could be to store paths in node maps.
1770  ///
1771  /// The first line of the section contains the names of the maps
1772  /// separated with white spaces. Each next line describes an item
1773  /// in the itemset, and contains in the first column the label of
1774  /// the item and then the mapped values for each map.
1775  ///
1776  /// \relates LemonWriter
1777  template <typename _Graph, typename _Traits = DefaultWriterTraits>
1778  class NodeMapWriter : public LemonWriter::SectionWriter {
1779    typedef LemonWriter::SectionWriter Parent;
1780  public:
1781
1782    typedef _Graph Graph;
1783    typedef _Traits Traits;
1784    typedef typename Graph::Node Node;
1785
1786    /// \brief Constructor.
1787    ///
1788    /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
1789    /// attach it into the given LemonWriter. If the the
1790    /// \c _forceSort is true then the writer will write the edges
1791    /// sorted by the labels.
1792    template <typename _LabelWriter>
1793    NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
1794                 const _LabelWriter& _labelWriter,
1795                 const std::string& _name = std::string(),
1796                 bool _forceSort = true)
1797      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1798      checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
1799      labelWriter.reset(new _writer_bits::LabelWriter<Node,
1800                        _LabelWriter>(_labelWriter));
1801    }
1802
1803    /// \brief Destructor.
1804    ///
1805    /// Destructor for NodeMapWriter.
1806    virtual ~NodeMapWriter() {
1807      typename MapWriters::iterator it;
1808      for (it = writers.begin(); it != writers.end(); ++it) {
1809        delete it->second;
1810      }
1811    }
1812
1813  private:
1814    NodeMapWriter(const NodeMapWriter&);
1815    void operator=(const NodeMapWriter&);
1816 
1817  public:
1818
1819    /// \brief Add a new node map writer command for the writer.
1820    ///
1821    /// Add a new node map writer command for the writer.
1822    template <typename Map>
1823    NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
1824      return writeNodeMap<typename Traits::
1825        template Writer<typename Map::Value>, Map>(label, map);
1826    }
1827
1828    /// \brief Add a new node map writer command for the writer.
1829    ///
1830    /// Add a new node map writer command for the writer.
1831    template <typename ItemWriter, typename Map>
1832    NodeMapWriter& writeNodeMap(std::string label, const Map& map,
1833                           const ItemWriter& iw = ItemWriter()) {
1834      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1835      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1836      writers.push_back(
1837        make_pair(label, new _writer_bits::
1838                  MapWriter<Node, Map, ItemWriter>(map, iw)));
1839      return *this;
1840    }
1841
1842  protected:
1843
1844    /// \brief The header of the section.
1845    ///
1846    /// It gives back the header of the section.
1847    virtual std::string header() {
1848      return "@nodemaps " + name;
1849    }
1850
1851    /// \brief  Writer function of the section.
1852    ///
1853    /// Write the content of the section.
1854    virtual void write(std::ostream& os) {
1855      std::vector<Node> nodes;
1856      for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
1857        nodes.push_back(it);
1858      }
1859      if (forceSort) {
1860        labelWriter->sort(nodes);
1861      }
1862      os << '\t';
1863      for (int i = 0; i < int(writers.size()); ++i) {
1864        os << writers[i].first << '\t';
1865      }
1866      os << std::endl;
1867      for (typename std::vector<Node>::iterator it = nodes.begin();
1868           it != nodes.end(); ++it) {
1869
1870        labelWriter->write(os, *it); os << '\t';
1871        for (int i = 0; i < int(writers.size()); ++i) {
1872          writers[i].second->write(os, *it);
1873          os << '\t';
1874        }
1875        os << std::endl;
1876      }
1877    }
1878
1879
1880  private:
1881
1882    typedef std::vector<std::pair<std::string, _writer_bits::
1883                                  MapWriterBase<Node>*> > MapWriters;
1884    MapWriters writers;
1885
1886    _writer_bits::MapWriterBase<Node>* labelMap;
1887
1888    const Graph& graph;   
1889    std::string name;
1890    bool forceSort;
1891
1892    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1893  };
1894
1895  /// \ingroup section_io
1896  /// \brief SectionWriter for writing extra edge maps.
1897  ///
1898  /// The lemon format can store maps in the edgeset. This class let
1899  /// you make distinict section to store maps. The main purpose of
1900  /// this class is a logical separation of some maps. The other
1901  /// useful application could be to store paths in edge maps.
1902  ///
1903  /// The first line of the section contains the names of the maps
1904  /// separated with white spaces. Each next line describes an item
1905  /// in the itemset, and contains in the first column the label of
1906  /// the item and then the mapped values for each map.
1907  ///
1908  /// \relates LemonWriter
1909  template <typename _Graph, typename _Traits = DefaultWriterTraits>
1910  class EdgeMapWriter : public LemonWriter::SectionWriter {
1911    typedef LemonWriter::SectionWriter Parent;
1912  public:
1913
1914    typedef _Graph Graph;
1915    typedef _Traits Traits;
1916    typedef typename Graph::Edge Edge;
1917
1918    /// \brief Constructor.
1919    ///
1920    /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
1921    /// attach it into the given LemonWriter. If the the
1922    /// \c _forceSort is true then the writer will write the edges
1923    /// sorted by the labels.
1924    template <typename _LabelWriter>
1925    EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
1926                 const _LabelWriter& _labelWriter,
1927                 const std::string& _name = std::string(),
1928                 bool _forceSort = true)
1929      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1930      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1931      labelWriter.reset(new _writer_bits::LabelWriter<Edge,
1932                        _LabelWriter>(_labelWriter));
1933    }
1934
1935    /// \brief Destructor.
1936    ///
1937    /// Destructor for EdgeMapWriter.
1938    virtual ~EdgeMapWriter() {
1939      typename MapWriters::iterator it;
1940      for (it = writers.begin(); it != writers.end(); ++it) {
1941        delete it->second;
1942      }
1943    }
1944
1945  private:
1946    EdgeMapWriter(const EdgeMapWriter&);
1947    void operator=(const EdgeMapWriter&);
1948 
1949  public:
1950
1951    /// \brief Add a new edge map writer command for the writer.
1952    ///
1953    /// Add a new edge map writer command for the writer.
1954    template <typename Map>
1955    EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
1956      return writeEdgeMap<typename Traits::
1957        template Writer<typename Map::Value>, Map>(label, map);
1958    }
1959
1960    /// \brief Add a new edge map writer command for the writer.
1961    ///
1962    /// Add a new edge map writer command for the writer.
1963    template <typename ItemWriter, typename Map>
1964    EdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
1965                                const ItemWriter& iw = ItemWriter()) {
1966      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1967      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1968      writers.push_back(
1969        make_pair(label, new _writer_bits::
1970                  MapWriter<Edge, Map, ItemWriter>(map, iw)));
1971      return *this;
1972    }
1973
1974  protected:
1975
1976    /// \brief The header of the section.
1977    ///
1978    /// It gives back the header of the section.
1979    virtual std::string header() {
1980      return "@edgemaps " + name;
1981    }
1982
1983    /// \brief  Writer function of the section.
1984    ///
1985    /// Write the content of the section.
1986    virtual void write(std::ostream& os) {
1987      std::vector<Edge> edges;
1988      for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
1989        edges.push_back(it);
1990      }
1991      if (forceSort) {
1992        labelWriter->sort(edges);
1993      }
1994      os << '\t';
1995      for (int i = 0; i < int(writers.size()); ++i) {
1996        os << writers[i].first << '\t';
1997      }
1998      os << std::endl;
1999      for (typename std::vector<Edge>::iterator it = edges.begin();
2000           it != edges.end(); ++it) {
2001
2002        labelWriter->write(os, *it); os << '\t';
2003        for (int i = 0; i < int(writers.size()); ++i) {
2004          writers[i].second->write(os, *it);
2005          os << '\t';
2006        }
2007        os << std::endl;
2008      }
2009    }
2010
2011
2012  private:
2013
2014    typedef std::vector<std::pair<std::string, _writer_bits::
2015                                  MapWriterBase<Edge>*> > MapWriters;
2016    MapWriters writers;
2017
2018    _writer_bits::MapWriterBase<Edge>* labelMap;
2019
2020    const Graph& graph;   
2021    std::string name;
2022    bool forceSort;
2023
2024    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
2025  };
2026
2027  /// \ingroup section_io
2028  /// \brief SectionWriter for writing extra undirected edge maps.
2029  ///
2030  /// The lemon format can store maps in the uedgeset. This class let
2031  /// you make distinict section to store maps. The main purpose of
2032  /// this class is a logical separation of some maps. The other
2033  /// useful application could be to store paths in undirected edge
2034  /// maps.
2035  ///
2036  /// The first line of the section contains the names of the maps
2037  /// separated with white spaces. Each next line describes an item
2038  /// in the itemset, and contains in the first column the label of
2039  /// the item and then the mapped values for each map.
2040  ///
2041  /// \relates LemonWriter
2042  template <typename _Graph, typename _Traits = DefaultWriterTraits>
2043  class UEdgeMapWriter : public LemonWriter::SectionWriter {
2044    typedef LemonWriter::SectionWriter Parent;
2045  public:
2046
2047    typedef _Graph Graph;
2048    typedef _Traits Traits;
2049    typedef typename Graph::UEdge UEdge;
2050    typedef typename Graph::Edge Edge;
2051
2052    /// \brief Constructor.
2053    ///
2054    /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
2055    /// attach it into the given LemonWriter. If the the
2056    /// \c _forceSort is true then the writer will write the uedges
2057    /// sorted by the labels.
2058    template <typename _LabelWriter>
2059    UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
2060                 const _LabelWriter& _labelWriter,
2061                 const std::string& _name = std::string(),
2062                 bool _forceSort = true)
2063      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
2064      checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
2065      labelWriter.reset(new _writer_bits::LabelWriter<UEdge,
2066                            _LabelWriter>(_labelWriter));
2067    }
2068
2069    /// \brief Destructor.
2070    ///
2071    /// Destructor for UEdgeMapWriter.
2072    virtual ~UEdgeMapWriter() {
2073      typename MapWriters::iterator it;
2074      for (it = writers.begin(); it != writers.end(); ++it) {
2075        delete it->second;
2076      }
2077    }
2078
2079  private:
2080    UEdgeMapWriter(const UEdgeMapWriter&);
2081    void operator=(const UEdgeMapWriter&);
2082 
2083  public:
2084
2085    /// \brief Add a new undirected edge map writer command for the writer.
2086    ///
2087    /// Add a new undirected edge map writer command for the writer.
2088    template <typename Map>
2089    UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
2090      return writeUEdgeMap<typename Traits::
2091        template Writer<typename Map::Value>, Map>(label, map);
2092    }
2093
2094    /// \brief Add a new undirected edge map writer command for the writer.
2095    ///
2096    /// Add a new undirected edge map writer command for the writer.
2097    template <typename ItemWriter, typename Map>
2098    UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map,
2099                           const ItemWriter& iw = ItemWriter()) {
2100      checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
2101      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
2102      writers.push_back(
2103        make_pair(label, new _writer_bits::
2104                  MapWriter<UEdge, Map, ItemWriter>(map, iw)));
2105      return *this;
2106    }
2107
2108    /// \brief Add a new directed edge map writer command for the writer.
2109    ///
2110    /// Add a new directed map writer command for the writer.
2111    template <typename Map>
2112    UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
2113      return writeEdgeMap<typename Traits::
2114        template Writer<typename Map::Value>, Map>(label, map);
2115    }
2116
2117    /// \brief Add a new directed map writer command for the writer.
2118    ///
2119    /// Add a new directed map writer command for the writer.
2120    template <typename ItemWriter, typename Map>
2121    UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
2122                                 const ItemWriter& iw = ItemWriter()) {
2123      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
2124      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
2125      writeUEdgeMap("+" + label,
2126                    _writer_bits::forwardComposeMap(graph, map), iw);
2127      writeUEdgeMap("-" + label,
2128                    _writer_bits::backwardComposeMap(graph, map), iw);
2129      return *this;
2130    }
2131
2132  protected:
2133
2134    /// \brief The header of the section.
2135    ///
2136    /// It gives back the header of the section.
2137    virtual std::string header() {
2138      return "@uedgemaps " + name;
2139    }
2140
2141    /// \brief  Writer function of the section.
2142    ///
2143    /// Write the content of the section.
2144    virtual void write(std::ostream& os) {
2145      std::vector<UEdge> uedges;
2146      for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
2147        uedges.push_back(it);
2148      }
2149      if (forceSort) {
2150        labelWriter->sort(uedges);
2151      }
2152      os << '\t';
2153      for (int i = 0; i < int(writers.size()); ++i) {
2154        os << writers[i].first << '\t';
2155      }
2156      os << std::endl;
2157      for (typename std::vector<UEdge>::iterator it = uedges.begin();
2158           it != uedges.end(); ++it) {
2159
2160        labelWriter->write(os, *it); os << '\t';
2161        for (int i = 0; i < int(writers.size()); ++i) {
2162          writers[i].second->write(os, *it);
2163          os << '\t';
2164        }
2165        os << std::endl;
2166      }
2167    }
2168
2169
2170  private:
2171
2172    typedef std::vector<std::pair<std::string, _writer_bits::
2173                                  MapWriterBase<UEdge>*> > MapWriters;
2174    MapWriters writers;
2175
2176    _writer_bits::MapWriterBase<UEdge>* labelMap;
2177
2178    const Graph& graph;   
2179    std::string name;
2180    bool forceSort;
2181
2182    std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
2183  };
2184
2185
2186  /// \ingroup section_io
2187  /// \brief SectionWriter for attributes.
2188  ///
2189  /// The lemon format can store multiple attribute set. Each set has
2190  /// the header line \c \@attributes \c attributes_name, but the
2191  /// attributeset_name may be empty.
2192  ///
2193  /// The attributeset section contains several lines. Each of them starts
2194  /// with the name of attribute and then the value.
2195  ///
2196  /// \relates LemonWriter
2197  template <typename _Traits = DefaultWriterTraits>
2198  class AttributeWriter : public LemonWriter::SectionWriter {
2199    typedef LemonWriter::SectionWriter Parent;
2200    typedef _Traits Traits;
2201  public:
2202    /// \brief Constructor.
2203    ///
2204    /// Constructor for AttributeWriter. It creates the AttributeWriter and
2205    /// attach it into the given LemonWriter.
2206    AttributeWriter(LemonWriter& _writer,
2207                    const std::string& _name = std::string())
2208      : Parent(_writer), name(_name) {}
2209
2210    /// \brief Destructor.
2211    ///
2212    /// Destructor for AttributeWriter.
2213    virtual ~AttributeWriter() {
2214      typename Writers::iterator it;
2215      for (it = writers.begin(); it != writers.end(); ++it) {
2216        delete it->second;
2217      }
2218    }
2219
2220  private:
2221    AttributeWriter(const AttributeWriter&);
2222    void operator=(AttributeWriter&);
2223
2224  public:
2225    /// \brief Add an attribute writer command for the writer.
2226    ///
2227    /// Add an attribute writer command for the writer.
2228    template <typename Value>
2229    AttributeWriter& writeAttribute(std::string label,
2230                                    const Value& value) {
2231      return
2232        writeAttribute<typename Traits::template Writer<Value> >(label, value);
2233    }
2234
2235    /// \brief Add an attribute writer command for the writer.
2236    ///
2237    /// Add an attribute writer command for the writer.
2238    template <typename ItemWriter, typename Value>
2239    AttributeWriter& writeAttribute(std::string label, const Value& value,
2240                                    const ItemWriter& iw = ItemWriter()) {
2241      checkConcept<_writer_bits::ItemWriter<Value>, ItemWriter>();
2242      writers.push_back(make_pair(label, new _writer_bits::
2243                                  ValueWriter<Value, ItemWriter>(value, iw)));
2244      return *this;
2245    }
2246
2247  protected:
2248
2249    /// \brief The header of section.
2250    ///
2251    /// It gives back the header of the section.
2252    std::string header() {
2253      return "@attributes " + name;
2254    }
2255
2256    /// \brief  Writer function of the section.
2257    ///
2258    /// Write the content of the section.
2259    void write(std::ostream& os) {
2260      typename Writers::iterator it;
2261      for (it = writers.begin(); it != writers.end(); ++it) {
2262        os << it->first << ' ';
2263        it->second->write(os);
2264        os << std::endl;
2265      }
2266    }   
2267
2268    /// \brief Gives back true when the section should be written.
2269    ///
2270    /// Gives back true when the section should be written.
2271    virtual bool valid() { return !writers.empty(); }
2272
2273  private:
2274    std::string name;
2275
2276    typedef std::vector<std::pair<std::string,
2277                                  _writer_bits::ValueWriterBase*> > Writers;
2278    Writers writers; 
2279  };
2280
2281
2282}
2283#endif
Note: See TracBrowser for help on using the repository browser.