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