lemon/lgf_writer.h
changeset 209 765619b7cbb2
parent 201 9757e3d9bfeb
child 212 1ae84dea7d09
equal deleted inserted replaced
11:bda14aa11159 12:e5c488f9c398
     1 /* -*- C++ -*-
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     4  *
     5  * Copyright (C) 2003-2008
     5  * Copyright (C) 2003-2008
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     8  *
    41   namespace _writer_bits {
    41   namespace _writer_bits {
    42 
    42 
    43     template <typename Value>
    43     template <typename Value>
    44     struct DefaultConverter {
    44     struct DefaultConverter {
    45       std::string operator()(const Value& value) {
    45       std::string operator()(const Value& value) {
    46 	std::ostringstream os;
    46         std::ostringstream os;
    47 	os << value;
    47         os << value;
    48 	return os.str();
    48         return os.str();
    49       }
    49       }
    50     };
    50     };
    51 
    51 
    52     template <typename T>
    52     template <typename T>
    53     bool operator<(const T&, const T&) {
    53     bool operator<(const T&, const T&) {
    60       typedef _Map Map;
    60       typedef _Map Map;
    61       typedef typename Map::Key Item;
    61       typedef typename Map::Key Item;
    62 
    62 
    63     private:
    63     private:
    64       const Map& _map;
    64       const Map& _map;
    65       
    65 
    66     public:
    66     public:
    67       MapLess(const Map& map) : _map(map) {}
    67       MapLess(const Map& map) : _map(map) {}
    68 
    68 
    69       bool operator()(const Item& left, const Item& right) {
    69       bool operator()(const Item& left, const Item& right) {
    70 	return _map[left] < _map[right];
    70         return _map[left] < _map[right];
    71       }
    71       }
    72     };
    72     };
    73 
    73 
    74     template <typename _Graph, bool _dir, typename _Map>
    74     template <typename _Graph, bool _dir, typename _Map>
    75     class GraphArcMapLess {
    75     class GraphArcMapLess {
    79       typedef typename Graph::Edge Item;
    79       typedef typename Graph::Edge Item;
    80 
    80 
    81     private:
    81     private:
    82       const Graph& _graph;
    82       const Graph& _graph;
    83       const Map& _map;
    83       const Map& _map;
    84       
    84 
    85     public:
    85     public:
    86       GraphArcMapLess(const Graph& graph, const Map& map) 
    86       GraphArcMapLess(const Graph& graph, const Map& map)
    87 	: _graph(graph), _map(map) {}
    87         : _graph(graph), _map(map) {}
    88 
    88 
    89       bool operator()(const Item& left, const Item& right) {
    89       bool operator()(const Item& left, const Item& right) {
    90 	return _map[_graph.direct(left, _dir)] < 
    90         return _map[_graph.direct(left, _dir)] <
    91 	  _map[_graph.direct(right, _dir)];
    91           _map[_graph.direct(right, _dir)];
    92       }
    92       }
    93     };
    93     };
    94 
    94 
    95     template <typename _Item>    
    95     template <typename _Item>
    96     class MapStorageBase {
    96     class MapStorageBase {
    97     public:
    97     public:
    98       typedef _Item Item;
    98       typedef _Item Item;
    99 
    99 
   100     public:
   100     public:
   103 
   103 
   104       virtual std::string get(const Item& item) = 0;
   104       virtual std::string get(const Item& item) = 0;
   105       virtual void sort(std::vector<Item>&) = 0;
   105       virtual void sort(std::vector<Item>&) = 0;
   106     };
   106     };
   107 
   107 
   108     template <typename _Item, typename _Map, 
   108     template <typename _Item, typename _Map,
   109 	      typename _Converter = DefaultConverter<typename _Map::Value> >
   109               typename _Converter = DefaultConverter<typename _Map::Value> >
   110     class MapStorage : public MapStorageBase<_Item> {
   110     class MapStorage : public MapStorageBase<_Item> {
   111     public:
   111     public:
   112       typedef _Map Map;
   112       typedef _Map Map;
   113       typedef _Converter Converter;
   113       typedef _Converter Converter;
   114       typedef _Item Item;
   114       typedef _Item Item;
   115       
   115 
   116     private:
   116     private:
   117       const Map& _map;
   117       const Map& _map;
   118       Converter _converter;
   118       Converter _converter;
   119 
   119 
   120     public:
   120     public:
   121       MapStorage(const Map& map, const Converter& converter = Converter()) 
   121       MapStorage(const Map& map, const Converter& converter = Converter())
   122 	: _map(map), _converter(converter) {}
   122         : _map(map), _converter(converter) {}
   123       virtual ~MapStorage() {}
   123       virtual ~MapStorage() {}
   124 
   124 
   125       virtual std::string get(const Item& item) {
   125       virtual std::string get(const Item& item) {
   126 	return _converter(_map[item]);
   126         return _converter(_map[item]);
   127       }
   127       }
   128       virtual void sort(std::vector<Item>& items) {
   128       virtual void sort(std::vector<Item>& items) {
   129 	MapLess<Map> less(_map);
   129         MapLess<Map> less(_map);
   130 	std::sort(items.begin(), items.end(), less);
   130         std::sort(items.begin(), items.end(), less);
   131       }
   131       }
   132     };
   132     };
   133 
   133 
   134     template <typename _Graph, bool _dir, typename _Map, 
   134     template <typename _Graph, bool _dir, typename _Map,
   135 	      typename _Converter = DefaultConverter<typename _Map::Value> >
   135               typename _Converter = DefaultConverter<typename _Map::Value> >
   136     class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
   136     class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
   137     public:
   137     public:
   138       typedef _Map Map;
   138       typedef _Map Map;
   139       typedef _Converter Converter;
   139       typedef _Converter Converter;
   140       typedef _Graph Graph;
   140       typedef _Graph Graph;
   141       typedef typename Graph::Edge Item;
   141       typedef typename Graph::Edge Item;
   142       static const bool dir = _dir;
   142       static const bool dir = _dir;
   143       
   143 
   144     private:
   144     private:
   145       const Graph& _graph;
   145       const Graph& _graph;
   146       const Map& _map;
   146       const Map& _map;
   147       Converter _converter;
   147       Converter _converter;
   148 
   148 
   149     public:
   149     public:
   150       GraphArcMapStorage(const Graph& graph, const Map& map,  
   150       GraphArcMapStorage(const Graph& graph, const Map& map,
   151 			 const Converter& converter = Converter()) 
   151                          const Converter& converter = Converter())
   152 	: _graph(graph), _map(map), _converter(converter) {}
   152         : _graph(graph), _map(map), _converter(converter) {}
   153       virtual ~GraphArcMapStorage() {}
   153       virtual ~GraphArcMapStorage() {}
   154 
   154 
   155       virtual std::string get(const Item& item) {
   155       virtual std::string get(const Item& item) {
   156 	return _converter(_map[_graph.direct(item, dir)]);
   156         return _converter(_map[_graph.direct(item, dir)]);
   157       }
   157       }
   158       virtual void sort(std::vector<Item>& items) {
   158       virtual void sort(std::vector<Item>& items) {
   159 	GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
   159         GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
   160 	std::sort(items.begin(), items.end(), less);
   160         std::sort(items.begin(), items.end(), less);
   161       }
   161       }
   162     };
   162     };
   163 
   163 
   164     class ValueStorageBase {
   164     class ValueStorageBase {
   165     public:
   165     public:
   166       ValueStorageBase() {}
   166       ValueStorageBase() {}
   167       virtual ~ValueStorageBase() {}
   167       virtual ~ValueStorageBase() {}
   168 
   168 
   169       virtual std::string get() = 0;      
   169       virtual std::string get() = 0;
   170     };
   170     };
   171 
   171 
   172     template <typename _Value, typename _Converter = DefaultConverter<_Value> >
   172     template <typename _Value, typename _Converter = DefaultConverter<_Value> >
   173     class ValueStorage : public ValueStorageBase {
   173     class ValueStorage : public ValueStorageBase {
   174     public:
   174     public:
   179       const Value& _value;
   179       const Value& _value;
   180       Converter _converter;
   180       Converter _converter;
   181 
   181 
   182     public:
   182     public:
   183       ValueStorage(const Value& value, const Converter& converter = Converter())
   183       ValueStorage(const Value& value, const Converter& converter = Converter())
   184  	: _value(value), _converter(converter) {}
   184          : _value(value), _converter(converter) {}
   185 
   185 
   186       virtual std::string get() {
   186       virtual std::string get() {
   187 	return _converter(_value);
   187         return _converter(_value);
   188       }
   188       }
   189     };
   189     };
   190 
   190 
   191     template <typename Value>
   191     template <typename Value>
   192     struct MapLookUpConverter {
   192     struct MapLookUpConverter {
   193       const std::map<Value, std::string>& _map;
   193       const std::map<Value, std::string>& _map;
   194       
   194 
   195       MapLookUpConverter(const std::map<Value, std::string>& map) 
   195       MapLookUpConverter(const std::map<Value, std::string>& map)
   196 	: _map(map) {}
   196         : _map(map) {}
   197       
   197 
   198       std::string operator()(const Value& str) {
   198       std::string operator()(const Value& str) {
   199 	typename std::map<Value, std::string>::const_iterator it = 
   199         typename std::map<Value, std::string>::const_iterator it =
   200 	  _map.find(str);
   200           _map.find(str);
   201 	if (it == _map.end()) {
   201         if (it == _map.end()) {
   202 	  throw DataFormatError("Item not found");
   202           throw DataFormatError("Item not found");
   203 	}
   203         }
   204 	return it->second;
   204         return it->second;
   205       }
   205       }
   206     };
   206     };
   207 
   207 
   208     template <typename Graph>
   208     template <typename Graph>
   209     struct GraphArcLookUpConverter {
   209     struct GraphArcLookUpConverter {
   210       const Graph& _graph;
   210       const Graph& _graph;
   211       const std::map<typename Graph::Edge, std::string>& _map;
   211       const std::map<typename Graph::Edge, std::string>& _map;
   212       
   212 
   213       GraphArcLookUpConverter(const Graph& graph, 
   213       GraphArcLookUpConverter(const Graph& graph,
   214 			      const std::map<typename Graph::Edge, 
   214                               const std::map<typename Graph::Edge,
   215 			                     std::string>& map) 
   215                                              std::string>& map)
   216 	: _graph(graph), _map(map) {}
   216         : _graph(graph), _map(map) {}
   217       
   217 
   218       std::string operator()(const typename Graph::Arc& val) {
   218       std::string operator()(const typename Graph::Arc& val) {
   219 	typename std::map<typename Graph::Edge, std::string>
   219         typename std::map<typename Graph::Edge, std::string>
   220 	  ::const_iterator it = _map.find(val);
   220           ::const_iterator it = _map.find(val);
   221 	if (it == _map.end()) {
   221         if (it == _map.end()) {
   222 	  throw DataFormatError("Item not found");
   222           throw DataFormatError("Item not found");
   223 	}
   223         }
   224 	return (_graph.direction(val) ? '+' : '-') + it->second;
   224         return (_graph.direction(val) ? '+' : '-') + it->second;
   225       }
   225       }
   226     };
   226     };
   227 
   227 
   228     inline bool isWhiteSpace(char c) {
   228     inline bool isWhiteSpace(char c) {
   229       return c == ' ' || c == '\t' || c == '\v' || 
   229       return c == ' ' || c == '\t' || c == '\v' ||
   230         c == '\n' || c == '\r' || c == '\f'; 
   230         c == '\n' || c == '\r' || c == '\f';
   231     }
   231     }
   232 
   232 
   233     inline bool isEscaped(char c) {
   233     inline bool isEscaped(char c) {
   234       return c == '\\' || c == '\"' || c == '\'' || 
   234       return c == '\\' || c == '\"' || c == '\'' ||
   235 	c == '\a' || c == '\b';
   235         c == '\a' || c == '\b';
   236     }
   236     }
   237 
   237 
   238     inline static void writeEscape(std::ostream& os, char c) {
   238     inline static void writeEscape(std::ostream& os, char c) {
   239       switch (c) {
   239       switch (c) {
   240       case '\\':
   240       case '\\':
   241 	os << "\\\\";
   241         os << "\\\\";
   242 	return;
   242         return;
   243       case '\"':
   243       case '\"':
   244 	os << "\\\"";
   244         os << "\\\"";
   245 	return;
   245         return;
   246       case '\a':
   246       case '\a':
   247 	os << "\\a";
   247         os << "\\a";
   248 	return;
   248         return;
   249       case '\b':
   249       case '\b':
   250 	os << "\\b";
   250         os << "\\b";
   251 	return;
   251         return;
   252       case '\f':
   252       case '\f':
   253 	os << "\\f";
   253         os << "\\f";
   254 	return;
   254         return;
   255       case '\r':
   255       case '\r':
   256 	os << "\\r";
   256         os << "\\r";
   257 	return;
   257         return;
   258       case '\n':
   258       case '\n':
   259 	os << "\\n";
   259         os << "\\n";
   260 	return;
   260         return;
   261       case '\t':
   261       case '\t':
   262 	os << "\\t";
   262         os << "\\t";
   263 	return;
   263         return;
   264       case '\v':
   264       case '\v':
   265 	os << "\\v";
   265         os << "\\v";
   266 	return;
   266         return;
   267       default:
   267       default:
   268 	if (c < 0x20) {
   268         if (c < 0x20) {
   269 	  std::ios::fmtflags flags = os.flags();
   269           std::ios::fmtflags flags = os.flags();
   270 	  os << '\\' << std::oct << static_cast<int>(c);
   270           os << '\\' << std::oct << static_cast<int>(c);
   271 	  os.flags(flags);
   271           os.flags(flags);
   272 	} else {
   272         } else {
   273 	  os << c;
   273           os << c;
   274 	}
   274         }
   275 	return;
   275         return;
   276       }     
   276       }
   277     }
   277     }
   278 
   278 
   279     inline bool requireEscape(const std::string& str) {
   279     inline bool requireEscape(const std::string& str) {
   280       if (str.empty() || str[0] == '@') return true;
   280       if (str.empty() || str[0] == '@') return true;
   281       std::istringstream is(str);
   281       std::istringstream is(str);
   282       char c;
   282       char c;
   283       while (is.get(c)) {
   283       while (is.get(c)) {
   284 	if (isWhiteSpace(c) || isEscaped(c)) {
   284         if (isWhiteSpace(c) || isEscaped(c)) {
   285 	  return true;
   285           return true;
   286 	}
   286         }
   287       }
   287       }
   288       return false;
   288       return false;
   289     }
   289     }
   290     
   290 
   291     inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
   291     inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
   292 
   292 
   293       if (requireEscape(str)) {
   293       if (requireEscape(str)) {
   294 	os << '\"';
   294         os << '\"';
   295 	for (std::string::const_iterator it = str.begin(); 
   295         for (std::string::const_iterator it = str.begin();
   296 	     it != str.end(); ++it) {
   296              it != str.end(); ++it) {
   297 	  writeEscape(os, *it);
   297           writeEscape(os, *it);
   298 	}	
   298         }
   299 	os << '\"';
   299         os << '\"';
   300       } else {
   300       } else {
   301 	os << str;
   301         os << str;
   302       }
   302       }
   303       return os;
   303       return os;
   304     }
   304     }
   305 
   305 
   306   }
   306   }
   307 
   307 
   308   template <typename Digraph>
   308   template <typename Digraph>
   309   class DigraphWriter;
   309   class DigraphWriter;
   310 
   310 
   311   template <typename Digraph>
   311   template <typename Digraph>
   312   DigraphWriter<Digraph> digraphWriter(std::ostream& os, 
   312   DigraphWriter<Digraph> digraphWriter(std::ostream& os,
   313 				       const Digraph& digraph);
   313                                        const Digraph& digraph);
   314 
   314 
   315   template <typename Digraph>
   315   template <typename Digraph>
   316   DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
   316   DigraphWriter<Digraph> digraphWriter(const std::string& fn,
   317 				       const Digraph& digraph);
   317                                        const Digraph& digraph);
   318 
   318 
   319   template <typename Digraph>
   319   template <typename Digraph>
   320   DigraphWriter<Digraph> digraphWriter(const char *fn, 
   320   DigraphWriter<Digraph> digraphWriter(const char *fn,
   321 				       const Digraph& digraph);
   321                                        const Digraph& digraph);
   322   
   322 
   323   /// \ingroup lemon_io
   323   /// \ingroup lemon_io
   324   ///  
   324   ///
   325   /// \brief \ref lgf-format "LGF" writer for directed graphs
   325   /// \brief \ref lgf-format "LGF" writer for directed graphs
   326   ///
   326   ///
   327   /// This utility writes an \ref lgf-format "LGF" file.
   327   /// This utility writes an \ref lgf-format "LGF" file.
   328   ///
   328   ///
   329   /// The writing method does a batch processing. The user creates a
   329   /// The writing method does a batch processing. The user creates a
   368   class DigraphWriter {
   368   class DigraphWriter {
   369   public:
   369   public:
   370 
   370 
   371     typedef _Digraph Digraph;
   371     typedef _Digraph Digraph;
   372     TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   372     TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   373     
   373 
   374   private:
   374   private:
   375 
   375 
   376 
   376 
   377     std::ostream* _os;
   377     std::ostream* _os;
   378     bool local_os;
   378     bool local_os;
   380     const Digraph& _digraph;
   380     const Digraph& _digraph;
   381 
   381 
   382     std::string _nodes_caption;
   382     std::string _nodes_caption;
   383     std::string _arcs_caption;
   383     std::string _arcs_caption;
   384     std::string _attributes_caption;
   384     std::string _attributes_caption;
   385     
   385 
   386     typedef std::map<Node, std::string> NodeIndex;
   386     typedef std::map<Node, std::string> NodeIndex;
   387     NodeIndex _node_index;
   387     NodeIndex _node_index;
   388     typedef std::map<Arc, std::string> ArcIndex;
   388     typedef std::map<Arc, std::string> ArcIndex;
   389     ArcIndex _arc_index;
   389     ArcIndex _arc_index;
   390 
   390 
   391     typedef std::vector<std::pair<std::string, 
   391     typedef std::vector<std::pair<std::string,
   392       _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
   392       _writer_bits::MapStorageBase<Node>* > > NodeMaps;
   393     NodeMaps _node_maps; 
   393     NodeMaps _node_maps;
   394 
   394 
   395     typedef std::vector<std::pair<std::string, 
   395     typedef std::vector<std::pair<std::string,
   396       _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
   396       _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
   397     ArcMaps _arc_maps;
   397     ArcMaps _arc_maps;
   398 
   398 
   399     typedef std::vector<std::pair<std::string, 
   399     typedef std::vector<std::pair<std::string,
   400       _writer_bits::ValueStorageBase*> > Attributes;
   400       _writer_bits::ValueStorageBase*> > Attributes;
   401     Attributes _attributes;
   401     Attributes _attributes;
   402 
   402 
   403     bool _skip_nodes;
   403     bool _skip_nodes;
   404     bool _skip_arcs;
   404     bool _skip_arcs;
   407 
   407 
   408     /// \brief Constructor
   408     /// \brief Constructor
   409     ///
   409     ///
   410     /// Construct a directed graph writer, which writes to the given
   410     /// Construct a directed graph writer, which writes to the given
   411     /// output stream.
   411     /// output stream.
   412     DigraphWriter(std::ostream& is, const Digraph& digraph) 
   412     DigraphWriter(std::ostream& is, const Digraph& digraph)
   413       : _os(&is), local_os(false), _digraph(digraph),
   413       : _os(&is), local_os(false), _digraph(digraph),
   414 	_skip_nodes(false), _skip_arcs(false) {}
   414         _skip_nodes(false), _skip_arcs(false) {}
   415 
   415 
   416     /// \brief Constructor
   416     /// \brief Constructor
   417     ///
   417     ///
   418     /// Construct a directed graph writer, which writes to the given
   418     /// Construct a directed graph writer, which writes to the given
   419     /// output file.
   419     /// output file.
   420     DigraphWriter(const std::string& fn, const Digraph& digraph) 
   420     DigraphWriter(const std::string& fn, const Digraph& digraph)
   421       : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
   421       : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
   422 	_skip_nodes(false), _skip_arcs(false) {}
   422         _skip_nodes(false), _skip_arcs(false) {}
   423 
   423 
   424     /// \brief Constructor
   424     /// \brief Constructor
   425     ///
   425     ///
   426     /// Construct a directed graph writer, which writes to the given
   426     /// Construct a directed graph writer, which writes to the given
   427     /// output file.
   427     /// output file.
   428     DigraphWriter(const char* fn, const Digraph& digraph) 
   428     DigraphWriter(const char* fn, const Digraph& digraph)
   429       : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
   429       : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
   430 	_skip_nodes(false), _skip_arcs(false) {}
   430         _skip_nodes(false), _skip_arcs(false) {}
   431 
   431 
   432     /// \brief Destructor
   432     /// \brief Destructor
   433     ~DigraphWriter() {
   433     ~DigraphWriter() {
   434       for (typename NodeMaps::iterator it = _node_maps.begin(); 
   434       for (typename NodeMaps::iterator it = _node_maps.begin();
   435 	   it != _node_maps.end(); ++it) {
   435            it != _node_maps.end(); ++it) {
   436 	delete it->second;
   436         delete it->second;
   437       }
   437       }
   438 
   438 
   439       for (typename ArcMaps::iterator it = _arc_maps.begin(); 
   439       for (typename ArcMaps::iterator it = _arc_maps.begin();
   440 	   it != _arc_maps.end(); ++it) {
   440            it != _arc_maps.end(); ++it) {
   441 	delete it->second;
   441         delete it->second;
   442       }
   442       }
   443 
   443 
   444       for (typename Attributes::iterator it = _attributes.begin(); 
   444       for (typename Attributes::iterator it = _attributes.begin();
   445 	   it != _attributes.end(); ++it) {
   445            it != _attributes.end(); ++it) {
   446 	delete it->second;
   446         delete it->second;
   447       }
   447       }
   448 
   448 
   449       if (local_os) {
   449       if (local_os) {
   450 	delete _os;
   450         delete _os;
   451       }
   451       }
   452     }
   452     }
   453 
   453 
   454   private:
   454   private:
   455 
   455 
   456     friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os, 
   456     friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os,
   457 						  const Digraph& digraph);
   457                                                   const Digraph& digraph);
   458     friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn, 
   458     friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn,
   459 						  const Digraph& digraph);   
   459                                                   const Digraph& digraph);
   460     friend DigraphWriter<Digraph> digraphWriter<>(const char *fn, 
   460     friend DigraphWriter<Digraph> digraphWriter<>(const char *fn,
   461 						  const Digraph& digraph);
   461                                                   const Digraph& digraph);
   462 
   462 
   463     DigraphWriter(DigraphWriter& other) 
   463     DigraphWriter(DigraphWriter& other)
   464       : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
   464       : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
   465 	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   465         _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   466 
   466 
   467       other._os = 0;
   467       other._os = 0;
   468       other.local_os = false;
   468       other.local_os = false;
   469 
   469 
   470       _node_index.swap(other._node_index);
   470       _node_index.swap(other._node_index);
   476 
   476 
   477       _nodes_caption = other._nodes_caption;
   477       _nodes_caption = other._nodes_caption;
   478       _arcs_caption = other._arcs_caption;
   478       _arcs_caption = other._arcs_caption;
   479       _attributes_caption = other._attributes_caption;
   479       _attributes_caption = other._attributes_caption;
   480     }
   480     }
   481     
   481 
   482     DigraphWriter& operator=(const DigraphWriter&);
   482     DigraphWriter& operator=(const DigraphWriter&);
   483 
   483 
   484   public:
   484   public:
   485 
   485 
   486     /// \name Writing rules
   486     /// \name Writing rules
   487     /// @{
   487     /// @{
   488     
   488 
   489     /// \brief Node map writing rule
   489     /// \brief Node map writing rule
   490     ///
   490     ///
   491     /// Add a node map writing rule to the writer.
   491     /// Add a node map writing rule to the writer.
   492     template <typename Map>
   492     template <typename Map>
   493     DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
   493     DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
   494       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   494       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   495       _writer_bits::MapStorageBase<Node>* storage = 
   495       _writer_bits::MapStorageBase<Node>* storage =
   496 	new _writer_bits::MapStorage<Node, Map>(map);
   496         new _writer_bits::MapStorage<Node, Map>(map);
   497       _node_maps.push_back(std::make_pair(caption, storage));
   497       _node_maps.push_back(std::make_pair(caption, storage));
   498       return *this;
   498       return *this;
   499     }
   499     }
   500 
   500 
   501     /// \brief Node map writing rule
   501     /// \brief Node map writing rule
   502     ///
   502     ///
   503     /// Add a node map writing rule with specialized converter to the
   503     /// Add a node map writing rule with specialized converter to the
   504     /// writer.
   504     /// writer.
   505     template <typename Map, typename Converter>
   505     template <typename Map, typename Converter>
   506     DigraphWriter& nodeMap(const std::string& caption, const Map& map, 
   506     DigraphWriter& nodeMap(const std::string& caption, const Map& map,
   507 			   const Converter& converter = Converter()) {
   507                            const Converter& converter = Converter()) {
   508       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   508       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   509       _writer_bits::MapStorageBase<Node>* storage = 
   509       _writer_bits::MapStorageBase<Node>* storage =
   510 	new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
   510         new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
   511       _node_maps.push_back(std::make_pair(caption, storage));
   511       _node_maps.push_back(std::make_pair(caption, storage));
   512       return *this;
   512       return *this;
   513     }
   513     }
   514 
   514 
   515     /// \brief Arc map writing rule
   515     /// \brief Arc map writing rule
   516     ///
   516     ///
   517     /// Add an arc map writing rule to the writer.
   517     /// Add an arc map writing rule to the writer.
   518     template <typename Map>
   518     template <typename Map>
   519     DigraphWriter& arcMap(const std::string& caption, const Map& map) {
   519     DigraphWriter& arcMap(const std::string& caption, const Map& map) {
   520       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   520       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   521       _writer_bits::MapStorageBase<Arc>* storage = 
   521       _writer_bits::MapStorageBase<Arc>* storage =
   522 	new _writer_bits::MapStorage<Arc, Map>(map);
   522         new _writer_bits::MapStorage<Arc, Map>(map);
   523       _arc_maps.push_back(std::make_pair(caption, storage));
   523       _arc_maps.push_back(std::make_pair(caption, storage));
   524       return *this;
   524       return *this;
   525     }
   525     }
   526 
   526 
   527     /// \brief Arc map writing rule
   527     /// \brief Arc map writing rule
   528     ///
   528     ///
   529     /// Add an arc map writing rule with specialized converter to the
   529     /// Add an arc map writing rule with specialized converter to the
   530     /// writer.
   530     /// writer.
   531     template <typename Map, typename Converter>
   531     template <typename Map, typename Converter>
   532     DigraphWriter& arcMap(const std::string& caption, const Map& map, 
   532     DigraphWriter& arcMap(const std::string& caption, const Map& map,
   533 			  const Converter& converter = Converter()) {
   533                           const Converter& converter = Converter()) {
   534       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   534       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   535       _writer_bits::MapStorageBase<Arc>* storage = 
   535       _writer_bits::MapStorageBase<Arc>* storage =
   536 	new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
   536         new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
   537       _arc_maps.push_back(std::make_pair(caption, storage));
   537       _arc_maps.push_back(std::make_pair(caption, storage));
   538       return *this;
   538       return *this;
   539     }
   539     }
   540 
   540 
   541     /// \brief Attribute writing rule
   541     /// \brief Attribute writing rule
   542     ///
   542     ///
   543     /// Add an attribute writing rule to the writer.
   543     /// Add an attribute writing rule to the writer.
   544     template <typename Value>
   544     template <typename Value>
   545     DigraphWriter& attribute(const std::string& caption, const Value& value) {
   545     DigraphWriter& attribute(const std::string& caption, const Value& value) {
   546       _writer_bits::ValueStorageBase* storage = 
   546       _writer_bits::ValueStorageBase* storage =
   547 	new _writer_bits::ValueStorage<Value>(value);
   547         new _writer_bits::ValueStorage<Value>(value);
   548       _attributes.push_back(std::make_pair(caption, storage));
   548       _attributes.push_back(std::make_pair(caption, storage));
   549       return *this;
   549       return *this;
   550     }
   550     }
   551 
   551 
   552     /// \brief Attribute writing rule
   552     /// \brief Attribute writing rule
   553     ///
   553     ///
   554     /// Add an attribute writing rule with specialized converter to the
   554     /// Add an attribute writing rule with specialized converter to the
   555     /// writer.
   555     /// writer.
   556     template <typename Value, typename Converter>
   556     template <typename Value, typename Converter>
   557     DigraphWriter& attribute(const std::string& caption, const Value& value, 
   557     DigraphWriter& attribute(const std::string& caption, const Value& value,
   558 			     const Converter& converter = Converter()) {
   558                              const Converter& converter = Converter()) {
   559       _writer_bits::ValueStorageBase* storage = 
   559       _writer_bits::ValueStorageBase* storage =
   560 	new _writer_bits::ValueStorage<Value, Converter>(value, converter);
   560         new _writer_bits::ValueStorage<Value, Converter>(value, converter);
   561       _attributes.push_back(std::make_pair(caption, storage));
   561       _attributes.push_back(std::make_pair(caption, storage));
   562       return *this;
   562       return *this;
   563     }
   563     }
   564 
   564 
   565     /// \brief Node writing rule
   565     /// \brief Node writing rule
   566     ///
   566     ///
   567     /// Add a node writing rule to the writer.
   567     /// Add a node writing rule to the writer.
   568     DigraphWriter& node(const std::string& caption, const Node& node) {
   568     DigraphWriter& node(const std::string& caption, const Node& node) {
   569       typedef _writer_bits::MapLookUpConverter<Node> Converter;
   569       typedef _writer_bits::MapLookUpConverter<Node> Converter;
   570       Converter converter(_node_index);
   570       Converter converter(_node_index);
   571       _writer_bits::ValueStorageBase* storage = 
   571       _writer_bits::ValueStorageBase* storage =
   572 	new _writer_bits::ValueStorage<Node, Converter>(node, converter);
   572         new _writer_bits::ValueStorage<Node, Converter>(node, converter);
   573       _attributes.push_back(std::make_pair(caption, storage));
   573       _attributes.push_back(std::make_pair(caption, storage));
   574       return *this;
   574       return *this;
   575     }
   575     }
   576 
   576 
   577     /// \brief Arc writing rule
   577     /// \brief Arc writing rule
   578     ///
   578     ///
   579     /// Add an arc writing rule to writer.
   579     /// Add an arc writing rule to writer.
   580     DigraphWriter& arc(const std::string& caption, const Arc& arc) {
   580     DigraphWriter& arc(const std::string& caption, const Arc& arc) {
   581       typedef _writer_bits::MapLookUpConverter<Arc> Converter;
   581       typedef _writer_bits::MapLookUpConverter<Arc> Converter;
   582       Converter converter(_arc_index);
   582       Converter converter(_arc_index);
   583       _writer_bits::ValueStorageBase* storage = 
   583       _writer_bits::ValueStorageBase* storage =
   584 	new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
   584         new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
   585       _attributes.push_back(std::make_pair(caption, storage));
   585       _attributes.push_back(std::make_pair(caption, storage));
   586       return *this;
   586       return *this;
   587     }
   587     }
   588 
   588 
   589     /// \name Section captions
   589     /// \name Section captions
   639   private:
   639   private:
   640 
   640 
   641     void writeNodes() {
   641     void writeNodes() {
   642       _writer_bits::MapStorageBase<Node>* label = 0;
   642       _writer_bits::MapStorageBase<Node>* label = 0;
   643       for (typename NodeMaps::iterator it = _node_maps.begin();
   643       for (typename NodeMaps::iterator it = _node_maps.begin();
   644 	   it != _node_maps.end(); ++it) {
   644            it != _node_maps.end(); ++it) {
   645         if (it->first == "label") {
   645         if (it->first == "label") {
   646 	  label = it->second;
   646           label = it->second;
   647 	  break;
   647           break;
   648 	}
   648         }
   649       }
   649       }
   650 
   650 
   651       *_os << "@nodes";
   651       *_os << "@nodes";
   652       if (!_nodes_caption.empty()) {
   652       if (!_nodes_caption.empty()) {
   653 	_writer_bits::writeToken(*_os << ' ', _nodes_caption);
   653         _writer_bits::writeToken(*_os << ' ', _nodes_caption);
   654       }
   654       }
   655       *_os << std::endl;
   655       *_os << std::endl;
   656 
   656 
   657       if (label == 0) {
   657       if (label == 0) {
   658 	*_os << "label" << '\t';
   658         *_os << "label" << '\t';
   659       }
   659       }
   660       for (typename NodeMaps::iterator it = _node_maps.begin();
   660       for (typename NodeMaps::iterator it = _node_maps.begin();
   661 	   it != _node_maps.end(); ++it) {
   661            it != _node_maps.end(); ++it) {
   662 	_writer_bits::writeToken(*_os, it->first) << '\t';
   662         _writer_bits::writeToken(*_os, it->first) << '\t';
   663       }
   663       }
   664       *_os << std::endl;
   664       *_os << std::endl;
   665 
   665 
   666       std::vector<Node> nodes;
   666       std::vector<Node> nodes;
   667       for (NodeIt n(_digraph); n != INVALID; ++n) {
   667       for (NodeIt n(_digraph); n != INVALID; ++n) {
   668 	nodes.push_back(n);
   668         nodes.push_back(n);
   669       }
   669       }
   670       
   670 
   671       if (label == 0) {
   671       if (label == 0) {
   672 	IdMap<Digraph, Node> id_map(_digraph);
   672         IdMap<Digraph, Node> id_map(_digraph);
   673 	_writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
   673         _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
   674 	std::sort(nodes.begin(), nodes.end(), id_less);
   674         std::sort(nodes.begin(), nodes.end(), id_less);
   675       } else {
   675       } else {
   676 	label->sort(nodes);
   676         label->sort(nodes);
   677       }
   677       }
   678 
   678 
   679       for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
   679       for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
   680 	Node n = nodes[i];
   680         Node n = nodes[i];
   681 	if (label == 0) {
   681         if (label == 0) {
   682 	  std::ostringstream os;
   682           std::ostringstream os;
   683 	  os << _digraph.id(n);
   683           os << _digraph.id(n);
   684 	  _writer_bits::writeToken(*_os, os.str());
   684           _writer_bits::writeToken(*_os, os.str());
   685 	  *_os << '\t';
   685           *_os << '\t';
   686 	  _node_index.insert(std::make_pair(n, os.str()));
   686           _node_index.insert(std::make_pair(n, os.str()));
   687 	}
   687         }
   688 	for (typename NodeMaps::iterator it = _node_maps.begin();
   688         for (typename NodeMaps::iterator it = _node_maps.begin();
   689 	     it != _node_maps.end(); ++it) {
   689              it != _node_maps.end(); ++it) {
   690 	  std::string value = it->second->get(n);
   690           std::string value = it->second->get(n);
   691 	  _writer_bits::writeToken(*_os, value);
   691           _writer_bits::writeToken(*_os, value);
   692 	  if (it->first == "label") {
   692           if (it->first == "label") {
   693 	    _node_index.insert(std::make_pair(n, value));
   693             _node_index.insert(std::make_pair(n, value));
   694 	  }
   694           }
   695 	  *_os << '\t';
   695           *_os << '\t';
   696 	}
   696         }
   697 	*_os << std::endl;
   697         *_os << std::endl;
   698       }
   698       }
   699     }
   699     }
   700 
   700 
   701     void createNodeIndex() {
   701     void createNodeIndex() {
   702       _writer_bits::MapStorageBase<Node>* label = 0;
   702       _writer_bits::MapStorageBase<Node>* label = 0;
   703       for (typename NodeMaps::iterator it = _node_maps.begin();
   703       for (typename NodeMaps::iterator it = _node_maps.begin();
   704 	   it != _node_maps.end(); ++it) {
   704            it != _node_maps.end(); ++it) {
   705         if (it->first == "label") {
   705         if (it->first == "label") {
   706 	  label = it->second;
   706           label = it->second;
   707 	  break;
   707           break;
   708 	}
   708         }
   709       }
   709       }
   710 
   710 
   711       if (label == 0) {
   711       if (label == 0) {
   712 	for (NodeIt n(_digraph); n != INVALID; ++n) {
   712         for (NodeIt n(_digraph); n != INVALID; ++n) {
   713 	  std::ostringstream os;
   713           std::ostringstream os;
   714 	  os << _digraph.id(n);
   714           os << _digraph.id(n);
   715 	  _node_index.insert(std::make_pair(n, os.str()));	  
   715           _node_index.insert(std::make_pair(n, os.str()));
   716 	}	
   716         }
   717       } else {
   717       } else {
   718 	for (NodeIt n(_digraph); n != INVALID; ++n) {
   718         for (NodeIt n(_digraph); n != INVALID; ++n) {
   719 	  std::string value = label->get(n);	  
   719           std::string value = label->get(n);
   720 	  _node_index.insert(std::make_pair(n, value));
   720           _node_index.insert(std::make_pair(n, value));
   721 	}
   721         }
   722       }
   722       }
   723     }
   723     }
   724 
   724 
   725     void writeArcs() {
   725     void writeArcs() {
   726       _writer_bits::MapStorageBase<Arc>* label = 0;
   726       _writer_bits::MapStorageBase<Arc>* label = 0;
   727       for (typename ArcMaps::iterator it = _arc_maps.begin();
   727       for (typename ArcMaps::iterator it = _arc_maps.begin();
   728 	   it != _arc_maps.end(); ++it) {
   728            it != _arc_maps.end(); ++it) {
   729         if (it->first == "label") {
   729         if (it->first == "label") {
   730 	  label = it->second;
   730           label = it->second;
   731 	  break;
   731           break;
   732 	}
   732         }
   733       }
   733       }
   734 
   734 
   735       *_os << "@arcs";
   735       *_os << "@arcs";
   736       if (!_arcs_caption.empty()) {
   736       if (!_arcs_caption.empty()) {
   737 	_writer_bits::writeToken(*_os << ' ', _arcs_caption);
   737         _writer_bits::writeToken(*_os << ' ', _arcs_caption);
   738       }
   738       }
   739       *_os << std::endl;
   739       *_os << std::endl;
   740 
   740 
   741       *_os << '\t' << '\t';
   741       *_os << '\t' << '\t';
   742       if (label == 0) {
   742       if (label == 0) {
   743 	*_os << "label" << '\t';
   743         *_os << "label" << '\t';
   744       }
   744       }
   745       for (typename ArcMaps::iterator it = _arc_maps.begin();
   745       for (typename ArcMaps::iterator it = _arc_maps.begin();
   746 	   it != _arc_maps.end(); ++it) {
   746            it != _arc_maps.end(); ++it) {
   747 	_writer_bits::writeToken(*_os, it->first) << '\t';
   747         _writer_bits::writeToken(*_os, it->first) << '\t';
   748       }
   748       }
   749       *_os << std::endl;
   749       *_os << std::endl;
   750 
   750 
   751       std::vector<Arc> arcs;
   751       std::vector<Arc> arcs;
   752       for (ArcIt n(_digraph); n != INVALID; ++n) {
   752       for (ArcIt n(_digraph); n != INVALID; ++n) {
   753 	arcs.push_back(n);
   753         arcs.push_back(n);
   754       }
   754       }
   755       
   755 
   756       if (label == 0) {
   756       if (label == 0) {
   757 	IdMap<Digraph, Arc> id_map(_digraph);
   757         IdMap<Digraph, Arc> id_map(_digraph);
   758 	_writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
   758         _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
   759 	std::sort(arcs.begin(), arcs.end(), id_less);
   759         std::sort(arcs.begin(), arcs.end(), id_less);
   760       } else {
   760       } else {
   761 	label->sort(arcs);
   761         label->sort(arcs);
   762       }
   762       }
   763 
   763 
   764       for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
   764       for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
   765 	Arc a = arcs[i];
   765         Arc a = arcs[i];
   766 	_writer_bits::writeToken(*_os, _node_index.
   766         _writer_bits::writeToken(*_os, _node_index.
   767 				 find(_digraph.source(a))->second);
   767                                  find(_digraph.source(a))->second);
   768 	*_os << '\t';
   768         *_os << '\t';
   769 	_writer_bits::writeToken(*_os, _node_index.
   769         _writer_bits::writeToken(*_os, _node_index.
   770 				 find(_digraph.target(a))->second);
   770                                  find(_digraph.target(a))->second);
   771 	*_os << '\t';
   771         *_os << '\t';
   772 	if (label == 0) {
   772         if (label == 0) {
   773 	  std::ostringstream os;
   773           std::ostringstream os;
   774 	  os << _digraph.id(a);
   774           os << _digraph.id(a);
   775 	  _writer_bits::writeToken(*_os, os.str());
   775           _writer_bits::writeToken(*_os, os.str());
   776 	  *_os << '\t';
   776           *_os << '\t';
   777 	  _arc_index.insert(std::make_pair(a, os.str()));
   777           _arc_index.insert(std::make_pair(a, os.str()));
   778 	}
   778         }
   779 	for (typename ArcMaps::iterator it = _arc_maps.begin();
   779         for (typename ArcMaps::iterator it = _arc_maps.begin();
   780 	     it != _arc_maps.end(); ++it) {
   780              it != _arc_maps.end(); ++it) {
   781 	  std::string value = it->second->get(a);
   781           std::string value = it->second->get(a);
   782 	  _writer_bits::writeToken(*_os, value);
   782           _writer_bits::writeToken(*_os, value);
   783 	  if (it->first == "label") {
   783           if (it->first == "label") {
   784 	    _arc_index.insert(std::make_pair(a, value));
   784             _arc_index.insert(std::make_pair(a, value));
   785 	  }
   785           }
   786 	  *_os << '\t';
   786           *_os << '\t';
   787 	}
   787         }
   788 	*_os << std::endl;
   788         *_os << std::endl;
   789       }
   789       }
   790     }
   790     }
   791 
   791 
   792     void createArcIndex() {
   792     void createArcIndex() {
   793       _writer_bits::MapStorageBase<Arc>* label = 0;
   793       _writer_bits::MapStorageBase<Arc>* label = 0;
   794       for (typename ArcMaps::iterator it = _arc_maps.begin();
   794       for (typename ArcMaps::iterator it = _arc_maps.begin();
   795 	   it != _arc_maps.end(); ++it) {
   795            it != _arc_maps.end(); ++it) {
   796         if (it->first == "label") {
   796         if (it->first == "label") {
   797 	  label = it->second;
   797           label = it->second;
   798 	  break;
   798           break;
   799 	}
   799         }
   800       }
   800       }
   801 
   801 
   802       if (label == 0) {
   802       if (label == 0) {
   803 	for (ArcIt a(_digraph); a != INVALID; ++a) {
   803         for (ArcIt a(_digraph); a != INVALID; ++a) {
   804 	  std::ostringstream os;
   804           std::ostringstream os;
   805 	  os << _digraph.id(a);
   805           os << _digraph.id(a);
   806 	  _arc_index.insert(std::make_pair(a, os.str()));	  
   806           _arc_index.insert(std::make_pair(a, os.str()));
   807 	}	
   807         }
   808       } else {
   808       } else {
   809 	for (ArcIt a(_digraph); a != INVALID; ++a) {
   809         for (ArcIt a(_digraph); a != INVALID; ++a) {
   810 	  std::string value = label->get(a);	  
   810           std::string value = label->get(a);
   811 	  _arc_index.insert(std::make_pair(a, value));
   811           _arc_index.insert(std::make_pair(a, value));
   812 	}
   812         }
   813       }
   813       }
   814     }
   814     }
   815 
   815 
   816     void writeAttributes() {
   816     void writeAttributes() {
   817       if (_attributes.empty()) return;
   817       if (_attributes.empty()) return;
   818       *_os << "@attributes";
   818       *_os << "@attributes";
   819       if (!_attributes_caption.empty()) {
   819       if (!_attributes_caption.empty()) {
   820 	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
   820         _writer_bits::writeToken(*_os << ' ', _attributes_caption);
   821       }
   821       }
   822       *_os << std::endl;
   822       *_os << std::endl;
   823       for (typename Attributes::iterator it = _attributes.begin();
   823       for (typename Attributes::iterator it = _attributes.begin();
   824 	   it != _attributes.end(); ++it) {
   824            it != _attributes.end(); ++it) {
   825 	_writer_bits::writeToken(*_os, it->first) << ' ';
   825         _writer_bits::writeToken(*_os, it->first) << ' ';
   826 	_writer_bits::writeToken(*_os, it->second->get());
   826         _writer_bits::writeToken(*_os, it->second->get());
   827 	*_os << std::endl;
   827         *_os << std::endl;
   828       }
   828       }
   829     }
   829     }
   830     
   830 
   831   public:
   831   public:
   832     
   832 
   833     /// \name Execution of the writer    
   833     /// \name Execution of the writer
   834     /// @{
   834     /// @{
   835 
   835 
   836     /// \brief Start the batch processing
   836     /// \brief Start the batch processing
   837     ///
   837     ///
   838     /// This function starts the batch processing.
   838     /// This function starts the batch processing.
   839     void run() {
   839     void run() {
   840       if (!_skip_nodes) {
   840       if (!_skip_nodes) {
   841 	writeNodes();
   841         writeNodes();
   842       } else {
   842       } else {
   843 	createNodeIndex();
   843         createNodeIndex();
   844       }
   844       }
   845       if (!_skip_arcs) {      
   845       if (!_skip_arcs) {
   846 	writeArcs();
   846         writeArcs();
   847       } else {
   847       } else {
   848 	createArcIndex();
   848         createArcIndex();
   849       }
   849       }
   850       writeAttributes();
   850       writeAttributes();
   851     }
   851     }
   852 
   852 
   853     /// \brief Give back the stream of the writer
   853     /// \brief Give back the stream of the writer
   859 
   859 
   860     /// @}
   860     /// @}
   861   };
   861   };
   862 
   862 
   863   /// \brief Return a \ref DigraphWriter class
   863   /// \brief Return a \ref DigraphWriter class
   864   /// 
   864   ///
   865   /// This function just returns a \ref DigraphWriter class.
   865   /// This function just returns a \ref DigraphWriter class.
   866   /// \relates DigraphWriter
   866   /// \relates DigraphWriter
   867   template <typename Digraph>
   867   template <typename Digraph>
   868   DigraphWriter<Digraph> digraphWriter(std::ostream& os, 
   868   DigraphWriter<Digraph> digraphWriter(std::ostream& os,
   869 				       const Digraph& digraph) {
   869                                        const Digraph& digraph) {
   870     DigraphWriter<Digraph> tmp(os, digraph);
   870     DigraphWriter<Digraph> tmp(os, digraph);
   871     return tmp;
   871     return tmp;
   872   }
   872   }
   873 
   873 
   874   /// \brief Return a \ref DigraphWriter class
   874   /// \brief Return a \ref DigraphWriter class
   875   /// 
   875   ///
   876   /// This function just returns a \ref DigraphWriter class.
   876   /// This function just returns a \ref DigraphWriter class.
   877   /// \relates DigraphWriter
   877   /// \relates DigraphWriter
   878   template <typename Digraph>
   878   template <typename Digraph>
   879   DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
   879   DigraphWriter<Digraph> digraphWriter(const std::string& fn,
   880 				       const Digraph& digraph) {
   880                                        const Digraph& digraph) {
   881     DigraphWriter<Digraph> tmp(fn, digraph);
   881     DigraphWriter<Digraph> tmp(fn, digraph);
   882     return tmp;
   882     return tmp;
   883   }
   883   }
   884 
   884 
   885   /// \brief Return a \ref DigraphWriter class
   885   /// \brief Return a \ref DigraphWriter class
   886   /// 
   886   ///
   887   /// This function just returns a \ref DigraphWriter class.
   887   /// This function just returns a \ref DigraphWriter class.
   888   /// \relates DigraphWriter
   888   /// \relates DigraphWriter
   889   template <typename Digraph>
   889   template <typename Digraph>
   890   DigraphWriter<Digraph> digraphWriter(const char* fn, 
   890   DigraphWriter<Digraph> digraphWriter(const char* fn,
   891 				       const Digraph& digraph) {
   891                                        const Digraph& digraph) {
   892     DigraphWriter<Digraph> tmp(fn, digraph);
   892     DigraphWriter<Digraph> tmp(fn, digraph);
   893     return tmp;
   893     return tmp;
   894   }
   894   }
   895 
   895 
   896   template <typename Graph>
   896   template <typename Graph>
   897   class GraphWriter;
   897   class GraphWriter;
   898 
   898 
   899   template <typename Graph>
   899   template <typename Graph>
   900   GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);    
   900   GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);
   901 
   901 
   902   template <typename Graph>
   902   template <typename Graph>
   903   GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);   
   903   GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);
   904 
   904 
   905   template <typename Graph>
   905   template <typename Graph>
   906   GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);    
   906   GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);
   907 
   907 
   908   /// \ingroup lemon_io
   908   /// \ingroup lemon_io
   909   ///  
   909   ///
   910   /// \brief \ref lgf-format "LGF" writer for directed graphs
   910   /// \brief \ref lgf-format "LGF" writer for directed graphs
   911   ///
   911   ///
   912   /// This utility writes an \ref lgf-format "LGF" file.
   912   /// This utility writes an \ref lgf-format "LGF" file.
   913   ///
   913   ///
   914   /// It can be used almost the same way as \c DigraphWriter.
   914   /// It can be used almost the same way as \c DigraphWriter.
   924   class GraphWriter {
   924   class GraphWriter {
   925   public:
   925   public:
   926 
   926 
   927     typedef _Graph Graph;
   927     typedef _Graph Graph;
   928     TEMPLATE_GRAPH_TYPEDEFS(Graph);
   928     TEMPLATE_GRAPH_TYPEDEFS(Graph);
   929     
   929 
   930   private:
   930   private:
   931 
   931 
   932 
   932 
   933     std::ostream* _os;
   933     std::ostream* _os;
   934     bool local_os;
   934     bool local_os;
   936     Graph& _graph;
   936     Graph& _graph;
   937 
   937 
   938     std::string _nodes_caption;
   938     std::string _nodes_caption;
   939     std::string _edges_caption;
   939     std::string _edges_caption;
   940     std::string _attributes_caption;
   940     std::string _attributes_caption;
   941     
   941 
   942     typedef std::map<Node, std::string> NodeIndex;
   942     typedef std::map<Node, std::string> NodeIndex;
   943     NodeIndex _node_index;
   943     NodeIndex _node_index;
   944     typedef std::map<Edge, std::string> EdgeIndex;
   944     typedef std::map<Edge, std::string> EdgeIndex;
   945     EdgeIndex _edge_index;
   945     EdgeIndex _edge_index;
   946 
   946 
   947     typedef std::vector<std::pair<std::string, 
   947     typedef std::vector<std::pair<std::string,
   948       _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
   948       _writer_bits::MapStorageBase<Node>* > > NodeMaps;
   949     NodeMaps _node_maps; 
   949     NodeMaps _node_maps;
   950 
   950 
   951     typedef std::vector<std::pair<std::string, 
   951     typedef std::vector<std::pair<std::string,
   952       _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
   952       _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
   953     EdgeMaps _edge_maps;
   953     EdgeMaps _edge_maps;
   954 
   954 
   955     typedef std::vector<std::pair<std::string, 
   955     typedef std::vector<std::pair<std::string,
   956       _writer_bits::ValueStorageBase*> > Attributes;
   956       _writer_bits::ValueStorageBase*> > Attributes;
   957     Attributes _attributes;
   957     Attributes _attributes;
   958 
   958 
   959     bool _skip_nodes;
   959     bool _skip_nodes;
   960     bool _skip_edges;
   960     bool _skip_edges;
   963 
   963 
   964     /// \brief Constructor
   964     /// \brief Constructor
   965     ///
   965     ///
   966     /// Construct a directed graph writer, which writes to the given
   966     /// Construct a directed graph writer, which writes to the given
   967     /// output stream.
   967     /// output stream.
   968     GraphWriter(std::ostream& is, const Graph& graph) 
   968     GraphWriter(std::ostream& is, const Graph& graph)
   969       : _os(&is), local_os(false), _graph(graph),
   969       : _os(&is), local_os(false), _graph(graph),
   970 	_skip_nodes(false), _skip_edges(false) {}
   970         _skip_nodes(false), _skip_edges(false) {}
   971 
   971 
   972     /// \brief Constructor
   972     /// \brief Constructor
   973     ///
   973     ///
   974     /// Construct a directed graph writer, which writes to the given
   974     /// Construct a directed graph writer, which writes to the given
   975     /// output file.
   975     /// output file.
   976     GraphWriter(const std::string& fn, const Graph& graph) 
   976     GraphWriter(const std::string& fn, const Graph& graph)
   977       : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
   977       : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
   978 	_skip_nodes(false), _skip_edges(false) {}
   978         _skip_nodes(false), _skip_edges(false) {}
   979 
   979 
   980     /// \brief Constructor
   980     /// \brief Constructor
   981     ///
   981     ///
   982     /// Construct a directed graph writer, which writes to the given
   982     /// Construct a directed graph writer, which writes to the given
   983     /// output file.
   983     /// output file.
   984     GraphWriter(const char* fn, const Graph& graph) 
   984     GraphWriter(const char* fn, const Graph& graph)
   985       : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
   985       : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
   986 	_skip_nodes(false), _skip_edges(false) {}
   986         _skip_nodes(false), _skip_edges(false) {}
   987 
   987 
   988     /// \brief Destructor
   988     /// \brief Destructor
   989     ~GraphWriter() {
   989     ~GraphWriter() {
   990       for (typename NodeMaps::iterator it = _node_maps.begin(); 
   990       for (typename NodeMaps::iterator it = _node_maps.begin();
   991 	   it != _node_maps.end(); ++it) {
   991            it != _node_maps.end(); ++it) {
   992 	delete it->second;
   992         delete it->second;
   993       }
   993       }
   994 
   994 
   995       for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
   995       for (typename EdgeMaps::iterator it = _edge_maps.begin();
   996 	   it != _edge_maps.end(); ++it) {
   996            it != _edge_maps.end(); ++it) {
   997 	delete it->second;
   997         delete it->second;
   998       }
   998       }
   999 
   999 
  1000       for (typename Attributes::iterator it = _attributes.begin(); 
  1000       for (typename Attributes::iterator it = _attributes.begin();
  1001 	   it != _attributes.end(); ++it) {
  1001            it != _attributes.end(); ++it) {
  1002 	delete it->second;
  1002         delete it->second;
  1003       }
  1003       }
  1004 
  1004 
  1005       if (local_os) {
  1005       if (local_os) {
  1006 	delete _os;
  1006         delete _os;
  1007       }
  1007       }
  1008     }
  1008     }
  1009     
  1009 
  1010   private:
  1010   private:
  1011 
  1011 
  1012     friend GraphWriter<Graph> graphWriter<>(std::ostream& os, 
  1012     friend GraphWriter<Graph> graphWriter<>(std::ostream& os,
  1013 					    const Graph& graph);    
  1013                                             const Graph& graph);
  1014     friend GraphWriter<Graph> graphWriter<>(const std::string& fn, 
  1014     friend GraphWriter<Graph> graphWriter<>(const std::string& fn,
  1015 					    const Graph& graph);   
  1015                                             const Graph& graph);
  1016     friend GraphWriter<Graph> graphWriter<>(const char *fn, 
  1016     friend GraphWriter<Graph> graphWriter<>(const char *fn,
  1017 					    const Graph& graph);    
  1017                                             const Graph& graph);
  1018 
  1018 
  1019     GraphWriter(GraphWriter& other) 
  1019     GraphWriter(GraphWriter& other)
  1020       : _os(other._os), local_os(other.local_os), _graph(other._graph),
  1020       : _os(other._os), local_os(other.local_os), _graph(other._graph),
  1021 	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
  1021         _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
  1022 
  1022 
  1023       other._os = 0;
  1023       other._os = 0;
  1024       other.local_os = false;
  1024       other.local_os = false;
  1025 
  1025 
  1026       _node_index.swap(other._node_index);
  1026       _node_index.swap(other._node_index);
  1039 
  1039 
  1040   public:
  1040   public:
  1041 
  1041 
  1042     /// \name Writing rules
  1042     /// \name Writing rules
  1043     /// @{
  1043     /// @{
  1044     
  1044 
  1045     /// \brief Node map writing rule
  1045     /// \brief Node map writing rule
  1046     ///
  1046     ///
  1047     /// Add a node map writing rule to the writer.
  1047     /// Add a node map writing rule to the writer.
  1048     template <typename Map>
  1048     template <typename Map>
  1049     GraphWriter& nodeMap(const std::string& caption, const Map& map) {
  1049     GraphWriter& nodeMap(const std::string& caption, const Map& map) {
  1050       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
  1050       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
  1051       _writer_bits::MapStorageBase<Node>* storage = 
  1051       _writer_bits::MapStorageBase<Node>* storage =
  1052 	new _writer_bits::MapStorage<Node, Map>(map);
  1052         new _writer_bits::MapStorage<Node, Map>(map);
  1053       _node_maps.push_back(std::make_pair(caption, storage));
  1053       _node_maps.push_back(std::make_pair(caption, storage));
  1054       return *this;
  1054       return *this;
  1055     }
  1055     }
  1056 
  1056 
  1057     /// \brief Node map writing rule
  1057     /// \brief Node map writing rule
  1058     ///
  1058     ///
  1059     /// Add a node map writing rule with specialized converter to the
  1059     /// Add a node map writing rule with specialized converter to the
  1060     /// writer.
  1060     /// writer.
  1061     template <typename Map, typename Converter>
  1061     template <typename Map, typename Converter>
  1062     GraphWriter& nodeMap(const std::string& caption, const Map& map, 
  1062     GraphWriter& nodeMap(const std::string& caption, const Map& map,
  1063 			   const Converter& converter = Converter()) {
  1063                            const Converter& converter = Converter()) {
  1064       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
  1064       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
  1065       _writer_bits::MapStorageBase<Node>* storage = 
  1065       _writer_bits::MapStorageBase<Node>* storage =
  1066 	new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
  1066         new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
  1067       _node_maps.push_back(std::make_pair(caption, storage));
  1067       _node_maps.push_back(std::make_pair(caption, storage));
  1068       return *this;
  1068       return *this;
  1069     }
  1069     }
  1070 
  1070 
  1071     /// \brief Edge map writing rule
  1071     /// \brief Edge map writing rule
  1072     ///
  1072     ///
  1073     /// Add an edge map writing rule to the writer.
  1073     /// Add an edge map writing rule to the writer.
  1074     template <typename Map>
  1074     template <typename Map>
  1075     GraphWriter& edgeMap(const std::string& caption, const Map& map) {
  1075     GraphWriter& edgeMap(const std::string& caption, const Map& map) {
  1076       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1076       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1077       _writer_bits::MapStorageBase<Edge>* storage = 
  1077       _writer_bits::MapStorageBase<Edge>* storage =
  1078 	new _writer_bits::MapStorage<Edge, Map>(map);
  1078         new _writer_bits::MapStorage<Edge, Map>(map);
  1079       _edge_maps.push_back(std::make_pair(caption, storage));
  1079       _edge_maps.push_back(std::make_pair(caption, storage));
  1080       return *this;
  1080       return *this;
  1081     }
  1081     }
  1082 
  1082 
  1083     /// \brief Edge map writing rule
  1083     /// \brief Edge map writing rule
  1084     ///
  1084     ///
  1085     /// Add an edge map writing rule with specialized converter to the
  1085     /// Add an edge map writing rule with specialized converter to the
  1086     /// writer.
  1086     /// writer.
  1087     template <typename Map, typename Converter>
  1087     template <typename Map, typename Converter>
  1088     GraphWriter& edgeMap(const std::string& caption, const Map& map, 
  1088     GraphWriter& edgeMap(const std::string& caption, const Map& map,
  1089 			  const Converter& converter = Converter()) {
  1089                           const Converter& converter = Converter()) {
  1090       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1090       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
  1091       _writer_bits::MapStorageBase<Edge>* storage = 
  1091       _writer_bits::MapStorageBase<Edge>* storage =
  1092 	new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
  1092         new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
  1093       _edge_maps.push_back(std::make_pair(caption, storage));
  1093       _edge_maps.push_back(std::make_pair(caption, storage));
  1094       return *this;
  1094       return *this;
  1095     }
  1095     }
  1096 
  1096 
  1097     /// \brief Arc map writing rule
  1097     /// \brief Arc map writing rule
  1098     ///
  1098     ///
  1099     /// Add an arc map writing rule to the writer.
  1099     /// Add an arc map writing rule to the writer.
  1100     template <typename Map>
  1100     template <typename Map>
  1101     GraphWriter& arcMap(const std::string& caption, const Map& map) {
  1101     GraphWriter& arcMap(const std::string& caption, const Map& map) {
  1102       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
  1102       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
  1103       _writer_bits::MapStorageBase<Edge>* forward_storage = 
  1103       _writer_bits::MapStorageBase<Edge>* forward_storage =
  1104 	new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
  1104         new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
  1105       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1105       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1106       _writer_bits::MapStorageBase<Edge>* backward_storage = 
  1106       _writer_bits::MapStorageBase<Edge>* backward_storage =
  1107 	new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
  1107         new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
  1108       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1108       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1109       return *this;
  1109       return *this;
  1110     }
  1110     }
  1111 
  1111 
  1112     /// \brief Arc map writing rule
  1112     /// \brief Arc map writing rule
  1113     ///
  1113     ///
  1114     /// Add an arc map writing rule with specialized converter to the
  1114     /// Add an arc map writing rule with specialized converter to the
  1115     /// writer.
  1115     /// writer.
  1116     template <typename Map, typename Converter>
  1116     template <typename Map, typename Converter>
  1117     GraphWriter& arcMap(const std::string& caption, const Map& map, 
  1117     GraphWriter& arcMap(const std::string& caption, const Map& map,
  1118 			  const Converter& converter = Converter()) {
  1118                           const Converter& converter = Converter()) {
  1119       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
  1119       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
  1120       _writer_bits::MapStorageBase<Edge>* forward_storage = 
  1120       _writer_bits::MapStorageBase<Edge>* forward_storage =
  1121 	new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
  1121         new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
  1122 	(_graph, map, converter);
  1122         (_graph, map, converter);
  1123       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1123       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
  1124       _writer_bits::MapStorageBase<Edge>* backward_storage = 
  1124       _writer_bits::MapStorageBase<Edge>* backward_storage =
  1125 	new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
  1125         new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
  1126 	(_graph, map, converter);
  1126         (_graph, map, converter);
  1127       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1127       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
  1128       return *this;
  1128       return *this;
  1129     }
  1129     }
  1130 
  1130 
  1131     /// \brief Attribute writing rule
  1131     /// \brief Attribute writing rule
  1132     ///
  1132     ///
  1133     /// Add an attribute writing rule to the writer.
  1133     /// Add an attribute writing rule to the writer.
  1134     template <typename Value>
  1134     template <typename Value>
  1135     GraphWriter& attribute(const std::string& caption, const Value& value) {
  1135     GraphWriter& attribute(const std::string& caption, const Value& value) {
  1136       _writer_bits::ValueStorageBase* storage = 
  1136       _writer_bits::ValueStorageBase* storage =
  1137 	new _writer_bits::ValueStorage<Value>(value);
  1137         new _writer_bits::ValueStorage<Value>(value);
  1138       _attributes.push_back(std::make_pair(caption, storage));
  1138       _attributes.push_back(std::make_pair(caption, storage));
  1139       return *this;
  1139       return *this;
  1140     }
  1140     }
  1141 
  1141 
  1142     /// \brief Attribute writing rule
  1142     /// \brief Attribute writing rule
  1143     ///
  1143     ///
  1144     /// Add an attribute writing rule with specialized converter to the
  1144     /// Add an attribute writing rule with specialized converter to the
  1145     /// writer.
  1145     /// writer.
  1146     template <typename Value, typename Converter>
  1146     template <typename Value, typename Converter>
  1147     GraphWriter& attribute(const std::string& caption, const Value& value, 
  1147     GraphWriter& attribute(const std::string& caption, const Value& value,
  1148 			     const Converter& converter = Converter()) {
  1148                              const Converter& converter = Converter()) {
  1149       _writer_bits::ValueStorageBase* storage = 
  1149       _writer_bits::ValueStorageBase* storage =
  1150 	new _writer_bits::ValueStorage<Value, Converter>(value, converter);
  1150         new _writer_bits::ValueStorage<Value, Converter>(value, converter);
  1151       _attributes.push_back(std::make_pair(caption, storage));
  1151       _attributes.push_back(std::make_pair(caption, storage));
  1152       return *this;
  1152       return *this;
  1153     }
  1153     }
  1154 
  1154 
  1155     /// \brief Node writing rule
  1155     /// \brief Node writing rule
  1156     ///
  1156     ///
  1157     /// Add a node writing rule to the writer.
  1157     /// Add a node writing rule to the writer.
  1158     GraphWriter& node(const std::string& caption, const Node& node) {
  1158     GraphWriter& node(const std::string& caption, const Node& node) {
  1159       typedef _writer_bits::MapLookUpConverter<Node> Converter;
  1159       typedef _writer_bits::MapLookUpConverter<Node> Converter;
  1160       Converter converter(_node_index);
  1160       Converter converter(_node_index);
  1161       _writer_bits::ValueStorageBase* storage = 
  1161       _writer_bits::ValueStorageBase* storage =
  1162 	new _writer_bits::ValueStorage<Node, Converter>(node, converter);
  1162         new _writer_bits::ValueStorage<Node, Converter>(node, converter);
  1163       _attributes.push_back(std::make_pair(caption, storage));
  1163       _attributes.push_back(std::make_pair(caption, storage));
  1164       return *this;
  1164       return *this;
  1165     }
  1165     }
  1166 
  1166 
  1167     /// \brief Edge writing rule
  1167     /// \brief Edge writing rule
  1168     ///
  1168     ///
  1169     /// Add an edge writing rule to writer.
  1169     /// Add an edge writing rule to writer.
  1170     GraphWriter& edge(const std::string& caption, const Edge& edge) {
  1170     GraphWriter& edge(const std::string& caption, const Edge& edge) {
  1171       typedef _writer_bits::MapLookUpConverter<Edge> Converter;
  1171       typedef _writer_bits::MapLookUpConverter<Edge> Converter;
  1172       Converter converter(_edge_index);
  1172       Converter converter(_edge_index);
  1173       _writer_bits::ValueStorageBase* storage = 
  1173       _writer_bits::ValueStorageBase* storage =
  1174 	new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
  1174         new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
  1175       _attributes.push_back(std::make_pair(caption, storage));
  1175       _attributes.push_back(std::make_pair(caption, storage));
  1176       return *this;
  1176       return *this;
  1177     }
  1177     }
  1178 
  1178 
  1179     /// \brief Arc writing rule
  1179     /// \brief Arc writing rule
  1180     ///
  1180     ///
  1181     /// Add an arc writing rule to writer.
  1181     /// Add an arc writing rule to writer.
  1182     GraphWriter& arc(const std::string& caption, const Arc& arc) {
  1182     GraphWriter& arc(const std::string& caption, const Arc& arc) {
  1183       typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
  1183       typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
  1184       Converter converter(_graph, _edge_index);
  1184       Converter converter(_graph, _edge_index);
  1185       _writer_bits::ValueStorageBase* storage = 
  1185       _writer_bits::ValueStorageBase* storage =
  1186 	new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
  1186         new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
  1187       _attributes.push_back(std::make_pair(caption, storage));
  1187       _attributes.push_back(std::make_pair(caption, storage));
  1188       return *this;
  1188       return *this;
  1189     }
  1189     }
  1190 
  1190 
  1191     /// \name Section captions
  1191     /// \name Section captions
  1241   private:
  1241   private:
  1242 
  1242 
  1243     void writeNodes() {
  1243     void writeNodes() {
  1244       _writer_bits::MapStorageBase<Node>* label = 0;
  1244       _writer_bits::MapStorageBase<Node>* label = 0;
  1245       for (typename NodeMaps::iterator it = _node_maps.begin();
  1245       for (typename NodeMaps::iterator it = _node_maps.begin();
  1246 	   it != _node_maps.end(); ++it) {
  1246            it != _node_maps.end(); ++it) {
  1247         if (it->first == "label") {
  1247         if (it->first == "label") {
  1248 	  label = it->second;
  1248           label = it->second;
  1249 	  break;
  1249           break;
  1250 	}
  1250         }
  1251       }
  1251       }
  1252 
  1252 
  1253       *_os << "@nodes";
  1253       *_os << "@nodes";
  1254       if (!_nodes_caption.empty()) {
  1254       if (!_nodes_caption.empty()) {
  1255 	_writer_bits::writeToken(*_os << ' ', _nodes_caption);
  1255         _writer_bits::writeToken(*_os << ' ', _nodes_caption);
  1256       }
  1256       }
  1257       *_os << std::endl;
  1257       *_os << std::endl;
  1258 
  1258 
  1259       if (label == 0) {
  1259       if (label == 0) {
  1260 	*_os << "label" << '\t';
  1260         *_os << "label" << '\t';
  1261       }
  1261       }
  1262       for (typename NodeMaps::iterator it = _node_maps.begin();
  1262       for (typename NodeMaps::iterator it = _node_maps.begin();
  1263 	   it != _node_maps.end(); ++it) {
  1263            it != _node_maps.end(); ++it) {
  1264 	_writer_bits::writeToken(*_os, it->first) << '\t';
  1264         _writer_bits::writeToken(*_os, it->first) << '\t';
  1265       }
  1265       }
  1266       *_os << std::endl;
  1266       *_os << std::endl;
  1267 
  1267 
  1268       std::vector<Node> nodes;
  1268       std::vector<Node> nodes;
  1269       for (NodeIt n(_graph); n != INVALID; ++n) {
  1269       for (NodeIt n(_graph); n != INVALID; ++n) {
  1270 	nodes.push_back(n);
  1270         nodes.push_back(n);
  1271       }
  1271       }
  1272       
  1272 
  1273       if (label == 0) {
  1273       if (label == 0) {
  1274 	IdMap<Graph, Node> id_map(_graph);
  1274         IdMap<Graph, Node> id_map(_graph);
  1275 	_writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
  1275         _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
  1276 	std::sort(nodes.begin(), nodes.end(), id_less);
  1276         std::sort(nodes.begin(), nodes.end(), id_less);
  1277       } else {
  1277       } else {
  1278 	label->sort(nodes);
  1278         label->sort(nodes);
  1279       }
  1279       }
  1280 
  1280 
  1281       for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
  1281       for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
  1282 	Node n = nodes[i];
  1282         Node n = nodes[i];
  1283 	if (label == 0) {
  1283         if (label == 0) {
  1284 	  std::ostringstream os;
  1284           std::ostringstream os;
  1285 	  os << _graph.id(n);
  1285           os << _graph.id(n);
  1286 	  _writer_bits::writeToken(*_os, os.str());
  1286           _writer_bits::writeToken(*_os, os.str());
  1287 	  *_os << '\t';
  1287           *_os << '\t';
  1288 	  _node_index.insert(std::make_pair(n, os.str()));
  1288           _node_index.insert(std::make_pair(n, os.str()));
  1289 	}
  1289         }
  1290 	for (typename NodeMaps::iterator it = _node_maps.begin();
  1290         for (typename NodeMaps::iterator it = _node_maps.begin();
  1291 	     it != _node_maps.end(); ++it) {
  1291              it != _node_maps.end(); ++it) {
  1292 	  std::string value = it->second->get(n);
  1292           std::string value = it->second->get(n);
  1293 	  _writer_bits::writeToken(*_os, value);
  1293           _writer_bits::writeToken(*_os, value);
  1294 	  if (it->first == "label") {
  1294           if (it->first == "label") {
  1295 	    _node_index.insert(std::make_pair(n, value));
  1295             _node_index.insert(std::make_pair(n, value));
  1296 	  }
  1296           }
  1297 	  *_os << '\t';
  1297           *_os << '\t';
  1298 	}
  1298         }
  1299 	*_os << std::endl;
  1299         *_os << std::endl;
  1300       }
  1300       }
  1301     }
  1301     }
  1302 
  1302 
  1303     void createNodeIndex() {
  1303     void createNodeIndex() {
  1304       _writer_bits::MapStorageBase<Node>* label = 0;
  1304       _writer_bits::MapStorageBase<Node>* label = 0;
  1305       for (typename NodeMaps::iterator it = _node_maps.begin();
  1305       for (typename NodeMaps::iterator it = _node_maps.begin();
  1306 	   it != _node_maps.end(); ++it) {
  1306            it != _node_maps.end(); ++it) {
  1307         if (it->first == "label") {
  1307         if (it->first == "label") {
  1308 	  label = it->second;
  1308           label = it->second;
  1309 	  break;
  1309           break;
  1310 	}
  1310         }
  1311       }
  1311       }
  1312 
  1312 
  1313       if (label == 0) {
  1313       if (label == 0) {
  1314 	for (NodeIt n(_graph); n != INVALID; ++n) {
  1314         for (NodeIt n(_graph); n != INVALID; ++n) {
  1315 	  std::ostringstream os;
  1315           std::ostringstream os;
  1316 	  os << _graph.id(n);
  1316           os << _graph.id(n);
  1317 	  _node_index.insert(std::make_pair(n, os.str()));	  
  1317           _node_index.insert(std::make_pair(n, os.str()));
  1318 	}	
  1318         }
  1319       } else {
  1319       } else {
  1320 	for (NodeIt n(_graph); n != INVALID; ++n) {
  1320         for (NodeIt n(_graph); n != INVALID; ++n) {
  1321 	  std::string value = label->get(n);	  
  1321           std::string value = label->get(n);
  1322 	  _node_index.insert(std::make_pair(n, value));
  1322           _node_index.insert(std::make_pair(n, value));
  1323 	}
  1323         }
  1324       }
  1324       }
  1325     }
  1325     }
  1326 
  1326 
  1327     void writeEdges() {
  1327     void writeEdges() {
  1328       _writer_bits::MapStorageBase<Edge>* label = 0;
  1328       _writer_bits::MapStorageBase<Edge>* label = 0;
  1329       for (typename EdgeMaps::iterator it = _edge_maps.begin();
  1329       for (typename EdgeMaps::iterator it = _edge_maps.begin();
  1330 	   it != _edge_maps.end(); ++it) {
  1330            it != _edge_maps.end(); ++it) {
  1331         if (it->first == "label") {
  1331         if (it->first == "label") {
  1332 	  label = it->second;
  1332           label = it->second;
  1333 	  break;
  1333           break;
  1334 	}
  1334         }
  1335       }
  1335       }
  1336 
  1336 
  1337       *_os << "@edges";
  1337       *_os << "@edges";
  1338       if (!_edges_caption.empty()) {
  1338       if (!_edges_caption.empty()) {
  1339 	_writer_bits::writeToken(*_os << ' ', _edges_caption);
  1339         _writer_bits::writeToken(*_os << ' ', _edges_caption);
  1340       }
  1340       }
  1341       *_os << std::endl;
  1341       *_os << std::endl;
  1342 
  1342 
  1343       *_os << '\t' << '\t';
  1343       *_os << '\t' << '\t';
  1344       if (label == 0) {
  1344       if (label == 0) {
  1345 	*_os << "label" << '\t';
  1345         *_os << "label" << '\t';
  1346       }
  1346       }
  1347       for (typename EdgeMaps::iterator it = _edge_maps.begin();
  1347       for (typename EdgeMaps::iterator it = _edge_maps.begin();
  1348 	   it != _edge_maps.end(); ++it) {
  1348            it != _edge_maps.end(); ++it) {
  1349 	_writer_bits::writeToken(*_os, it->first) << '\t';
  1349         _writer_bits::writeToken(*_os, it->first) << '\t';
  1350       }
  1350       }
  1351       *_os << std::endl;
  1351       *_os << std::endl;
  1352 
  1352 
  1353       std::vector<Edge> edges;
  1353       std::vector<Edge> edges;
  1354       for (EdgeIt n(_graph); n != INVALID; ++n) {
  1354       for (EdgeIt n(_graph); n != INVALID; ++n) {
  1355 	edges.push_back(n);
  1355         edges.push_back(n);
  1356       }
  1356       }
  1357       
  1357 
  1358       if (label == 0) {
  1358       if (label == 0) {
  1359 	IdMap<Graph, Edge> id_map(_graph);
  1359         IdMap<Graph, Edge> id_map(_graph);
  1360 	_writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
  1360         _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
  1361 	std::sort(edges.begin(), edges.end(), id_less);
  1361         std::sort(edges.begin(), edges.end(), id_less);
  1362       } else {
  1362       } else {
  1363 	label->sort(edges);
  1363         label->sort(edges);
  1364       }
  1364       }
  1365 
  1365 
  1366       for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
  1366       for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
  1367 	Edge e = edges[i];
  1367         Edge e = edges[i];
  1368 	_writer_bits::writeToken(*_os, _node_index.
  1368         _writer_bits::writeToken(*_os, _node_index.
  1369 				 find(_graph.u(e))->second);
  1369                                  find(_graph.u(e))->second);
  1370 	*_os << '\t';
  1370         *_os << '\t';
  1371 	_writer_bits::writeToken(*_os, _node_index.
  1371         _writer_bits::writeToken(*_os, _node_index.
  1372 				 find(_graph.v(e))->second);
  1372                                  find(_graph.v(e))->second);
  1373 	*_os << '\t';
  1373         *_os << '\t';
  1374 	if (label == 0) {
  1374         if (label == 0) {
  1375 	  std::ostringstream os;
  1375           std::ostringstream os;
  1376 	  os << _graph.id(e);
  1376           os << _graph.id(e);
  1377 	  _writer_bits::writeToken(*_os, os.str());
  1377           _writer_bits::writeToken(*_os, os.str());
  1378 	  *_os << '\t';
  1378           *_os << '\t';
  1379 	  _edge_index.insert(std::make_pair(e, os.str()));
  1379           _edge_index.insert(std::make_pair(e, os.str()));
  1380 	}
  1380         }
  1381 	for (typename EdgeMaps::iterator it = _edge_maps.begin();
  1381         for (typename EdgeMaps::iterator it = _edge_maps.begin();
  1382 	     it != _edge_maps.end(); ++it) {
  1382              it != _edge_maps.end(); ++it) {
  1383 	  std::string value = it->second->get(e);
  1383           std::string value = it->second->get(e);
  1384 	  _writer_bits::writeToken(*_os, value);
  1384           _writer_bits::writeToken(*_os, value);
  1385 	  if (it->first == "label") {
  1385           if (it->first == "label") {
  1386 	    _edge_index.insert(std::make_pair(e, value));
  1386             _edge_index.insert(std::make_pair(e, value));
  1387 	  }
  1387           }
  1388 	  *_os << '\t';
  1388           *_os << '\t';
  1389 	}
  1389         }
  1390 	*_os << std::endl;
  1390         *_os << std::endl;
  1391       }
  1391       }
  1392     }
  1392     }
  1393 
  1393 
  1394     void createEdgeIndex() {
  1394     void createEdgeIndex() {
  1395       _writer_bits::MapStorageBase<Edge>* label = 0;
  1395       _writer_bits::MapStorageBase<Edge>* label = 0;
  1396       for (typename EdgeMaps::iterator it = _edge_maps.begin();
  1396       for (typename EdgeMaps::iterator it = _edge_maps.begin();
  1397 	   it != _edge_maps.end(); ++it) {
  1397            it != _edge_maps.end(); ++it) {
  1398         if (it->first == "label") {
  1398         if (it->first == "label") {
  1399 	  label = it->second;
  1399           label = it->second;
  1400 	  break;
  1400           break;
  1401 	}
  1401         }
  1402       }
  1402       }
  1403 
  1403 
  1404       if (label == 0) {
  1404       if (label == 0) {
  1405 	for (EdgeIt e(_graph); e != INVALID; ++e) {
  1405         for (EdgeIt e(_graph); e != INVALID; ++e) {
  1406 	  std::ostringstream os;
  1406           std::ostringstream os;
  1407 	  os << _graph.id(e);
  1407           os << _graph.id(e);
  1408 	  _edge_index.insert(std::make_pair(e, os.str()));	  
  1408           _edge_index.insert(std::make_pair(e, os.str()));
  1409 	}	
  1409         }
  1410       } else {
  1410       } else {
  1411 	for (EdgeIt e(_graph); e != INVALID; ++e) {
  1411         for (EdgeIt e(_graph); e != INVALID; ++e) {
  1412 	  std::string value = label->get(e);	  
  1412           std::string value = label->get(e);
  1413 	  _edge_index.insert(std::make_pair(e, value));
  1413           _edge_index.insert(std::make_pair(e, value));
  1414 	}
  1414         }
  1415       }
  1415       }
  1416     }
  1416     }
  1417 
  1417 
  1418     void writeAttributes() {
  1418     void writeAttributes() {
  1419       if (_attributes.empty()) return;
  1419       if (_attributes.empty()) return;
  1420       *_os << "@attributes";
  1420       *_os << "@attributes";
  1421       if (!_attributes_caption.empty()) {
  1421       if (!_attributes_caption.empty()) {
  1422 	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
  1422         _writer_bits::writeToken(*_os << ' ', _attributes_caption);
  1423       }
  1423       }
  1424       *_os << std::endl;
  1424       *_os << std::endl;
  1425       for (typename Attributes::iterator it = _attributes.begin();
  1425       for (typename Attributes::iterator it = _attributes.begin();
  1426 	   it != _attributes.end(); ++it) {
  1426            it != _attributes.end(); ++it) {
  1427 	_writer_bits::writeToken(*_os, it->first) << ' ';
  1427         _writer_bits::writeToken(*_os, it->first) << ' ';
  1428 	_writer_bits::writeToken(*_os, it->second->get());
  1428         _writer_bits::writeToken(*_os, it->second->get());
  1429 	*_os << std::endl;
  1429         *_os << std::endl;
  1430       }
  1430       }
  1431     }
  1431     }
  1432     
  1432 
  1433   public:
  1433   public:
  1434     
  1434 
  1435     /// \name Execution of the writer    
  1435     /// \name Execution of the writer
  1436     /// @{
  1436     /// @{
  1437 
  1437 
  1438     /// \brief Start the batch processing
  1438     /// \brief Start the batch processing
  1439     ///
  1439     ///
  1440     /// This function starts the batch processing.
  1440     /// This function starts the batch processing.
  1441     void run() {
  1441     void run() {
  1442       if (!_skip_nodes) {
  1442       if (!_skip_nodes) {
  1443 	writeNodes();
  1443         writeNodes();
  1444       } else {
  1444       } else {
  1445 	createNodeIndex();
  1445         createNodeIndex();
  1446       }
  1446       }
  1447       if (!_skip_edges) {      
  1447       if (!_skip_edges) {
  1448 	writeEdges();
  1448         writeEdges();
  1449       } else {
  1449       } else {
  1450 	createEdgeIndex();
  1450         createEdgeIndex();
  1451       }
  1451       }
  1452       writeAttributes();
  1452       writeAttributes();
  1453     }
  1453     }
  1454 
  1454 
  1455     /// \brief Give back the stream of the writer
  1455     /// \brief Give back the stream of the writer
  1461 
  1461 
  1462     /// @}
  1462     /// @}
  1463   };
  1463   };
  1464 
  1464 
  1465   /// \brief Return a \ref GraphWriter class
  1465   /// \brief Return a \ref GraphWriter class
  1466   /// 
  1466   ///
  1467   /// This function just returns a \ref GraphWriter class.
  1467   /// This function just returns a \ref GraphWriter class.
  1468   /// \relates GraphWriter
  1468   /// \relates GraphWriter
  1469   template <typename Graph>
  1469   template <typename Graph>
  1470   GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
  1470   GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
  1471     GraphWriter<Graph> tmp(os, graph);
  1471     GraphWriter<Graph> tmp(os, graph);
  1472     return tmp;
  1472     return tmp;
  1473   }
  1473   }
  1474 
  1474 
  1475   /// \brief Return a \ref GraphWriter class
  1475   /// \brief Return a \ref GraphWriter class
  1476   /// 
  1476   ///
  1477   /// This function just returns a \ref GraphWriter class.
  1477   /// This function just returns a \ref GraphWriter class.
  1478   /// \relates GraphWriter
  1478   /// \relates GraphWriter
  1479   template <typename Graph>
  1479   template <typename Graph>
  1480   GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
  1480   GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
  1481     GraphWriter<Graph> tmp(fn, graph);
  1481     GraphWriter<Graph> tmp(fn, graph);
  1482     return tmp;
  1482     return tmp;
  1483   }
  1483   }
  1484 
  1484 
  1485   /// \brief Return a \ref GraphWriter class
  1485   /// \brief Return a \ref GraphWriter class
  1486   /// 
  1486   ///
  1487   /// This function just returns a \ref GraphWriter class.
  1487   /// This function just returns a \ref GraphWriter class.
  1488   /// \relates GraphWriter
  1488   /// \relates GraphWriter
  1489   template <typename Graph>
  1489   template <typename Graph>
  1490   GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
  1490   GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
  1491     GraphWriter<Graph> tmp(fn, graph);
  1491     GraphWriter<Graph> tmp(fn, graph);