lemon/lemon_writer.h
author deba
Wed, 25 Jan 2006 14:58:04 +0000
changeset 1904 a64e4735bda6
parent 1875 98698b69a902
child 1909 2d806130e700
permissions -rw-r--r--
Bug fix for empty intervall sorting
deba@1409
     1
/* -*- C++ -*-
ladanyi@1435
     2
 * lemon/lemon_writer.h - Part of LEMON, a generic C++ optimization library
deba@1409
     3
 *
alpar@1875
     4
 * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1409
     5
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1409
     6
 *
deba@1409
     7
 * Permission to use, modify and distribute this software is granted
deba@1409
     8
 * provided that this copyright notice appears in all copies. For
deba@1409
     9
 * precise terms see the accompanying LICENSE file.
deba@1409
    10
 *
deba@1409
    11
 * This software is provided "AS IS" with no warranty of any kind,
deba@1409
    12
 * express or implied, and with no claim as to its suitability for any
deba@1409
    13
 * purpose.
deba@1409
    14
 *
deba@1409
    15
 */
deba@1409
    16
deba@1409
    17
///\ingroup io_group
deba@1409
    18
///\file
deba@1409
    19
///\brief Lemon Format writer.
deba@1409
    20
deba@1409
    21
#ifndef LEMON_LEMON_WRITER_H
deba@1409
    22
#define LEMON_LEMON_WRITER_H
deba@1409
    23
deba@1409
    24
#include <iostream>
deba@1409
    25
#include <fstream>
deba@1409
    26
#include <string>
deba@1409
    27
#include <vector>
deba@1409
    28
#include <algorithm>
deba@1409
    29
#include <map>
deba@1409
    30
#include <memory>
deba@1409
    31
deba@1409
    32
#include <lemon/error.h>
deba@1409
    33
#include <lemon/invalid.h>
deba@1421
    34
#include <lemon/graph_utils.h>
deba@1409
    35
#include <lemon/bits/item_writer.h>
deba@1421
    36
#include <lemon/utility.h>
deba@1421
    37
#include <lemon/maps.h>
deba@1705
    38
#include <lemon/xy.h>
deba@1409
    39
deba@1476
    40
#include <lemon/concept_check.h>
deba@1476
    41
#include <lemon/concept/maps.h>
deba@1476
    42
deba@1409
    43
deba@1409
    44
namespace lemon {
deba@1409
    45
deba@1476
    46
  namespace _writer_bits {
deba@1476
    47
    
deba@1476
    48
    template <typename Item>
deba@1901
    49
    class ItemLabelWriter {
deba@1476
    50
    public:
deba@1476
    51
deba@1901
    52
      bool isLabelWriter() { return true; }
deba@1476
    53
deba@1901
    54
      void writeLabel(std::ostream&, const Item&) {}
deba@1476
    55
      
deba@1901
    56
      template <class _ItemLabelWriter>
deba@1476
    57
      struct Constraints {
deba@1476
    58
	void constraints() {
deba@1901
    59
	  bool b = writer.isLabelWriter();
deba@1476
    60
	  ignore_unused_variable_warning(b);
deba@1901
    61
	  writer.writeLabel(os, item);
deba@1476
    62
	}
deba@1901
    63
	_ItemLabelWriter& writer;
deba@1476
    64
	std::ostream& os;
deba@1492
    65
	const Item& item;
deba@1492
    66
      };
deba@1492
    67
deba@1492
    68
    };
deba@1492
    69
deba@1492
    70
    template <typename Item>
deba@1492
    71
    class ItemWriter {
deba@1492
    72
    public:
deba@1492
    73
deba@1492
    74
      void write(std::ostream&, const Item&) {}
deba@1492
    75
      
deba@1492
    76
      template <class _ItemWriter>
deba@1492
    77
      struct Constraints {
deba@1492
    78
	void constraints() {
deba@1492
    79
	  writer.write(os, item);
deba@1492
    80
	}
deba@1492
    81
	_ItemWriter& writer;
deba@1492
    82
	std::ostream& os;
deba@1492
    83
	const Item& item;
deba@1476
    84
      };
deba@1476
    85
deba@1476
    86
    };
deba@1476
    87
deba@1705
    88
    template <typename Map>
deba@1705
    89
    struct Ref { typedef const Map& Type; };
deba@1705
    90
deba@1705
    91
    template <typename Graph, typename Map>
deba@1705
    92
    class ForwardComposeMap {
deba@1705
    93
    public:
deba@1705
    94
      typedef typename Graph::UndirEdge Key;
deba@1705
    95
      typedef typename Map::Value Value;
deba@1705
    96
deba@1705
    97
      ForwardComposeMap(const Graph& _graph, const Map& _map) 
deba@1705
    98
	: graph(_graph), map(_map) {}
deba@1705
    99
      
deba@1705
   100
      Value operator[](const Key& key) {
deba@1705
   101
	return map[graph.direct(key, false)];
deba@1705
   102
      }
deba@1705
   103
deba@1705
   104
    private:
deba@1705
   105
      typename Ref<Map>::Type map;
deba@1705
   106
      const Graph& graph;
deba@1705
   107
    };
deba@1705
   108
deba@1705
   109
    template <typename Graph, typename Map>
deba@1705
   110
    ForwardComposeMap<Graph, Map>
deba@1705
   111
    forwardComposeMap(const Graph& graph, const Map& map) {
deba@1705
   112
      return ForwardComposeMap<Graph, Map>(graph, map);
deba@1705
   113
    }
deba@1705
   114
deba@1705
   115
    template <typename Graph, typename Map>
deba@1705
   116
    class BackwardComposeMap {
deba@1705
   117
    public:
deba@1705
   118
      typedef typename Graph::UndirEdge Key;
deba@1705
   119
      typedef typename Map::Value Value;
deba@1705
   120
deba@1705
   121
      BackwardComposeMap(const Graph& _graph, const Map& _map) 
deba@1705
   122
	: graph(_graph), map(_map) {}
deba@1705
   123
      
deba@1705
   124
      Value operator[](const Key& key) {
deba@1705
   125
	return map[graph.direct(key, false)];
deba@1705
   126
      }
deba@1705
   127
deba@1705
   128
    private:
deba@1705
   129
      typename Ref<Map>::Type map;
deba@1705
   130
      const Graph& graph;
deba@1705
   131
    };
deba@1705
   132
deba@1705
   133
    template <typename Graph, typename Map>
deba@1705
   134
    BackwardComposeMap<Graph, Map>
deba@1705
   135
    backwardComposeMap(const Graph& graph, const Map& map) {
deba@1705
   136
      return BackwardComposeMap<Graph, Map>(graph, map);
deba@1705
   137
    }
deba@1705
   138
deba@1705
   139
    template <typename Graph, typename Map>
deba@1705
   140
    struct Ref<ForwardComposeMap<Graph, Map> > { 
deba@1705
   141
      typedef ForwardComposeMap<Graph, Map> Type;
deba@1705
   142
    };
deba@1705
   143
deba@1705
   144
    template <typename Graph, typename Map>
deba@1705
   145
    struct Ref<BackwardComposeMap<Graph, Map> > { 
deba@1705
   146
      typedef BackwardComposeMap<Graph, Map> Type; 
deba@1705
   147
    };
deba@1705
   148
deba@1705
   149
    template <typename Map>
deba@1705
   150
    struct Ref<XMap<Map> > { 
deba@1705
   151
      typedef XMap<Map> Type;
deba@1705
   152
    };
deba@1705
   153
    template <typename Map>
deba@1705
   154
    struct Ref<ConstXMap<Map> > { 
deba@1705
   155
      typedef ConstXMap<Map> Type;
deba@1705
   156
    };
deba@1705
   157
deba@1705
   158
    template <typename Map>
deba@1705
   159
    struct Ref<YMap<Map> > { 
deba@1705
   160
      typedef YMap<Map> Type;
deba@1705
   161
    };
deba@1705
   162
    template <typename Map>
deba@1705
   163
    struct Ref<ConstYMap<Map> > { 
deba@1705
   164
      typedef ConstYMap<Map> Type;
deba@1705
   165
    };
deba@1705
   166
deba@1845
   167
deba@1845
   168
    template <typename _Item>    
deba@1845
   169
    class MapWriterBase {
deba@1845
   170
    public:
deba@1845
   171
      typedef _Item Item;
deba@1845
   172
deba@1845
   173
      virtual ~MapWriterBase() {}
deba@1845
   174
deba@1852
   175
      virtual void write(std::ostream& os, const Item& item) const = 0;
deba@1845
   176
    };
deba@1845
   177
deba@1845
   178
deba@1845
   179
    template <typename _Item, typename _Map, typename _Writer>
deba@1845
   180
    class MapWriter : public MapWriterBase<_Item> {
deba@1845
   181
    public:
deba@1845
   182
      typedef _Map Map;
deba@1845
   183
      typedef _Writer Writer;
deba@1845
   184
      typedef typename Writer::Value Value;
deba@1845
   185
      typedef _Item Item;
deba@1845
   186
      
deba@1845
   187
      typename _writer_bits::Ref<Map>::Type map;
deba@1845
   188
      Writer writer;
deba@1845
   189
deba@1845
   190
      MapWriter(const Map& _map, const Writer& _writer) 
deba@1845
   191
	: map(_map), writer(_writer) {}
deba@1845
   192
deba@1845
   193
      virtual ~MapWriter() {}
deba@1845
   194
deba@1852
   195
      virtual void write(std::ostream& os, const Item& item) const {
deba@1845
   196
	Value value = map[item];
deba@1845
   197
	writer.write(os, value);
deba@1845
   198
      }
deba@1845
   199
deba@1845
   200
    };
deba@1845
   201
deba@1845
   202
deba@1845
   203
    class ValueWriterBase {
deba@1845
   204
    public:
deba@1845
   205
      virtual ~ValueWriterBase() {}
deba@1845
   206
      virtual void write(std::ostream&) = 0;
deba@1845
   207
    };
deba@1845
   208
deba@1845
   209
    template <typename _Value, typename _Writer>
deba@1845
   210
    class ValueWriter : public ValueWriterBase {
deba@1845
   211
    public:
deba@1845
   212
      typedef _Value Value;
deba@1845
   213
      typedef _Writer Writer;
deba@1845
   214
deba@1845
   215
      ValueWriter(const Value& _value, const Writer& _writer)
deba@1845
   216
 	: value(_value), writer(_writer) {}
deba@1845
   217
deba@1845
   218
      virtual void write(std::ostream& os) {
deba@1845
   219
	writer.write(os, value);
deba@1845
   220
      }
deba@1845
   221
    private:
deba@1845
   222
      const Value& value;
deba@1845
   223
      Writer writer;
deba@1845
   224
    };
deba@1845
   225
    
deba@1845
   226
deba@1845
   227
    template <typename _Item>
deba@1901
   228
    class LabelWriterBase {
deba@1845
   229
    public:
deba@1845
   230
      typedef _Item Item;
deba@1901
   231
      virtual ~LabelWriterBase() {}
deba@1845
   232
      virtual void write(std::ostream&, const Item&) const = 0;
deba@1901
   233
      virtual bool isLabelWriter() const = 0;
deba@1845
   234
    };
deba@1845
   235
deba@1901
   236
    template <typename _Item, typename _BoxedLabelWriter>
deba@1901
   237
    class LabelWriter : public LabelWriterBase<_Item> {
deba@1845
   238
    public:
deba@1845
   239
      typedef _Item Item;
deba@1901
   240
      typedef _BoxedLabelWriter BoxedLabelWriter;
deba@1845
   241
deba@1901
   242
      const BoxedLabelWriter& labelWriter;
deba@1845
   243
deba@1901
   244
      LabelWriter(const BoxedLabelWriter& _labelWriter) 
deba@1901
   245
	: labelWriter(_labelWriter) {}
deba@1845
   246
deba@1845
   247
      virtual void write(std::ostream& os, const Item& item) const {
deba@1901
   248
	labelWriter.writeLabel(os, item);
deba@1845
   249
      }
deba@1845
   250
deba@1901
   251
      virtual bool isLabelWriter() const {
deba@1901
   252
	return labelWriter.isLabelWriter();
deba@1845
   253
      }
deba@1845
   254
    };
deba@1845
   255
deba@1476
   256
  }
deba@1476
   257
deba@1409
   258
  /// \ingroup io_group
deba@1409
   259
  /// \brief Lemon Format writer class.
deba@1409
   260
  /// 
deba@1409
   261
  /// The Lemon Format contains several sections. We do not want to
deba@1409
   262
  /// determine what sections are in a lemon file we give only a framework
deba@1409
   263
  /// to write a section oriented format.
deba@1409
   264
  ///
deba@1409
   265
  /// In the Lemon Format each section starts with a line contains a \c \@
deba@1409
   266
  /// character on the first not white space position. This line is the
deba@1409
   267
  /// header line of the section. Each next lines belong to this section
deba@1409
   268
  /// while it does not starts with \c \@ character. This line can start a 
deba@1409
   269
  /// new section or if it can close the file with the \c \@end line.
deba@1409
   270
  /// The file format ignore the empty lines and it may contain comments
deba@1409
   271
  /// started with a \c # character to the end of the line. 
deba@1409
   272
  ///
deba@1409
   273
  /// The framework provides an abstract LemonWriter::SectionWriter class
deba@1409
   274
  /// what defines the interface of a SectionWriter. The SectionWriter
deba@1409
   275
  /// has the \c header() member function what gives back the header of the
deba@1409
   276
  /// section. After that it will be called the \c write() member which
deba@1409
   277
  /// should write the content of the section.
deba@1409
   278
  ///
deba@1409
   279
  /// \relates GraphWriter
deba@1409
   280
  /// \relates NodeSetWriter
deba@1409
   281
  /// \relates EdgeSetWriter
deba@1409
   282
  /// \relates NodesWriter
deba@1409
   283
  /// \relates EdgesWriter
deba@1409
   284
  /// \relates AttributeWriter
deba@1409
   285
  class LemonWriter {
deba@1409
   286
  public:
deba@1409
   287
deba@1409
   288
    /// \brief Abstract base class for writing a section.
deba@1409
   289
    ///
deba@1409
   290
    /// This class has an \c header() member function what gives back
deba@1409
   291
    /// the header line of the section. The \c write() member should
deba@1409
   292
    /// write the content of the section to the stream.
deba@1409
   293
    class SectionWriter {
deba@1409
   294
      friend class LemonWriter;
deba@1409
   295
    protected:
deba@1409
   296
      /// \brief Constructor for SectionWriter.
deba@1409
   297
      ///
deba@1409
   298
      /// Constructor for SectionWriter. It attach this writer to
deba@1409
   299
      /// the given LemonWriter.
deba@1409
   300
      SectionWriter(LemonWriter& writer) {
deba@1409
   301
	writer.attach(*this);
deba@1409
   302
      }
alpar@1494
   303
      
alpar@1494
   304
      virtual ~SectionWriter() {}
deba@1409
   305
deba@1409
   306
      /// \brief The header of section.
deba@1409
   307
      ///
deba@1409
   308
      /// It gives back the header of the section.
deba@1409
   309
      virtual std::string header() = 0;
deba@1409
   310
deba@1409
   311
      /// \brief  Writer function of the section.
deba@1409
   312
      ///
deba@1409
   313
      /// Write the content of the section.
deba@1409
   314
      virtual void write(std::ostream& os) = 0;
deba@1409
   315
    };
deba@1409
   316
deba@1409
   317
    /// \brief Constructor for LemonWriter.
deba@1409
   318
    ///
deba@1409
   319
    /// Constructor for LemonWriter which writes to the given stream.
deba@1409
   320
    LemonWriter(std::ostream& _os) 
deba@1409
   321
      : os(&_os), own_os(false) {}
deba@1409
   322
deba@1409
   323
    /// \brief Constructor for LemonWriter.
deba@1409
   324
    ///
deba@1409
   325
    /// Constructor for LemonWriter which writes to the given file.
deba@1409
   326
    LemonWriter(const std::string& filename) 
deba@1409
   327
      : os(0), own_os(true) {
deba@1409
   328
      os = new std::ofstream(filename.c_str());
deba@1409
   329
    }
deba@1409
   330
deba@1409
   331
    /// \brief Desctructor for LemonWriter.
deba@1409
   332
    ///
deba@1409
   333
    /// Desctructor for LemonWriter.
deba@1409
   334
    ~LemonWriter() {
deba@1409
   335
      if (own_os) {
deba@1409
   336
	delete os;
deba@1409
   337
      }
deba@1409
   338
    }
deba@1409
   339
deba@1409
   340
  private:
deba@1409
   341
    LemonWriter(const LemonWriter&);
deba@1409
   342
    void operator=(const LemonWriter&);
deba@1409
   343
deba@1409
   344
    void attach(SectionWriter& writer) {
deba@1409
   345
      writers.push_back(&writer);
deba@1409
   346
    }
deba@1409
   347
deba@1409
   348
  public:
deba@1409
   349
deba@1409
   350
    /// \brief Executes the LemonWriter.
deba@1409
   351
    /// 
deba@1409
   352
    /// It executes the LemonWriter.
deba@1409
   353
    void run() {
deba@1409
   354
      SectionWriters::iterator it;
deba@1409
   355
      for (it = writers.begin(); it != writers.end(); ++it) {
deba@1409
   356
	*os << (*it)->header() << std::endl;
deba@1409
   357
	(*it)->write(*os);
deba@1409
   358
      }
deba@1409
   359
      *os << "@end" << std::endl;
deba@1409
   360
    }
deba@1409
   361
deba@1409
   362
deba@1409
   363
  private:
deba@1409
   364
deba@1409
   365
    std::ostream* os;
deba@1409
   366
    bool own_os;
deba@1409
   367
deba@1409
   368
    typedef std::vector<SectionWriter*> SectionWriters;
deba@1409
   369
    SectionWriters writers;
deba@1409
   370
deba@1409
   371
  };
deba@1409
   372
deba@1409
   373
  /// \ingroup io_group
deba@1409
   374
  /// \brief SectionWriter for writing a graph's nodeset.
deba@1409
   375
  ///
deba@1409
   376
  /// The lemon format can store multiple graph nodesets with several maps.
deba@1901
   377
  /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but 
deba@1901
   378
  /// the \c nodeset_name may be empty.
deba@1409
   379
  ///
deba@1409
   380
  /// The first line of the section contains the names of the maps separated
deba@1409
   381
  /// with white spaces. Each next lines describes a node in the nodeset, and
deba@1409
   382
  /// contains the mapped values for each map.
deba@1409
   383
  ///
deba@1901
   384
  /// If the nodeset contains an \c "label" named map then it will be regarded
deba@1901
   385
  /// as label map. This map should contain only unique values and when the 
deba@1901
   386
  /// \c writeLabel() member will be called with a node it will write it's 
deba@1901
   387
  /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
deba@1901
   388
  /// then the label map will be the id in the graph.
deba@1409
   389
  ///
deba@1409
   390
  /// \relates LemonWriter
deba@1409
   391
  template <typename _Graph, typename _Traits = DefaultWriterTraits>
deba@1845
   392
  class NodeSetWriter : public LemonWriter::SectionWriter {
deba@1845
   393
    typedef LemonWriter::SectionWriter Parent;
deba@1409
   394
  public:
deba@1409
   395
deba@1409
   396
    typedef _Graph Graph;
deba@1409
   397
    typedef _Traits Traits;
deba@1429
   398
    typedef typename Graph::Node Node;
deba@1409
   399
deba@1409
   400
    /// \brief Constructor.
deba@1409
   401
    ///
deba@1409
   402
    /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
deba@1901
   403
    /// attach it into the given LemonWriter. If the \c _forceLabelMap
deba@1901
   404
    /// parameter is true then the writer will write own label map when
deba@1901
   405
    /// the user does not give "label" named map.
deba@1409
   406
    NodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
deba@1901
   407
		  const std::string& _name = std::string(), 
deba@1901
   408
		  bool _forceLabelMap = true) 
deba@1901
   409
      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), 
deba@1901
   410
	graph(_graph), name(_name) {}
deba@1409
   411
deba@1409
   412
    /// \brief Destructor.
deba@1409
   413
    ///
deba@1409
   414
    /// Destructor for NodeSetWriter.
deba@1409
   415
    virtual ~NodeSetWriter() {
deba@1409
   416
      typename MapWriters::iterator it;
deba@1409
   417
      for (it = writers.begin(); it != writers.end(); ++it) {
deba@1409
   418
	delete it->second;
deba@1409
   419
      }
deba@1409
   420
    }
deba@1409
   421
deba@1409
   422
  private:
deba@1409
   423
    NodeSetWriter(const NodeSetWriter&);
deba@1409
   424
    void operator=(const NodeSetWriter&);
deba@1409
   425
  
deba@1409
   426
  public:
deba@1409
   427
deba@1409
   428
    /// \brief Add a new node map writer command for the writer.
deba@1409
   429
    ///
deba@1409
   430
    /// Add a new node map writer command for the writer.
deba@1409
   431
    template <typename Map>
deba@1421
   432
    NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
deba@1421
   433
      return writeNodeMap<typename Traits::
deba@1409
   434
	template Writer<typename Map::Value>, Map>(name, map);
deba@1409
   435
    }
deba@1409
   436
deba@1409
   437
    /// \brief Add a new node map writer command for the writer.
deba@1409
   438
    ///
deba@1409
   439
    /// Add a new node map writer command for the writer.
deba@1409
   440
    template <typename Writer, typename Map>
deba@1421
   441
    NodeSetWriter& writeNodeMap(std::string name, const Map& map, 
deba@1421
   442
			    const Writer& writer = Writer()) {
deba@1492
   443
      checkConcept<concept::ReadMap<Node, typename Map::Value>, Map>();
deba@1492
   444
      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
deba@1409
   445
      writers.push_back(
deba@1845
   446
	make_pair(name, new _writer_bits::
deba@1845
   447
		  MapWriter<Node, Map, Writer>(map, writer)));
deba@1409
   448
      return *this;
deba@1409
   449
    }
deba@1409
   450
deba@1409
   451
  protected:
deba@1409
   452
deba@1409
   453
    /// \brief The header of the section.
deba@1409
   454
    ///
deba@1409
   455
    /// It gives back the header of the section.
deba@1409
   456
    virtual std::string header() {
deba@1901
   457
      return "@nodeset " + name;
deba@1409
   458
    }
deba@1409
   459
deba@1409
   460
    /// \brief  Writer function of the section.
deba@1409
   461
    ///
deba@1409
   462
    /// Write the content of the section.
deba@1409
   463
    virtual void write(std::ostream& os) {
deba@1409
   464
      for (int i = 0; i < (int)writers.size(); ++i) {
deba@1901
   465
	if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) {
deba@1901
   466
	  labelMap = writers[i].second;
deba@1901
   467
	  forceLabelMap = false;
deba@1409
   468
	  break;
deba@1409
   469
	}
deba@1409
   470
      }
deba@1901
   471
      if (forceLabelMap) {
deba@1901
   472
	os << "label\t";
deba@1409
   473
      }
deba@1409
   474
      for (int i = 0; i < (int)writers.size(); ++i) {
deba@1409
   475
	os << writers[i].first << '\t';
deba@1409
   476
      }
deba@1409
   477
      os << std::endl;
deba@1409
   478
      for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
deba@1901
   479
	if (forceLabelMap) {
deba@1409
   480
	  os << graph.id(it) << '\t';
deba@1409
   481
	}
deba@1409
   482
	for (int i = 0; i < (int)writers.size(); ++i) {
deba@1409
   483
	  writers[i].second->write(os, it);
deba@1409
   484
	  os << '\t';
deba@1409
   485
	}
deba@1409
   486
	os << std::endl;
deba@1409
   487
      }
deba@1409
   488
    }
deba@1409
   489
deba@1409
   490
  public:
deba@1409
   491
deba@1901
   492
    /// \brief Returns true if the nodeset can write the labels of the nodes.
deba@1409
   493
    ///
deba@1901
   494
    /// Returns true if the nodeset can write the labels of the nodes.
deba@1901
   495
    /// It is possible only if an "label" named map was written or the 
deba@1901
   496
    /// \c _forceLabelMap constructor parameter was true.
deba@1901
   497
    bool isLabelWriter() const {
deba@1901
   498
      return labelMap != 0 || forceLabelMap;
deba@1409
   499
    }
deba@1409
   500
deba@1901
   501
    /// \brief Write the label of the given node.
deba@1409
   502
    ///
deba@1901
   503
    /// It writes the label of the given node. If there was written an "label"
deba@1409
   504
    /// named map then it will write the map value belongs to the node.
deba@1901
   505
    /// Otherwise if the \c forceLabel parameter was true it will write
deba@1901
   506
    /// its label in the graph. 
deba@1901
   507
    void writeLabel(std::ostream& os, const Node& item) const {
deba@1901
   508
      if (forceLabelMap) {
deba@1409
   509
	os << graph.id(item);
deba@1409
   510
      } else {
deba@1901
   511
	labelMap->write(os, item);
deba@1409
   512
      }
deba@1409
   513
    }
deba@1409
   514
deba@1409
   515
  private:
deba@1409
   516
deba@1845
   517
    typedef std::vector<std::pair<std::string, _writer_bits::
deba@1845
   518
				  MapWriterBase<Node>*> > MapWriters;
deba@1409
   519
    MapWriters writers;
deba@1409
   520
deba@1901
   521
    _writer_bits::MapWriterBase<Node>* labelMap;
deba@1901
   522
    bool forceLabelMap;
deba@1409
   523
   
deba@1705
   524
    const Graph& graph;   
deba@1901
   525
    std::string name;
deba@1409
   526
deba@1409
   527
  };
deba@1409
   528
deba@1409
   529
  /// \ingroup io_group
deba@1421
   530
  /// \brief SectionWriter for writing a graph's edgesets.
deba@1409
   531
  ///
deba@1421
   532
  /// The lemon format can store multiple graph edgesets with several maps. 
deba@1901
   533
  /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but 
deba@1901
   534
  /// the \c edgeset_name may be empty.
deba@1409
   535
  ///
deba@1409
   536
  /// The first line of the section contains the names of the maps separated
deba@1409
   537
  /// with white spaces. Each next lines describes a edge in the edgeset. The
deba@1901
   538
  /// line contains the source and the target nodes' label and the mapped 
deba@1409
   539
  /// values for each map.
deba@1409
   540
  ///
deba@1901
   541
  /// If the edgeset contains an \c "label" named map then it will be regarded
deba@1901
   542
  /// as label map. This map should contain only unique values and when the 
deba@1901
   543
  /// \c writeLabel() member will be called with an edge it will write it's 
deba@1901
   544
  /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
deba@1901
   545
  /// then the label map will be the id in the graph.
deba@1409
   546
  ///
deba@1901
   547
  /// The edgeset writer needs a node label writer to identify which nodes
deba@1901
   548
  /// have to be connected. If a NodeSetWriter can write the nodes' label,
deba@1409
   549
  /// it will be able to use with this class.
deba@1409
   550
  ///
deba@1409
   551
  /// \relates LemonWriter
deba@1409
   552
  template <typename _Graph, typename _Traits = DefaultWriterTraits>
deba@1845
   553
  class EdgeSetWriter : public LemonWriter::SectionWriter {
deba@1845
   554
    typedef LemonWriter::SectionWriter Parent;
deba@1409
   555
  public:
deba@1409
   556
deba@1409
   557
    typedef _Graph Graph;
deba@1409
   558
    typedef _Traits Traits;
deba@1429
   559
    typedef typename Graph::Node Node;
deba@1429
   560
    typedef typename Graph::Edge Edge;
deba@1409
   561
deba@1409
   562
    /// \brief Constructor.
deba@1409
   563
    ///
deba@1409
   564
    /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
deba@1901
   565
    /// attach it into the given LemonWriter. It will write node labels by
deba@1901
   566
    /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true 
deba@1901
   567
    /// then the writer will write own label map if the user does not give 
deba@1901
   568
    /// "label" named map.
deba@1901
   569
    template <typename NodeLabelWriter>
deba@1409
   570
    EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
deba@1901
   571
		  const NodeLabelWriter& _nodeLabelWriter, 
deba@1901
   572
		  const std::string& _name = std::string(),
deba@1901
   573
		  bool _forceLabelMap = true)
deba@1901
   574
      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
deba@1901
   575
	graph(_graph), name(_name) {
deba@1901
   576
      checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
deba@1901
   577
      nodeLabelWriter.reset(new _writer_bits::
deba@1901
   578
			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
deba@1476
   579
    } 
deba@1409
   580
deba@1409
   581
    /// \brief Destructor.
deba@1409
   582
    ///
deba@1409
   583
    /// Destructor for EdgeSetWriter.
deba@1409
   584
    virtual ~EdgeSetWriter() {
deba@1409
   585
      typename MapWriters::iterator it;
deba@1409
   586
      for (it = writers.begin(); it != writers.end(); ++it) {
deba@1409
   587
	delete it->second;
deba@1409
   588
      }
deba@1409
   589
    }
deba@1409
   590
deba@1409
   591
  private:
deba@1409
   592
    EdgeSetWriter(const EdgeSetWriter&);
deba@1409
   593
    void operator=(const EdgeSetWriter&);
deba@1409
   594
deba@1409
   595
  public:
deba@1409
   596
deba@1421
   597
    /// \brief Add a new edge map writer command for the writer.
deba@1409
   598
    ///
deba@1421
   599
    /// Add a new edge map writer command for the writer.
deba@1409
   600
    template <typename Map>
deba@1421
   601
    EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
deba@1421
   602
      return writeEdgeMap<typename Traits::
deba@1409
   603
	template Writer<typename Map::Value>, Map>(name, map);
deba@1409
   604
    }
deba@1409
   605
deba@1421
   606
    /// \brief Add a new edge map writer command for the writer.
deba@1409
   607
    ///
deba@1421
   608
    /// Add a new edge map writer command for the writer.
deba@1409
   609
    template <typename Writer, typename Map>
deba@1421
   610
    EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
deba@1421
   611
			    const Writer& writer = Writer()) {
deba@1492
   612
      checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
deba@1492
   613
      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
deba@1409
   614
      writers.push_back(
deba@1845
   615
	make_pair(name, new _writer_bits::
deba@1845
   616
		  MapWriter<Edge, Map, Writer>(map, writer)));
deba@1409
   617
      return *this;
deba@1409
   618
    }
deba@1409
   619
deba@1409
   620
  protected:
deba@1409
   621
deba@1409
   622
    /// \brief The header of the section.
deba@1409
   623
    ///
deba@1409
   624
    /// It gives back the header of the section.
deba@1409
   625
    virtual std::string header() {
deba@1901
   626
      return "@edgeset " + name;
deba@1409
   627
    }
deba@1409
   628
deba@1409
   629
    /// \brief  Writer function of the section.
deba@1409
   630
    ///
deba@1409
   631
    /// Write the content of the section.
deba@1409
   632
    virtual void write(std::ostream& os) {
deba@1901
   633
      if (!nodeLabelWriter->isLabelWriter()) {
deba@1901
   634
	throw DataFormatError("Cannot find nodeset or label map");
deba@1476
   635
      }
deba@1409
   636
      for (int i = 0; i < (int)writers.size(); ++i) {
deba@1901
   637
	if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) {
deba@1901
   638
	  labelMap = writers[i].second;
deba@1901
   639
	  forceLabelMap = false;
deba@1409
   640
	  break;
deba@1409
   641
	}
deba@1409
   642
      }
deba@1409
   643
      os << "\t\t";
deba@1901
   644
      if (forceLabelMap) {
deba@1901
   645
	os << "label\t";
deba@1409
   646
      }
deba@1409
   647
      for (int i = 0; i < (int)writers.size(); ++i) {
deba@1409
   648
	os << writers[i].first << '\t';
deba@1409
   649
      }
deba@1409
   650
      os << std::endl;
deba@1409
   651
      for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
deba@1901
   652
	nodeLabelWriter->write(os, graph.source(it));
deba@1409
   653
	os << '\t';
deba@1901
   654
	nodeLabelWriter->write(os, graph.target(it));
deba@1409
   655
	os << '\t';
deba@1901
   656
	if (forceLabelMap) {
deba@1409
   657
	  os << graph.id(it) << '\t';
deba@1409
   658
	}
deba@1409
   659
	for (int i = 0; i < (int)writers.size(); ++i) {
deba@1409
   660
	  writers[i].second->write(os, it);
deba@1409
   661
	  os << '\t';
deba@1409
   662
	}
deba@1409
   663
	os << std::endl;
deba@1409
   664
      }
deba@1409
   665
    }
deba@1409
   666
deba@1409
   667
  public:
deba@1409
   668
deba@1901
   669
    /// \brief Returns true if the edgeset can write the labels of the edges.
deba@1409
   670
    ///
deba@1901
   671
    /// Returns true if the edgeset can write the labels of the edges.
deba@1901
   672
    /// It is possible only if an "label" named map was written or the 
deba@1901
   673
    /// \c _forceLabelMap constructor parameter was true.
deba@1901
   674
    bool isLabelWriter() const {
deba@1901
   675
      return forceLabelMap || labelMap != 0;
deba@1409
   676
    }
deba@1409
   677
deba@1901
   678
    /// \brief Write the label of the given edge.
deba@1409
   679
    ///
deba@1901
   680
    /// It writes the label of the given edge. If there was written an "label"
deba@1409
   681
    /// named map then it will write the map value belongs to the edge.
deba@1901
   682
    /// Otherwise if the \c forceLabel parameter was true it will write
deba@1901
   683
    /// its label in the graph. 
deba@1901
   684
    void writeLabel(std::ostream& os, const Edge& item) const {
deba@1901
   685
      if (forceLabelMap) {
deba@1409
   686
	os << graph.id(item);
deba@1409
   687
      } else {
deba@1901
   688
	labelMap->write(os, item);
deba@1409
   689
      }
deba@1409
   690
    } 
deba@1409
   691
deba@1409
   692
  private:
deba@1409
   693
deba@1845
   694
    typedef std::vector<std::pair<std::string, _writer_bits::
deba@1845
   695
				  MapWriterBase<Edge>*> > MapWriters;
deba@1409
   696
    MapWriters writers;
deba@1409
   697
deba@1901
   698
    _writer_bits::MapWriterBase<Edge>* labelMap;
deba@1901
   699
    bool forceLabelMap;
deba@1409
   700
   
deba@1705
   701
    const Graph& graph;   
deba@1901
   702
    std::string name;
deba@1421
   703
deba@1901
   704
    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
deba@1421
   705
  };
deba@1421
   706
deba@1421
   707
  /// \ingroup io_group
deba@1421
   708
  /// \brief SectionWriter for writing a undirected edgeset.
deba@1421
   709
  ///
deba@1421
   710
  /// The lemon format can store multiple undirected edgesets with several 
deba@1421
   711
  /// maps. The undirected edgeset section's header line is \c \@undiredgeset 
deba@1901
   712
  /// \c undiredgeset_name, but the \c undiredgeset_name may be empty.
deba@1421
   713
  ///
deba@1421
   714
  /// The first line of the section contains the names of the maps separated
deba@1421
   715
  /// with white spaces. Each next lines describes an undirected edge in the 
deba@1901
   716
  /// edgeset. The line contains the two connected nodes' label and the mapped 
deba@1421
   717
  /// values for each undirected map.
deba@1421
   718
  ///
deba@1421
   719
  /// The section can handle the directed as a syntactical sugar. Two
deba@1421
   720
  /// undirected edge map describes one directed edge map. This two maps
deba@1421
   721
  /// are the forward map and the backward map and the names of this map
deba@1421
   722
  /// is near the same just with a prefix \c '+' or \c '-' character 
deba@1421
   723
  /// difference.
deba@1421
   724
  ///
deba@1901
   725
  /// If the edgeset contains an \c "label" named map then it will be regarded
deba@1901
   726
  /// as label map. This map should contain only unique values and when the 
deba@1901
   727
  /// \c writeLabel() member will be called with an undirected edge it will 
deba@1901
   728
  /// write it's label. Otherwise if the \c _forceLabelMap constructor 
deba@1901
   729
  /// parameter is true then the label map will be the id in the graph.
deba@1421
   730
  ///
deba@1901
   731
  /// The undirected edgeset writer needs a node label writer to identify 
deba@1421
   732
  /// which nodes have to be connected. If a NodeSetWriter can write the 
deba@1901
   733
  /// nodes' label, it will be able to use with this class.
deba@1421
   734
  ///
deba@1421
   735
  /// \relates LemonWriter
deba@1421
   736
  template <typename _Graph, typename _Traits = DefaultWriterTraits>
deba@1845
   737
  class UndirEdgeSetWriter : public LemonWriter::SectionWriter {
deba@1845
   738
    typedef LemonWriter::SectionWriter Parent;
deba@1421
   739
  public:
deba@1421
   740
deba@1421
   741
    typedef _Graph Graph;
deba@1421
   742
    typedef _Traits Traits;
deba@1429
   743
    typedef typename Graph::Node Node;
deba@1429
   744
    typedef typename Graph::Edge Edge;
deba@1429
   745
    typedef typename Graph::UndirEdge UndirEdge;
deba@1421
   746
deba@1421
   747
    /// \brief Constructor.
deba@1421
   748
    ///
deba@1421
   749
    /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
deba@1901
   750
    /// and attach it into the given LemonWriter. It will write node labels by
deba@1901
   751
    /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true 
deba@1901
   752
    /// then the writer will write own label map if the user does not give 
deba@1901
   753
    /// "label" named map.
deba@1901
   754
    template <typename NodeLabelWriter>
deba@1421
   755
    UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
deba@1901
   756
		       const NodeLabelWriter& _nodeLabelWriter, 
deba@1901
   757
		       const std::string& _name = std::string(),
deba@1901
   758
		       bool _forceLabelMap = true)
deba@1901
   759
      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
deba@1901
   760
	graph(_graph), name(_name) {
deba@1901
   761
      checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
deba@1901
   762
      nodeLabelWriter.reset(new _writer_bits::
deba@1901
   763
			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
deba@1476
   764
    } 
deba@1421
   765
deba@1421
   766
    /// \brief Destructor.
deba@1421
   767
    ///
deba@1421
   768
    /// Destructor for UndirEdgeSetWriter.
deba@1421
   769
    virtual ~UndirEdgeSetWriter() {
deba@1421
   770
      typename MapWriters::iterator it;
deba@1421
   771
      for (it = writers.begin(); it != writers.end(); ++it) {
deba@1421
   772
	delete it->second;
deba@1421
   773
      }
deba@1421
   774
    }
deba@1421
   775
deba@1421
   776
  private:
deba@1421
   777
    UndirEdgeSetWriter(const UndirEdgeSetWriter&);
deba@1421
   778
    void operator=(const UndirEdgeSetWriter&);
deba@1421
   779
deba@1421
   780
  public:
deba@1421
   781
deba@1421
   782
    /// \brief Add a new undirected edge map writer command for the writer.
deba@1421
   783
    ///
deba@1421
   784
    /// Add a new undirected map writer command for the writer.
deba@1421
   785
    template <typename Map>
deba@1421
   786
    UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
deba@1421
   787
      return writeUndirEdgeMap<typename Traits::
deba@1421
   788
	template Writer<typename Map::Value>, Map>(name, map);
deba@1421
   789
    }
deba@1421
   790
deba@1421
   791
    /// \brief Add a new undirected map writer command for the writer.
deba@1421
   792
    ///
deba@1421
   793
    /// Add a new undirected map writer command for the writer.
deba@1421
   794
    template <typename Writer, typename Map>
deba@1421
   795
    UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, 
deba@1421
   796
					  const Writer& writer = Writer()) {
deba@1492
   797
      checkConcept<concept::ReadMap<UndirEdge, typename Map::Value>, Map>();
deba@1492
   798
      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
deba@1421
   799
      writers.push_back(
deba@1845
   800
	make_pair(name, new _writer_bits::
deba@1845
   801
		  MapWriter<UndirEdge, Map, Writer>(map, writer)));
deba@1421
   802
      return *this;
deba@1421
   803
    }
deba@1421
   804
deba@1421
   805
    /// \brief Add a new directed edge map writer command for the writer.
deba@1421
   806
    ///
deba@1421
   807
    /// Add a new directed map writer command for the writer.
deba@1421
   808
    template <typename Map>
deba@1421
   809
    UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
deba@1492
   810
      return writeEdgeMap<typename Traits::
deba@1492
   811
	template Writer<typename Map::Value>, Map>(name, map);
deba@1421
   812
    }
deba@1421
   813
deba@1421
   814
    /// \brief Add a new directed map writer command for the writer.
deba@1421
   815
    ///
deba@1421
   816
    /// Add a new directed map writer command for the writer.
deba@1421
   817
    template <typename Writer, typename Map>
deba@1421
   818
    UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
deba@1421
   819
				     const Writer& writer = Writer()) {
deba@1492
   820
      checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
deba@1492
   821
      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
deba@1705
   822
      writeUndirEdge("+" + name, 
deba@1705
   823
		     _writer_bits::forwardComposeMap(graph, map), writer);
deba@1705
   824
      writeUndirEdge("-" + name, 
deba@1705
   825
		     _writer_bits::backwardComposeMap(graph, map), writer);
deba@1421
   826
      return *this;
deba@1421
   827
    }
deba@1421
   828
deba@1421
   829
  protected:
deba@1421
   830
deba@1421
   831
    /// \brief The header of the section.
deba@1421
   832
    ///
deba@1421
   833
    /// It gives back the header of the section.
deba@1421
   834
    virtual std::string header() {
deba@1901
   835
      return "@undiredgeset " + name;
deba@1421
   836
    }
deba@1421
   837
deba@1421
   838
    /// \brief  Writer function of the section.
deba@1421
   839
    ///
deba@1421
   840
    /// Write the content of the section.
deba@1421
   841
    virtual void write(std::ostream& os) {
deba@1901
   842
      if (!nodeLabelWriter->isLabelWriter()) {
deba@1901
   843
	throw DataFormatError("Cannot find nodeset or label map");
deba@1476
   844
      }
deba@1421
   845
      for (int i = 0; i < (int)writers.size(); ++i) {
deba@1901
   846
	if (writers[i].first == "label") {
deba@1901
   847
	  labelMap = writers[i].second;
deba@1901
   848
	  forceLabelMap = false;
deba@1421
   849
	  break;
deba@1421
   850
	}
deba@1421
   851
      }
deba@1421
   852
      os << "\t\t";
deba@1901
   853
      if (forceLabelMap) {
deba@1901
   854
	os << "label\t";
deba@1421
   855
      }
deba@1421
   856
      for (int i = 0; i < (int)writers.size(); ++i) {
deba@1421
   857
	os << writers[i].first << '\t';
deba@1421
   858
      }
deba@1421
   859
      os << std::endl;
deba@1421
   860
      for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
deba@1901
   861
	nodeLabelWriter->write(os, graph.source(it));
deba@1421
   862
	os << '\t';
deba@1901
   863
	nodeLabelWriter->write(os, graph.target(it));
deba@1421
   864
	os << '\t';
deba@1901
   865
	if (forceLabelMap) {
deba@1421
   866
	  os << graph.id(it) << '\t';
deba@1421
   867
	}
deba@1421
   868
	for (int i = 0; i < (int)writers.size(); ++i) {
deba@1421
   869
	  writers[i].second->write(os, it);
deba@1421
   870
	  os << '\t';
deba@1421
   871
	}
deba@1421
   872
	os << std::endl;
deba@1421
   873
      }
deba@1421
   874
    }
deba@1421
   875
deba@1421
   876
  public:
deba@1421
   877
deba@1901
   878
    /// \brief Returns true if the undirected edgeset can write the labels of 
deba@1421
   879
    /// the edges.
deba@1421
   880
    ///
deba@1901
   881
    /// Returns true if the undirected edgeset can write the labels of the 
deba@1901
   882
    /// undirected edges. It is possible only if an "label" named map was 
deba@1901
   883
    /// written or the \c _forceLabelMap constructor parameter was true.
deba@1901
   884
    bool isLabelWriter() const {
deba@1901
   885
      return forceLabelMap || labelMap != 0;
deba@1421
   886
    }
deba@1421
   887
deba@1901
   888
    /// \brief Write the label of the given undirected edge.
deba@1421
   889
    ///
deba@1901
   890
    /// It writes the label of the given undirected edge. If there was written 
deba@1901
   891
    /// an "label" named map then it will write the map value belongs to the 
deba@1901
   892
    /// undirected edge. Otherwise if the \c forceLabel parameter was true it 
deba@1421
   893
    /// will write its id in the graph. 
deba@1901
   894
    void writeLabel(std::ostream& os, const UndirEdge& item) const {
deba@1901
   895
      if (forceLabelMap) {
deba@1429
   896
	os << graph.id(item);
deba@1429
   897
      } else {
deba@1901
   898
	labelMap->write(os, item);
deba@1429
   899
      }
deba@1429
   900
    } 
deba@1429
   901
deba@1901
   902
    /// \brief Write the label of the given edge.
deba@1429
   903
    ///
deba@1901
   904
    /// It writes the label of the given edge. If there was written 
deba@1901
   905
    /// an "label" named map then it will write the map value belongs to the 
deba@1901
   906
    /// edge. Otherwise if the \c forceLabel parameter was true it 
deba@1429
   907
    /// will write its id in the graph. If the edge is forward map
deba@1429
   908
    /// then its prefix character is \c '+' elsewhere \c '-'.
deba@1901
   909
    void writeLabel(std::ostream& os, const Edge& item) const {
deba@1690
   910
      if (graph.direction(item)) {
deba@1429
   911
	os << "+ ";
deba@1429
   912
      } else {
deba@1429
   913
	os << "- ";
deba@1429
   914
      }
deba@1901
   915
      if (forceLabelMap) {
deba@1421
   916
	os << graph.id(item);
deba@1421
   917
      } else {
deba@1901
   918
	labelMap->write(os, item);
deba@1421
   919
      }
deba@1421
   920
    } 
deba@1421
   921
deba@1421
   922
  private:
deba@1421
   923
deba@1845
   924
    typedef std::vector<std::pair<std::string, _writer_bits::
deba@1845
   925
				  MapWriterBase<UndirEdge>*> > MapWriters;
deba@1421
   926
    MapWriters writers;
deba@1421
   927
deba@1901
   928
    _writer_bits::MapWriterBase<UndirEdge>* labelMap;
deba@1901
   929
    bool forceLabelMap;
deba@1421
   930
   
deba@1705
   931
    const Graph& graph;   
deba@1901
   932
    std::string name;
deba@1409
   933
deba@1901
   934
    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
deba@1409
   935
  };
deba@1409
   936
deba@1409
   937
  /// \ingroup io_group
deba@1901
   938
  /// \brief SectionWriter for writing named nodes.
deba@1409
   939
  ///
deba@1901
   940
  /// The nodes section's header line is \c \@nodes \c nodes_name, but the
deba@1901
   941
  /// \c nodes_name may be empty.
deba@1409
   942
  ///
deba@1901
   943
  /// Each line in the section contains the name of the node and 
deba@1901
   944
  /// then the node label. 
deba@1409
   945
  ///
deba@1409
   946
  /// \relates LemonWriter
deba@1409
   947
  template <typename _Graph>
deba@1845
   948
  class NodeWriter : public LemonWriter::SectionWriter {
deba@1845
   949
    typedef LemonWriter::SectionWriter Parent;
deba@1409
   950
    typedef _Graph Graph;
deba@1429
   951
    typedef typename Graph::Node Node;
deba@1409
   952
  public:
deba@1409
   953
    
deba@1409
   954
    /// \brief Constructor.
deba@1409
   955
    ///
deba@1409
   956
    /// Constructor for NodeWriter. It creates the NodeWriter and
deba@1901
   957
    /// attach it into the given LemonWriter. The given \c _LabelWriter
deba@1901
   958
    /// will write the nodes' label what can be a nodeset writer.
deba@1901
   959
    template <typename _LabelWriter>
deba@1901
   960
    NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
deba@1901
   961
	       const std::string& _name = std::string()) 
deba@1901
   962
      : Parent(_writer), name(_name) {
deba@1901
   963
      checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
deba@1901
   964
      labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
deba@1901
   965
                        (_labelWriter));
deba@1476
   966
    }
deba@1476
   967
deba@1409
   968
deba@1409
   969
    /// \brief Destructor.
deba@1409
   970
    ///
deba@1409
   971
    /// Destructor for NodeWriter.
deba@1409
   972
    virtual ~NodeWriter() {}
deba@1409
   973
deba@1409
   974
  private:
deba@1409
   975
    NodeWriter(const NodeWriter&);
deba@1409
   976
    void operator=(const NodeWriter&);
deba@1409
   977
deba@1409
   978
  public:
deba@1409
   979
deba@1409
   980
    /// \brief Add a node writer command for the NodeWriter.
deba@1409
   981
    ///
deba@1409
   982
    /// Add a node writer command for the NodeWriter.
deba@1429
   983
    void writeNode(const std::string& name, const Node& item) {
deba@1409
   984
      writers.push_back(make_pair(name, &item));
deba@1409
   985
    }
deba@1409
   986
deba@1409
   987
  protected:
deba@1409
   988
deba@1901
   989
    /// \brief The header of the section.
deba@1409
   990
    ///
deba@1901
   991
    /// It gives back the header of the section.
deba@1409
   992
    virtual std::string header() {
deba@1901
   993
      return "@nodes " + name;
deba@1409
   994
    }
deba@1409
   995
deba@1409
   996
    /// \brief  Writer function of the section.
deba@1409
   997
    ///
deba@1409
   998
    /// Write the content of the section.
deba@1409
   999
    virtual void write(std::ostream& os) {
deba@1901
  1000
      if (!labelWriter->isLabelWriter()) {
deba@1901
  1001
	throw DataFormatError("Cannot find nodeset or label map");
deba@1476
  1002
      }
deba@1409
  1003
      for (int i = 0; i < (int)writers.size(); ++i) {
deba@1409
  1004
	os << writers[i].first << ' ';
deba@1901
  1005
	labelWriter->write(os, *(writers[i].second));
deba@1409
  1006
	os << std::endl;
deba@1409
  1007
      }
deba@1409
  1008
    }
deba@1409
  1009
    
deba@1409
  1010
  private:
deba@1409
  1011
deba@1901
  1012
    std::string name;
deba@1409
  1013
deba@1429
  1014
    typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
deba@1429
  1015
    NodeWriters writers;
deba@1901
  1016
    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
deba@1409
  1017
  };
deba@1409
  1018
deba@1409
  1019
  /// \ingroup io_group
deba@1901
  1020
  /// \brief SectionWriter for writing named edges.
deba@1409
  1021
  ///
deba@1901
  1022
  /// The edges section's header line is \c \@edges \c edges_name, but the
deba@1901
  1023
  /// \c edges_name may be empty.
deba@1409
  1024
  ///
deba@1901
  1025
  /// Each line in the section contains the name of the edge and 
deba@1901
  1026
  /// then the edge label. 
deba@1409
  1027
  ///
deba@1409
  1028
  /// \relates LemonWriter
deba@1409
  1029
  template <typename _Graph>
deba@1845
  1030
  class EdgeWriter : public LemonWriter::SectionWriter {
deba@1845
  1031
    typedef LemonWriter::SectionWriter Parent;
deba@1409
  1032
    typedef _Graph Graph;
deba@1429
  1033
    typedef typename Graph::Edge Edge;
deba@1409
  1034
  public:
deba@1409
  1035
    
deba@1409
  1036
    /// \brief Constructor.
deba@1409
  1037
    ///
deba@1409
  1038
    /// Constructor for EdgeWriter. It creates the EdgeWriter and
deba@1901
  1039
    /// attach it into the given LemonWriter. The given \c _LabelWriter
deba@1901
  1040
    /// will write the edges' label what can be a edgeset writer.
deba@1901
  1041
    template <typename _LabelWriter>
deba@1901
  1042
    EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
deba@1901
  1043
	       const std::string& _name = std::string()) 
deba@1901
  1044
      : Parent(_writer), name(_name) {
deba@1901
  1045
      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
deba@1901
  1046
      labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
deba@1476
  1047
    }
deba@1409
  1048
deba@1409
  1049
    /// \brief Destructor.
deba@1409
  1050
    ///
deba@1409
  1051
    /// Destructor for EdgeWriter.
deba@1409
  1052
    virtual ~EdgeWriter() {}
deba@1409
  1053
  private:
deba@1409
  1054
    EdgeWriter(const EdgeWriter&);
deba@1409
  1055
    void operator=(const EdgeWriter&);
deba@1409
  1056
deba@1409
  1057
  public:
deba@1409
  1058
deba@1421
  1059
    /// \brief Add an edge writer command for the EdgeWriter.
deba@1409
  1060
    ///
deba@1421
  1061
    /// Add an edge writer command for the EdgeWriter.
deba@1429
  1062
    void writeEdge(const std::string& name, const Edge& item) {
deba@1409
  1063
      writers.push_back(make_pair(name, &item));
deba@1409
  1064
    }
deba@1409
  1065
deba@1409
  1066
  protected:
deba@1409
  1067
deba@1901
  1068
    /// \brief The header of the section.
deba@1409
  1069
    ///
deba@1901
  1070
    /// It gives back the header of the section.
deba@1421
  1071
    virtual std::string header() {
deba@1901
  1072
      return "@edges " + name;
deba@1421
  1073
    }
deba@1421
  1074
deba@1421
  1075
    /// \brief  Writer function of the section.
deba@1421
  1076
    ///
deba@1421
  1077
    /// Write the content of the section.
deba@1421
  1078
    virtual void write(std::ostream& os) {
deba@1901
  1079
      if (!labelWriter->isLabelWriter()) {
deba@1901
  1080
	throw DataFormatError("Cannot find edgeset or label map");
deba@1476
  1081
      }
deba@1421
  1082
      for (int i = 0; i < (int)writers.size(); ++i) {
deba@1421
  1083
	os << writers[i].first << ' ';
deba@1901
  1084
	labelWriter->write(os, *(writers[i].second));
deba@1421
  1085
	os << std::endl;
deba@1421
  1086
      }
deba@1421
  1087
    }
deba@1421
  1088
    
deba@1421
  1089
  private:
deba@1421
  1090
deba@1901
  1091
    std::string name;
deba@1421
  1092
deba@1429
  1093
    typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
deba@1429
  1094
    EdgeWriters writers;
deba@1421
  1095
deba@1901
  1096
    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
deba@1421
  1097
  };
deba@1421
  1098
deba@1421
  1099
  /// \ingroup io_group
deba@1901
  1100
  /// \brief SectionWriter for writing named undirected edges.
deba@1421
  1101
  ///
deba@1421
  1102
  /// The undirected edges section's header line is \c \@undiredges 
deba@1901
  1103
  /// \c undiredges_name, but the \c undiredges_name may be empty.
deba@1421
  1104
  ///
deba@1901
  1105
  /// Each line in the section contains the name of the undirected edge and 
deba@1901
  1106
  /// then the undirected edge label. 
deba@1421
  1107
  ///
deba@1421
  1108
  /// \relates LemonWriter
deba@1421
  1109
  template <typename _Graph>
deba@1845
  1110
  class UndirEdgeWriter : public LemonWriter::SectionWriter {
deba@1845
  1111
    typedef LemonWriter::SectionWriter Parent;
deba@1421
  1112
    typedef _Graph Graph;
deba@1429
  1113
    typedef typename Graph::Node Node;
deba@1429
  1114
    typedef typename Graph::Edge Edge;
deba@1429
  1115
    typedef typename Graph::UndirEdge UndirEdge;
deba@1421
  1116
  public:
deba@1421
  1117
    
deba@1421
  1118
    /// \brief Constructor.
deba@1421
  1119
    ///
deba@1421
  1120
    /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
deba@1901
  1121
    /// attach it into the given LemonWriter. The given \c _LabelWriter
deba@1901
  1122
    /// will write the undirected edges' label what can be an undirected 
deba@1421
  1123
    /// edgeset writer.
deba@1901
  1124
    template <typename _LabelWriter>
deba@1901
  1125
    UndirEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, 
deba@1901
  1126
	       const std::string& _name = std::string()) 
deba@1901
  1127
      : Parent(_writer), name(_name) {
deba@1901
  1128
      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
deba@1901
  1129
      checkConcept<_writer_bits::ItemLabelWriter<UndirEdge>, _LabelWriter>();
deba@1901
  1130
      undirEdgeLabelWriter.reset(new _writer_bits::
deba@1901
  1131
			      LabelWriter<UndirEdge, _LabelWriter>(_labelWriter));
deba@1901
  1132
      edgeLabelWriter.reset(new _writer_bits::
deba@1901
  1133
			 LabelWriter<Edge, _LabelWriter>(_labelWriter));
deba@1476
  1134
    }
deba@1421
  1135
deba@1421
  1136
    /// \brief Destructor.
deba@1421
  1137
    ///
deba@1421
  1138
    /// Destructor for UndirEdgeWriter.
deba@1421
  1139
    virtual ~UndirEdgeWriter() {}
deba@1421
  1140
  private:
deba@1421
  1141
    UndirEdgeWriter(const UndirEdgeWriter&);
deba@1421
  1142
    void operator=(const UndirEdgeWriter&);
deba@1421
  1143
deba@1421
  1144
  public:
deba@1421
  1145
deba@1429
  1146
    /// \brief Add an edge writer command for the UndirEdgeWriter.
deba@1429
  1147
    ///
deba@1429
  1148
    /// Add an edge writer command for the UndirEdgeWriter.
deba@1429
  1149
    void writeEdge(const std::string& name, const Edge& item) {
deba@1429
  1150
      edgeWriters.push_back(make_pair(name, &item));
deba@1429
  1151
    }
deba@1429
  1152
deba@1421
  1153
    /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
deba@1421
  1154
    ///
deba@1429
  1155
    /// Add an undirected edge writer command for the UndirEdgeWriter.
deba@1429
  1156
    void writeUndirEdge(const std::string& name, const UndirEdge& item) {
deba@1429
  1157
      undirEdgeWriters.push_back(make_pair(name, &item));
deba@1421
  1158
    }
deba@1421
  1159
deba@1421
  1160
  protected:
deba@1421
  1161
deba@1901
  1162
    /// \brief The header of the section.
deba@1421
  1163
    ///
deba@1901
  1164
    /// It gives back the header of the section.
deba@1409
  1165
    virtual std::string header() {
deba@1901
  1166
      return "@undiredges " + name;
deba@1409
  1167
    }
deba@1409
  1168
deba@1409
  1169
    /// \brief  Writer function of the section.
deba@1409
  1170
    ///
deba@1409
  1171
    /// Write the content of the section.
deba@1409
  1172
    virtual void write(std::ostream& os) {
deba@1901
  1173
      if (!edgeLabelWriter->isLabelWriter()) {
deba@1901
  1174
	throw DataFormatError("Cannot find undirected edgeset or label map");
deba@1476
  1175
      }
deba@1901
  1176
      if (!undirEdgeLabelWriter->isLabelWriter()) {
deba@1901
  1177
	throw DataFormatError("Cannot find undirected edgeset or label map");
deba@1476
  1178
      }
deba@1429
  1179
      for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
deba@1429
  1180
	os << undirEdgeWriters[i].first << ' ';
deba@1901
  1181
	undirEdgeLabelWriter->write(os, *(undirEdgeWriters[i].second));
deba@1429
  1182
	os << std::endl;
deba@1429
  1183
      }
deba@1429
  1184
      for (int i = 0; i < (int)edgeWriters.size(); ++i) {
deba@1429
  1185
	os << edgeWriters[i].first << ' ';
deba@1901
  1186
	edgeLabelWriter->write(os, *(edgeWriters[i].second));
deba@1409
  1187
	os << std::endl;
deba@1409
  1188
      }
deba@1409
  1189
    }
deba@1409
  1190
    
deba@1409
  1191
  private:
deba@1409
  1192
deba@1901
  1193
    std::string name;
deba@1409
  1194
deba@1429
  1195
    typedef std::vector<std::pair<std::string, 
deba@1429
  1196
				  const UndirEdge*> > UndirEdgeWriters;
deba@1429
  1197
    UndirEdgeWriters undirEdgeWriters;
deba@1901
  1198
    std::auto_ptr<_writer_bits::LabelWriterBase<UndirEdge> > undirEdgeLabelWriter;
deba@1409
  1199
deba@1429
  1200
    typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
deba@1429
  1201
    EdgeWriters edgeWriters;
deba@1901
  1202
    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
deba@1429
  1203
deba@1409
  1204
  };
deba@1409
  1205
deba@1409
  1206
  /// \ingroup io_group
deba@1409
  1207
  /// \brief SectionWriter for attributes.
deba@1409
  1208
  ///
deba@1409
  1209
  /// The lemon format can store multiple attribute set. Each set has
deba@1901
  1210
  /// the header line \c \@attributes \c attributes_name, but the 
deba@1901
  1211
  /// attributeset_name may be empty.
deba@1409
  1212
  ///
deba@1409
  1213
  /// The attributeset section contains several lines. Each of them starts
deba@1409
  1214
  /// with the name of attribute and then the value.
deba@1409
  1215
  ///
deba@1409
  1216
  /// \relates LemonWriter
deba@1409
  1217
  template <typename _Traits = DefaultWriterTraits>
deba@1845
  1218
  class AttributeWriter : public LemonWriter::SectionWriter {
deba@1845
  1219
    typedef LemonWriter::SectionWriter Parent;
deba@1409
  1220
    typedef _Traits Traits; 
deba@1409
  1221
  public:
deba@1409
  1222
    /// \brief Constructor.
deba@1409
  1223
    ///
deba@1409
  1224
    /// Constructor for AttributeWriter. It creates the AttributeWriter and
deba@1409
  1225
    /// attach it into the given LemonWriter.
deba@1409
  1226
    AttributeWriter(LemonWriter& _writer, 
deba@1901
  1227
		    const std::string& _name = std::string()) 
deba@1901
  1228
      : Parent(_writer), name(_name) {}
deba@1409
  1229
deba@1409
  1230
    /// \brief Destructor.
deba@1409
  1231
    ///
deba@1409
  1232
    /// Destructor for AttributeWriter.
deba@1409
  1233
    virtual ~AttributeWriter() {
deba@1409
  1234
      typename Writers::iterator it;
deba@1409
  1235
      for (it = writers.begin(); it != writers.end(); ++it) {
deba@1409
  1236
	delete it->second;
deba@1409
  1237
      }
deba@1409
  1238
    }
deba@1409
  1239
deba@1409
  1240
  private:
deba@1409
  1241
    AttributeWriter(const AttributeWriter&);
deba@1409
  1242
    void operator=(AttributeWriter&);
deba@1409
  1243
deba@1409
  1244
  public:
deba@1409
  1245
    /// \brief Add an attribute writer command for the writer.
deba@1409
  1246
    ///
deba@1409
  1247
    /// Add an attribute writer command for the writer.
deba@1409
  1248
    template <typename Value>
deba@1901
  1249
    AttributeWriter& writeAttribute(const std::string& name, 
deba@1409
  1250
				    const Value& value) {
deba@1409
  1251
      return 
deba@1901
  1252
	writeAttribute<typename Traits::template Writer<Value> >(name, value);
deba@1409
  1253
    }
deba@1409
  1254
deba@1409
  1255
    /// \brief Add an attribute writer command for the writer.
deba@1409
  1256
    ///
deba@1409
  1257
    /// Add an attribute writer command for the writer.
deba@1409
  1258
    template <typename Writer, typename Value>
deba@1409
  1259
    AttributeWriter& writeAttribute(const std::string& name, 
deba@1409
  1260
				    const Value& value,
deba@1409
  1261
				    const Writer& writer = Writer()) {
deba@1492
  1262
      checkConcept<_writer_bits::ItemWriter<Value>, Writer>();
deba@1845
  1263
      writers.push_back(make_pair(name, new _writer_bits::
deba@1845
  1264
				  ValueWriter<Value, Writer>(value, writer)));
deba@1409
  1265
      return *this;
deba@1409
  1266
    }
deba@1409
  1267
deba@1409
  1268
  protected:
deba@1409
  1269
deba@1409
  1270
    /// \brief The header of section.
deba@1409
  1271
    ///
deba@1409
  1272
    /// It gives back the header of the section.
deba@1409
  1273
    std::string header() {
deba@1901
  1274
      return "@attributes " + name;
deba@1409
  1275
    }
deba@1409
  1276
deba@1409
  1277
    /// \brief  Writer function of the section.
deba@1409
  1278
    ///
deba@1409
  1279
    /// Write the content of the section.
deba@1409
  1280
    void write(std::ostream& os) {
deba@1409
  1281
      typename Writers::iterator it;
deba@1409
  1282
      for (it = writers.begin(); it != writers.end(); ++it) {
deba@1409
  1283
	os << it->first << ' ';
deba@1409
  1284
	it->second->write(os);
deba@1409
  1285
	os << std::endl;
deba@1409
  1286
      }
deba@1409
  1287
    }    
deba@1409
  1288
deba@1409
  1289
  private:
deba@1901
  1290
    std::string name;
deba@1409
  1291
deba@1845
  1292
    typedef std::vector<std::pair<std::string, 
deba@1845
  1293
				  _writer_bits::ValueWriterBase*> > Writers;
deba@1409
  1294
    Writers writers;  
deba@1409
  1295
  };
deba@1409
  1296
deba@1409
  1297
deba@1409
  1298
}
deba@1409
  1299
#endif