COIN-OR::LEMON - Graph Library

Ticket #35: lgf_io.hg

File lgf_io.hg, 71.4 KB (added by Balazs Dezso, 17 years ago)

Preliminary version of redesigned IO

Line 
1# HG changeset patch
2# User Balazs Dezso <deba@inf.elte.hu>
3# Date 1207815600 -7200
4# Node ID 988226bc5e6c092db643ebcb020e0a9e38f08dd0
5# Parent  b6bede534255e492871c601771442b65e12f7319
6Redesign lgf related tools
7
8diff -r b6bede534255 -r 988226bc5e6c demo/Makefile.am
9--- a/demo/Makefile.am  Thu Apr 03 13:00:18 2008 +0100
10+++ b/demo/Makefile.am  Thu Apr 10 10:20:00 2008 +0200
11@@ -4,9 +4,11 @@ if WANT_DEMO
12 if WANT_DEMO
13 
14 noinst_PROGRAMS += \
15-        demo/arg_parser_demo
16+        demo/arg_parser_demo \
17+       demo/lgf_demo
18 
19 endif WANT_DEMO
20 
21 demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc
22+demo_lgf_demo_SOURCES = demo/lgf_demo.cc
23 
24diff -r b6bede534255 -r 988226bc5e6c demo/lgf_demo.cc
25--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
26+++ b/demo/lgf_demo.cc  Thu Apr 10 10:20:00 2008 +0200
27@@ -0,0 +1,125 @@
28+/* -*- C++ -*-
29+ *
30+ * This file is a part of LEMON, a generic C++ optimization library
31+ *
32+ * Copyright (C) 2003-2008
33+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
34+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
35+ *
36+ * Permission to use, modify and distribute this software is granted
37+ * provided that this copyright notice appears in all copies. For
38+ * precise terms see the accompanying LICENSE file.
39+ *
40+ * This software is provided "AS IS" with no warranty of any kind,
41+ * express or implied, and with no claim as to its suitability for any
42+ * purpose.
43+ *
44+ */
45+
46+///\ingroup demos
47+///\file
48+///\brief Demonstrating graph input and output
49+///
50+/// This simple demo program gives an example of how to read and write
51+/// a graph and additional maps (on the nodes or the edges) from/to a
52+/// stream.
53+///
54+/// \include reader_writer_demo.cc
55+
56+#include <iostream>
57+#include <lemon/smart_graph.h>
58+#include <lemon/lgf_reader.h>
59+#include <lemon/lgf_writer.h>
60+#include <lemon/random.h>
61+
62+
63+using namespace lemon;
64+
65+int main(int argc, const char *argv[]) {
66+  SmartDigraph digraph;
67+
68+  std::stringstream ss;
69+
70+  try {
71+
72+    typedef SmartDigraph Digraph;
73+    typedef Digraph::Node Node;
74+    typedef Digraph::Arc Arc;
75+    typedef Digraph::ArcIt ArcIt;
76+
77+    typedef Digraph::ArcMap<int> CapacityMap;
78+    typedef Digraph::ArcMap<std::string> NameMap;
79+
80+    const int n = argc > 1 ? std::atoi(argv[1]) : 20;
81+    const int e = argc > 2 ? std::atoi(argv[2]) : static_cast<int>(n * log(n));
82+    const int m = argc > 3 ? std::atoi(argv[3]) : 100;
83+
84+    Digraph digraph;
85+    CapacityMap capacity(digraph);
86+    NameMap name(digraph);
87+
88+    std::vector<Node> nodes;
89+
90+    for (int i = 0; i < n; ++i) {
91+      nodes.push_back(digraph.addNode());
92+    }
93+    for (int i = 0; i < e; ++i) {
94+      int s = rnd[n];
95+      int t = rnd[n];
96+      int c = rnd[m];
97+      Arc arc = digraph.addArc(nodes[s], nodes[t]);
98+      capacity[arc] = c;
99+      std::ostringstream os;
100+      os << "arc \t" << i << std::endl;
101+      name[arc] = os.str();
102+    }
103+
104+
105+    DigraphWriter<Digraph>(ss, digraph).
106+      arcMap("capacity", capacity).
107+      arcMap("name", name).
108+      node("source", nodes[0]).
109+      node("target", nodes[1]).
110+      run();
111+
112+  } catch (DataFormatError& error) {
113+    std::cerr << error.what() << std::endl;
114+  }
115+
116+  try {
117+
118+    typedef SmartDigraph Digraph;
119+    typedef Digraph::Node Node;
120+    typedef Digraph::Arc Arc;
121+    typedef Digraph::ArcIt ArcIt;
122+
123+    typedef Digraph::ArcMap<int> CapacityMap;
124+    typedef Digraph::ArcMap<std::string> NameMap;
125+
126+    Digraph digraph;
127+    CapacityMap capacity(digraph);
128+    NameMap name(digraph);
129+
130+    Node s, t;
131+
132+    DigraphReader<Digraph>(ss, digraph).
133+      arcMap("capacity", capacity).
134+      arcMap("name", name).
135+      node("source", s).
136+      node("target", t).
137+      run();
138+
139+    DigraphWriter<Digraph>(std::cout, digraph).
140+      arcMap("capacity", capacity).
141+      arcMap("name", name).
142+      node("source", s).
143+      node("target", t).
144+      run();
145+
146+  } catch (DataFormatError& error) {
147+    std::cerr << error.what() << std::endl;
148+  }
149+
150+
151+  return 0;
152+}
153diff -r b6bede534255 -r 988226bc5e6c lemon/Makefile.am
154--- a/lemon/Makefile.am Thu Apr 03 13:00:18 2008 +0100
155+++ b/lemon/Makefile.am Thu Apr 10 10:20:00 2008 +0200
156@@ -26,6 +26,7 @@ lemon_HEADERS += \
157        lemon/error.h \
158        lemon/graph_utils.h \
159        lemon/kruskal.h \
160+       lemon/lgf_reader.h \
161        lemon/list_graph.h \
162        lemon/maps.h \
163        lemon/math.h \
164diff -r b6bede534255 -r 988226bc5e6c lemon/lgf_reader.h
165--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
166+++ b/lemon/lgf_reader.h        Thu Apr 10 10:20:00 2008 +0200
167@@ -0,0 +1,866 @@
168+/* -*- C++ -*-
169+ *
170+ * This file is a part of LEMON, a generic C++ optimization library
171+ *
172+ * Copyright (C) 2003-2008
173+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
174+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
175+ *
176+ * Permission to use, modify and distribute this software is granted
177+ * provided that this copyright notice appears in all copies. For
178+ * precise terms see the accompanying LICENSE file.
179+ *
180+ * This software is provided "AS IS" with no warranty of any kind,
181+ * express or implied, and with no claim as to its suitability for any
182+ * purpose.
183+ *
184+ */
185+
186+///\ingroup lemon_io
187+///\file
188+///\brief Lemon Graph Format reader.
189+
190+
191+#ifndef LEMON_LGF_READER_H
192+#define LEMON_LGF_READER_H
193+
194+#include <iostream>
195+#include <fstream>
196+#include <sstream>
197+
198+#include <map>
199+#include <typeinfo>
200+
201+#include <lemon/assert.h>
202+#include <lemon/graph_utils.h>
203+
204+namespace lemon {
205+
206+  namespace _reader_bits {
207+
208+    template <typename Value>
209+    struct DefaultConverter {
210+      Value operator()(const std::string& str) {
211+       std::istringstream is(str);
212+       Value value;
213+       is >> value;
214+
215+       char c;
216+       if (is >> std::ws >> c) {
217+         throw DataFormatError("Remaining characters in token");
218+       }
219+       return value;
220+      }
221+    };
222+
223+    template <>
224+    struct DefaultConverter<std::string> {
225+      std::string operator()(const std::string& str) {
226+       return str;
227+      }
228+    };
229+
230+    template <typename _Item>   
231+    class MapStorageBase {
232+    public:
233+      typedef _Item Item;
234+
235+    private:     
236+      bool _touched;
237+
238+    public:
239+      MapStorageBase() : _touched(false) {}
240+      virtual ~MapStorageBase() {}
241+
242+      void touch(bool value = true) { _touched = value; }
243+      bool touched() const { return _touched; }
244+
245+      virtual void set(const Item& item, const std::string& value) = 0;
246+
247+    };
248+
249+    template <typename _Item, typename _Map,
250+             typename _Converter = DefaultConverter<typename _Map::Value> >
251+    class MapStorage : public MapStorageBase<_Item> {
252+    public:
253+      typedef _Map Map;
254+      typedef _Converter Converter;
255+      typedef _Item Item;
256+     
257+    private:
258+      Map& _map;
259+      Converter _converter;
260+
261+    public:
262+      MapStorage(Map& map, const Converter& converter = Converter())
263+       : _map(map), _converter(converter) {}
264+      virtual ~MapStorage() {}
265+
266+      virtual void set(const Item& item ,const std::string& value) {
267+       _map.set(item, _converter(value));
268+      }
269+    };
270+
271+    class ValueStorageBase {
272+    private:
273+      bool _touched;
274+
275+    public:
276+      ValueStorageBase() : _touched(false) {}
277+      virtual ~ValueStorageBase() {}
278+
279+      void touch() { _touched = true; }
280+      bool touched() const { return _touched; }
281+
282+      virtual void set(const std::string&) = 0;
283+    };
284+
285+    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
286+    class ValueStorage : public ValueStorageBase {
287+    public:
288+      typedef _Value Value;
289+      typedef _Converter Converter;
290+
291+    private:
292+      Value& _value;
293+      Converter _converter;
294+
295+    public:
296+      ValueStorage(Value& value, const Converter& converter = Converter())
297+       : _value(value), _converter(converter) {}
298+
299+      virtual void set(const std::string& value) {
300+       _value = _converter(value);
301+      }
302+    };
303+
304+
305+    class FilterStreamBuf : public std::streambuf {
306+    public:
307+
308+      typedef std::streambuf Parent;
309+      typedef Parent::char_type char_type;
310+      FilterStreamBuf(std::istream& is, int& num)
311+       : _is(is), _base(0), _eptr(0),
312+         _num(num), skip_state(after_endl) {}
313+
314+    protected:
315+
316+      enum skip_state_type {
317+       no_skip,
318+       after_endl,
319+       comment_line
320+      };
321+
322+      char_type small_buf[1];
323+
324+
325+      std::istream& _is;
326+
327+      char_type* _base;
328+      char_type* _eptr;
329+
330+      int& _num;
331+
332+      skip_state_type skip_state;
333+
334+
335+      char_type* base() { return _base; }
336+      char_type* eptr() { return _eptr; }
337+      int_type blen() { return _eptr - _base; }
338+
339+      void setb(char_type* buf, int_type len) {
340+       _base = buf;
341+       _eptr = buf + len;
342+      }
343
344+      virtual std::streambuf* setbuf(char *buf, std::streamsize len) {
345+       if (base()) return 0;
346+       if (buf != 0 && len >= int(sizeof(small_buf))) {
347+         setb(buf, len);
348+       } else {
349+         setb(small_buf, sizeof(small_buf));
350+       }
351+       setg(0, 0, 0);
352+       return this;
353+      }
354+
355+      bool put_char(char c) {
356+       switch (skip_state) {
357+       case no_skip:
358+         switch (c) {
359+         case '\n':
360+           skip_state = after_endl;
361+           return true;
362+         default:
363+           return true;
364+         }
365+       case after_endl:
366+         switch (c) {
367+         case '@':
368+           return false;
369+         case '\n':
370+           return false;
371+         case '#':
372+           skip_state = comment_line;
373+           return false;
374+         default:
375+           if (!isspace(c)) {
376+             skip_state = no_skip;
377+             return true;
378+           } else {
379+             return false;
380+           }
381+         }
382+         break;
383+       case comment_line:
384+         switch (c) {
385+         case '\n':
386+           skip_state = after_endl;
387+           return false;
388+         default:
389+           return false;
390+         }
391+       }
392+       return false;
393+      }
394+
395+      virtual int_type underflow() {
396+       char c;
397+       if ((c = _is.peek()) != EOF) {
398+         if (c == '@') {
399+           return EOF;
400+         }
401+       } else {
402+         return EOF;
403+       }
404+       char_type *ptr;
405+       for (ptr = base(); ptr != eptr(); ++ptr) {
406+         if ((c = _is.get()) != EOF) {
407+           if (c == '\n') ++_num;
408+           if (put_char(c)) {
409+             *ptr = c;
410+           } else {
411+             if (skip_state == after_endl && c == '@') {
412+               _is.putback(c);
413+               break;
414+             }
415+             --ptr;
416+           }
417+         } else {
418+           break;
419+         }
420+       }
421+       setg(base(), base(), ptr);
422+       return *base();
423+      }
424+
425+      virtual int_type sync() {
426+       return EOF;
427+      }
428+
429+    public:
430+
431+      int line_num() const {
432+       int r = _num;
433+       for (char_type* p = gptr(); p != egptr(); ++p) {
434+         if (*p == '\n') --r;
435+       }
436+       return r;
437+      }
438+
439+    };
440+
441+    template <typename Value>
442+    struct MapLookUpConverter {
443+      const std::map<std::string, Value>& _map;
444+     
445+      MapLookUpConverter(const std::map<std::string, Value>& map)
446+       : _map(map) {}
447+     
448+      Value operator()(const std::string& str) {
449+       typename std::map<std::string, Value>::const_iterator it =
450+         _map.find(str);
451+
452+       if (it == _map.end()) {
453+         std::ostringstream msg;
454+         msg << "Item not found: " << str;
455+         throw DataFormatError(msg.str().c_str());
456+       }
457+       return it->second;
458+      }
459+    };
460+
461+    bool isWhiteSpace(char c) {
462+      return c == ' ' || c == '\t' || c == '\v' ||
463+        c == '\n' || c == '\r' || c == '\f';
464+    }
465+   
466+    bool isOct(char c) {
467+      return '0' <= c && c <='7';
468+    }
469+   
470+    int valueOct(char c) {
471+      LEMON_ASSERT(isOct(c), "The character is not octal.");
472+      return c - '0';
473+    }
474+
475+    bool isHex(char c) {
476+      return ('0' <= c && c <= '9') ||
477+       ('a' <= c && c <= 'z') ||
478+       ('A' <= c && c <= 'Z');
479+    }
480+   
481+    int valueHex(char c) {
482+      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
483+      if ('0' <= c && c <= '9') return c - '0';
484+      if ('a' <= c && c <= 'z') return c - 'a' + 10;
485+      return c - 'A' + 10;
486+    }
487+
488+    char readEscape(std::istream& is) {
489+      char c;
490+      if (!is.get(c))
491+       throw DataFormatError("Escape format error");
492+
493+      switch (c) {
494+      case '\\':
495+       return '\\';
496+      case '\"':
497+       return '\"';
498+      case '\'':
499+       return '\'';
500+      case '\?':
501+       return '\?';
502+      case 'a':
503+       return '\a';
504+      case 'b':
505+       return '\b';
506+      case 'f':
507+       return '\f';
508+      case 'n':
509+       return '\n';
510+      case 'r':
511+       return '\r';
512+      case 't':
513+       return '\t';
514+      case 'v':
515+       return '\v';
516+      case 'x':
517+       {
518+         int code;
519+         if (!is.get(c) || !isHex(c))
520+           throw DataFormatError("Escape format error");
521+         else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
522+         else code = code * 16 + valueHex(c);
523+         return code;
524+       }
525+      default:
526+       {
527+         int code;
528+         if (!isOct(c))
529+           throw DataFormatError("Escape format error");
530+         else if (code = valueOct(c), !is.get(c) || !isOct(c))
531+           is.putback(c);
532+         else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
533+           is.putback(c);
534+         else code = code * 8 + valueOct(c);
535+         return code;
536+       }             
537+      }
538+    }
539+
540+
541+    std::istream& readToken(std::istream& is, std::string& str) {
542+      std::ostringstream os;
543+
544+      char c;
545+      is >> std::ws;
546+     
547+      if (!is.get(c))
548+       throw DataFormatError("Token not found");
549+
550+      if (c == '\"') {
551+       while (is.get(c) && c != '\"') {
552+         if (c == '\\')
553+           c = readEscape(is);
554+         os << c;
555+       }
556+       if (!is)
557+         throw DataFormatError("Quoted format error");
558+      } else {
559+       is.putback(c);
560+       while (is.get(c) && !isWhiteSpace(c)) {
561+         if (c == '\\')
562+           c = readEscape(is);
563+         os << c;
564+       }
565+       if (!is) {
566+         is.setstate(std::ios_base::goodbit);
567+       } else {
568+         is.putback(c);
569+       }
570+      }
571+      str = os.str();
572+      return is;
573+    }
574+
575+  }
576
577+  /// \e
578+  template <typename _Digraph>
579+  class DigraphReader {
580+  public:
581+
582+    typedef _Digraph Digraph;
583+    GRAPH_TYPEDEFS(typename Digraph);
584+   
585+  private:
586+
587+
588+    std::istream* _is;
589+    bool local_is;
590+
591+    Digraph& _digraph;
592+
593+    std::string _node_set_caption;
594+    std::string _arc_set_caption;
595+    std::string _attributes_caption;
596+
597+    typedef std::map<std::string, Node> NodeIndex;
598+    NodeIndex _node_index;
599+    typedef std::map<std::string, Arc> ArcIndex;
600+    ArcIndex _arc_index;
601+   
602+    typedef std::multimap<std::string, _reader_bits::MapStorageBase<Node>* >
603+      NodeMaps;   
604+    NodeMaps _node_maps;
605+
606+    typedef std::multimap<std::string, _reader_bits::MapStorageBase<Arc>* >
607+      ArcMaps;
608+    ArcMaps _arc_maps;
609+
610+    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
611+      Attributes;
612+    Attributes _attributes;
613+
614+  public:
615+
616+    /// \e
617+    DigraphReader(std::istream& is, Digraph& digraph)
618+      : _is(&is), local_is(false), _digraph(digraph) {}
619+
620+    /// \e
621+    DigraphReader(const std::string& fn, Digraph& digraph)
622+      : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph) {}
623+
624+    /// \e
625+    DigraphReader(const char* fn, Digraph& digraph)
626+      : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph) {}
627+
628+    DigraphReader(DigraphReader& other)
629+      : _is(other._is), local_is(other.local_is), _digraph(other._digraph) {
630+
631+      other.is = 0;
632+      other.local_is = false;
633+
634+      _node_index.swap(other._node_index);
635+      _arc_index.swap(other._arc_index);
636+
637+      _node_maps.swap(other._node_maps);
638+      _arc_maps.swap(other._arc_maps);
639+      _attributes.swap(other._attributes);
640+
641+      _node_set_caption = other._node_set_caption;
642+      _arc_set_caption = other._arc_set_caption;
643+      _attributes_caption = other._attributes_caption;
644+    }
645+
646+    /// \e
647+    ~DigraphReader() {
648+      for (typename NodeMaps::iterator it = _node_maps.begin();
649+          it != _node_maps.end(); ++it) {
650+       delete it->second;
651+      }
652+
653+      for (typename ArcMaps::iterator it = _arc_maps.begin();
654+          it != _arc_maps.end(); ++it) {
655+       delete it->second;
656+      }
657+
658+      for (typename Attributes::iterator it = _attributes.begin();
659+          it != _attributes.end(); ++it) {
660+       delete it->second;
661+      }
662+
663+      if (local_is) {
664+       delete _is;
665+      }
666+    }
667+
668+  private:
669+   
670+    DigraphReader& operator=(const DigraphReader&);
671+
672+  public:
673+
674+    /// \e
675+    template <typename Map>
676+    DigraphReader& nodeMap(const std::string& caption, Map& map) {
677+      _reader_bits::MapStorageBase<Node>* storage =
678+       new _reader_bits::MapStorage<Node, Map>(map);
679+      _node_maps.insert(std::make_pair(caption, storage));
680+      return *this;
681+    }
682+
683+    /// \e
684+    template <typename Map, typename Converter>
685+    DigraphReader& nodeMap(const std::string& caption, Map& map,
686+                          const Converter& converter = Converter()) {
687+      _reader_bits::MapStorageBase<Node>* storage =
688+       new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
689+      _node_maps.insert(std::make_pair(caption, storage));
690+      return *this;
691+    }
692+
693+    /// \e
694+    template <typename Map>
695+    DigraphReader& arcMap(const std::string& caption, Map& map) {
696+      _reader_bits::MapStorageBase<Arc>* storage =
697+       new _reader_bits::MapStorage<Arc, Map>(map);
698+      _arc_maps.insert(std::make_pair(caption, storage));
699+      return *this;
700+    }
701+
702+    /// \e
703+    template <typename Map, typename Converter>
704+    DigraphReader& arcMap(const std::string& caption, Map& map,
705+                         const Converter& converter = Converter()) {
706+      _reader_bits::MapStorageBase<Arc>* storage =
707+       new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
708+      _arc_maps.insert(std::make_pair(caption, storage));
709+      return *this;
710+    }
711+
712+    /// \e
713+    template <typename Value>
714+    DigraphReader& attribute(const std::string& caption, Value& value) {
715+      _reader_bits::ValueStorageBase* storage =
716+       new _reader_bits::ValueStorage<Value>(value);
717+      _attributes.insert(std::make_pair(caption, storage));
718+      return *this;
719+    }
720+
721+    /// \e
722+    template <typename Value, typename Converter>
723+    DigraphReader& attribute(const std::string& caption, Value& value,
724+                            const Converter& converter = Converter()) {
725+      _reader_bits::ValueStorageBase* storage =
726+       new _reader_bits::ValueStorage<Value, Converter>(value, converter);
727+      _attributes.insert(std::make_pair(caption, storage));
728+      return *this;
729+    }
730+
731+    /// \e
732+    DigraphReader& node(const std::string& caption, Node& node) {
733+      typedef _reader_bits::MapLookUpConverter<Node> Converter;
734+      Converter converter(_node_index);
735+      _reader_bits::ValueStorageBase* storage =
736+       new _reader_bits::ValueStorage<Node, Converter>(node, converter);
737+      _attributes.insert(std::make_pair(caption, storage));
738+      return *this;
739+    }
740+
741+    /// \e
742+    DigraphReader& arc(const std::string& caption, Arc& arc) {
743+      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
744+      Converter converter(_arc_index);
745+      _reader_bits::ValueStorageBase* storage =
746+       new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
747+      _attributes.insert(std::make_pair(caption, storage));
748+      return *this;
749+    }
750+
751+    /// \e
752+    DigraphReader& nodeSet(const std::string& caption) {
753+      _node_set_caption = caption;
754+      return *this;
755+    }
756+
757+    /// \e
758+    DigraphReader& arcSet(const std::string& caption) {
759+      _arc_set_caption = caption;
760+      return *this;
761+    }
762+
763+    /// \e
764+    DigraphReader& attributes(const std::string& caption) {
765+      _attributes_caption = caption;
766+      return *this;
767+    }
768+
769+  private:
770+   
771+
772+    static void skipSection(std::istream& is, int& line_num) {
773+      enum skip_state_type { skip, after_endl };
774+
775+      skip_state_type skip_state = after_endl;
776+      char c;
777+     
778+      while ((c = is.get()) != EOF) {
779+       if (c == '\n') ++line_num;
780+
781+       switch (skip_state) {
782+       case skip:
783+         if (c == '\n') skip_state = after_endl;
784+         break;
785+       case after_endl:
786+         switch (c) {
787+         case '@':
788+           is.putback(c);
789+           return;
790+         case '\n':
791+           continue;
792+         default:
793+           if (!isspace(c)) {
794+             skip_state = skip;
795+           }
796+           break;
797+         }
798+       }       
799+      }
800+    }
801+
802+    void readNodeSet(std::istream& is) {
803+
804+      std::vector<std::string> maps;
805+      std::string line;
806+
807+      {
808+       std::getline(is, line);
809+        std::istringstream ls(line);
810+
811+       std::string map;
812+       while (ls >> map) {
813+         maps.push_back(map);
814+
815+         typename NodeMaps::iterator it = _node_maps.lower_bound(map);
816+         while (it != _node_maps.end() && it->first == map) {
817+           it->second->touch();
818+           ++it;
819+         }
820+       }
821+
822+       for (typename NodeMaps::iterator it = _node_maps.begin();
823+            it != _node_maps.end(); ++it) {
824+         if (!it->second->touched()) {
825+           ErrorMessage msg;
826+           msg << "Map not found in file: " << it->first;
827+           throw IoParameterError(msg.message());
828+         }
829+       }
830+      }
831+     
832+      while (getline(is, line)) {
833+       Node n = _digraph.addNode();
834+
835+       std::istringstream ls(line);
836+       for (int i = 0; i < static_cast<int>(maps.size()); ++i) {
837+         std::string token;
838+         _reader_bits::readToken(ls, token);
839+         
840+         typename NodeMaps::iterator it = _node_maps.lower_bound(maps[i]);
841+         while (it != _node_maps.end() && it->first == maps[i]) {
842+           it->second->set(n, token);
843+           ++it;
844+         }
845+         
846+         if (maps[i] == "label") {
847+           _node_index[token] = n;
848+         }
849+       }
850+      }
851+    }
852+
853+    void readArcSet(std::istream& is) {
854+
855+      std::vector<std::string> maps;
856+      std::string line;
857+
858+      {
859+       
860+       std::getline(is, line);
861+        std::istringstream ls(line);
862+
863+       std::string map;
864+       while (ls >> map) {
865+         maps.push_back(map);
866+
867+         typename ArcMaps::iterator it = _arc_maps.lower_bound(map);
868+         while (it != _arc_maps.end() && it->first == map) {
869+           it->second->touch();
870+           ++it;
871+         }
872+       }
873+
874+       for (typename ArcMaps::iterator it = _arc_maps.begin();
875+            it != _arc_maps.end(); ++it) {
876+         if (!it->second->touched()) {
877+           ErrorMessage msg;
878+           msg << "Map not found in file: " << it->first;
879+           throw IoParameterError(msg.message());
880+         }
881+       }
882+      }
883+     
884+      while (getline(is, line)) {
885+       std::istringstream ls(line);
886+
887+       Node s, t;
888+       {
889+         std::string token;
890+         typename NodeIndex::iterator it;
891+         
892+         _reader_bits::readToken(ls, token);
893+         it = _node_index.find(token);
894+         if (it == _node_index.end()) {
895+           std::ostringstream msg;
896+           msg << "Item not found: " << token;
897+           throw DataFormatError(msg.str().c_str());
898+         }
899+         s = it->second;
900+
901+         _reader_bits::readToken(ls, token);
902+         it = _node_index.find(token);
903+         if (it == _node_index.end()) {
904+           std::ostringstream msg;
905+           msg << "Item not found: " << token;
906+           throw DataFormatError(msg.str().c_str());
907+         }
908+         t = it->second;
909+       }
910+
911+       Arc a = _digraph.addArc(s, t);
912+
913+       for (int i = 0; i < static_cast<int>(maps.size()); ++i) {
914+         std::string token;
915+         _reader_bits::readToken(ls, token);
916+         
917+         typename ArcMaps::iterator it = _arc_maps.lower_bound(maps[i]);
918+         while (it != _arc_maps.end() && it->first == maps[i]) {
919+           it->second->set(a, token);
920+           ++it;
921+         }
922+         
923+         if (maps[i] == "label") {
924+           _arc_index[token] = a;
925+         }
926+       }
927+      }
928+    }
929+
930+    void readAttributes(std::istream& is) {
931+
932+      std::vector<std::string> maps;
933+      std::string line;
934+
935+      while (std::getline(is, line)) {
936+
937+        std::istringstream ls(line);
938+
939+       std::string attr, token;
940+
941+       ls >> attr;
942+       _reader_bits::readToken(ls, token);
943+       
944+       typename Attributes::iterator it = _attributes.lower_bound(attr);
945+       while (it != _attributes.end() && it->first == attr) {
946+         it->second->set(token);
947+         it->second->touch();
948+         ++it;
949+       }
950+      }
951+      for (typename Attributes::iterator it = _attributes.begin();
952+          it != _attributes.end(); ++it) {
953+       if (!it->second->touched()) {
954+         ErrorMessage msg;
955+         msg << "Attribute not found in file: " << it->first;
956+         throw IoParameterError(msg.message());
957+       }       
958+      }
959+    }
960+
961+  public:
962+   
963+    /// \e
964+    void run() {
965+      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
966+     
967+      bool node_set_done = false;
968+      bool arc_set_done = false;
969+      bool attributes_done = false;
970+     
971+      int line_num = 0;
972+      std::string line;
973+     
974+      skipSection(*_is, line_num);
975+
976+      while (++line_num, getline(*_is, line)) {
977+       char buf[2048];
978+       _reader_bits::FilterStreamBuf buffer(*_is, line_num);
979+       try {
980+         buffer.pubsetbuf(buf, sizeof(buf));
981+         std::istream fs(&buffer);
982+         
983+         std::istringstream ls(line);
984+         std::string section, caption;
985+         ls >> section >> caption;
986+
987+         if (section == "@nodeset" && !node_set_done) {
988+           if (_node_set_caption.empty() || _node_set_caption == caption) {
989+             readNodeSet(fs);
990+             node_set_done = true;
991+           }
992+         } else if ((section == "@arcset" || section == "@edgeset") &&
993+                    !arc_set_done) {
994+           if (_arc_set_caption.empty() || _arc_set_caption == caption) {
995+             readArcSet(fs);
996+             arc_set_done = true;
997+           }
998+         } else if (section == "@attributes" && !attributes_done) {
999+           if (_attributes_caption.empty() || _attributes_caption == caption) {
1000+             readAttributes(fs);
1001+             attributes_done = true;
1002+           }
1003+         }
1004+         
1005+         skipSection(*_is, line_num);
1006+       } catch (DataFormatError& error) {
1007+         error.line(buffer.line_num());
1008+         throw;
1009+       }       
1010+      }       
1011+
1012+    }
1013+   
1014+  };
1015+
1016+  template <typename Digraph>
1017+  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1018+    return DigraphReader<Digraph>(is, digraph);
1019+  }
1020+
1021+  template <typename Digraph>
1022+  DigraphReader<Digraph> digraphReader(const std::string& fn,
1023+                                      Digraph& digraph) {
1024+    return DigraphReader<Digraph>(fn, digraph);
1025+  }
1026+
1027+  template <typename Digraph>
1028+  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1029+    return DigraphReader<Digraph>(fn, digraph);
1030+  }
1031+}
1032+
1033+#endif
1034diff -r b6bede534255 -r 988226bc5e6c lemon/lgf_writer.h
1035--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1036+++ b/lemon/lgf_writer.h        Thu Apr 10 10:20:00 2008 +0200
1037@@ -0,0 +1,542 @@
1038+/* -*- C++ -*-
1039+ *
1040+ * This file is a part of LEMON, a generic C++ optimization library
1041+ *
1042+ * Copyright (C) 2003-2008
1043+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1044+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
1045+ *
1046+ * Permission to use, modify and distribute this software is granted
1047+ * provided that this copyright notice appears in all copies. For
1048+ * precise terms see the accompanying LICENSE file.
1049+ *
1050+ * This software is provided "AS IS" with no warranty of any kind,
1051+ * express or implied, and with no claim as to its suitability for any
1052+ * purpose.
1053+ *
1054+ */
1055+
1056+///\ingroup lemon_io
1057+///\file
1058+///\brief Lemon Graph Format writer.
1059+
1060+
1061+#ifndef LEMON_LGF_WRITER_H
1062+#define LEMON_LGF_WRITER_H
1063+
1064+#include <iostream>
1065+#include <fstream>
1066+#include <sstream>
1067+
1068+#include <vector>
1069+#include <functional>
1070+
1071+#include <lemon/assert.h>
1072+#include <lemon/graph_utils.h>
1073+
1074+namespace lemon {
1075+
1076+  namespace _writer_bits {
1077+
1078+    template <typename Value>
1079+    struct DefaultConverter {
1080+      std::string operator()(const Value& value) {
1081+       std::ostringstream os;
1082+       os << value;
1083+       return os.str();
1084+      }
1085+    };
1086+
1087+    template <typename _Item>   
1088+    class MapStorageBase {
1089+    public:
1090+      typedef _Item Item;
1091+
1092+    public:
1093+      MapStorageBase() {}
1094+      virtual ~MapStorageBase() {}
1095+
1096+      virtual std::string get(const Item& item) = 0;
1097+
1098+    };
1099+
1100+    template <typename _Item, typename _Map,
1101+             typename _Converter = DefaultConverter<typename _Map::Value> >
1102+    class MapStorage : public MapStorageBase<_Item> {
1103+    public:
1104+      typedef _Map Map;
1105+      typedef _Converter Converter;
1106+      typedef _Item Item;
1107+     
1108+    private:
1109+      const Map& _map;
1110+      Converter _converter;
1111+
1112+    public:
1113+      MapStorage(const Map& map, const Converter& converter = Converter())
1114+       : _map(map), _converter(converter) {}
1115+      virtual ~MapStorage() {}
1116+
1117+      virtual std::string get(const Item& item) {
1118+       return _converter(_map[item]);
1119+      }
1120+    };
1121+
1122+    class ValueStorageBase {
1123+    public:
1124+      ValueStorageBase() {}
1125+      virtual ~ValueStorageBase() {}
1126+
1127+      virtual std::string get() = 0;
1128+    };
1129+
1130+    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
1131+    class ValueStorage : public ValueStorageBase {
1132+    public:
1133+      typedef _Value Value;
1134+      typedef _Converter Converter;
1135+
1136+    private:
1137+      const Value& _value;
1138+      Converter _converter;
1139+
1140+    public:
1141+      ValueStorage(const Value& value, const Converter& converter = Converter())
1142+       : _value(value), _converter(converter) {}
1143+
1144+      virtual std::string get() {
1145+       return _converter(_value);
1146+      }
1147+    };
1148+
1149+    template <typename Value>
1150+    struct MapLookUpConverter {
1151+      const std::map<Value, std::string>& _map;
1152+     
1153+      MapLookUpConverter(const std::map<Value, std::string>& map)
1154+       : _map(map) {}
1155+     
1156+      std::string operator()(const Value& str) {
1157+       typename std::map<Value, std::string>::const_iterator it =
1158+         _map.find(str);
1159+       if (it == _map.end()) {
1160+         std::ostringstream msg;
1161+         msg << "Item not found";
1162+         throw DataFormatError("Item not found");
1163+       }
1164+       return it->second;
1165+      }
1166+    };
1167+
1168+    bool isWhiteSpace(char c) {
1169+      return c == ' ' || c == '\t' || c == '\v' ||
1170+        c == '\n' || c == '\r' || c == '\f';
1171+    }
1172+
1173+    bool isEscaped(char c) {
1174+      return c == '\\' || c == '\"' || c == '\'' ||
1175+       c == '\a' || c == '\b';
1176+    }
1177+
1178+    static void writeEscape(std::ostream& os, char c) {
1179+      switch (c) {
1180+      case '\\':
1181+       os << "\\\\";
1182+       return;
1183+      case '\"':
1184+       os << "\\\"";
1185+       return;
1186+      case '\a':
1187+       os << "\\a";
1188+       return;
1189+      case '\b':
1190+       os << "\\b";
1191+       return;
1192+      case '\f':
1193+       os << "\\f";
1194+       return;
1195+      case '\r':
1196+       os << "\\r";
1197+       return;
1198+      case '\n':
1199+       os << "\\n";
1200+       return;
1201+      case '\t':
1202+       os << "\\t";
1203+       return;
1204+      case '\v':
1205+       os << "\\v";
1206+       return;
1207+      default:
1208+       if (c < 0x20) {
1209+         os << '\\' << std::oct << static_cast<int>(c);
1210+       } else {
1211+         os << c;
1212+       }
1213+       return;
1214+      }     
1215+    }
1216+
1217+    bool requireEscape(const std::string& str) {
1218+      std::istringstream is(str);
1219+      char c;
1220+      while (is.get(c)) {
1221+       if (isWhiteSpace(c) || isEscaped(c)) {
1222+         return true;
1223+       }
1224+      }
1225+      return false;
1226+    }
1227+   
1228+    std::ostream& writeToken(std::ostream& os, const std::string& str) {
1229+
1230+      if (requireEscape(str)) {
1231+       os << '\"';
1232+       for (std::string::const_iterator it = str.begin();
1233+            it != str.end(); ++it) {
1234+         writeEscape(os, *it);
1235+       }       
1236+       os << '\"';
1237+      } else {
1238+       os << str;
1239+      }
1240+      return os;
1241+    }
1242+
1243+  }
1244
1245+  /// \e
1246+  template <typename _Digraph>
1247+  class DigraphWriter {
1248+  public:
1249+
1250+    typedef _Digraph Digraph;
1251+    GRAPH_TYPEDEFS(typename Digraph);
1252+   
1253+  private:
1254+
1255+
1256+    std::ostream* _os;
1257+    bool local_os;
1258+
1259+    Digraph& _digraph;
1260+
1261+    std::string _node_set_caption;
1262+    std::string _arc_set_caption;
1263+    std::string _attributes_caption;
1264+   
1265+    typedef std::map<Node, std::string> NodeIndex;
1266+    NodeIndex _node_index;
1267+    typedef std::map<Arc, std::string> ArcIndex;
1268+    ArcIndex _arc_index;
1269+
1270+    typedef std::vector<std::pair<std::string,
1271+      _writer_bits::MapStorageBase<Node>* > > NodeMaps;   
1272+    NodeMaps _node_maps;
1273+
1274+    typedef std::vector<std::pair<std::string,
1275+      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
1276+    ArcMaps _arc_maps;
1277+
1278+    typedef std::vector<std::pair<std::string,
1279+      _writer_bits::ValueStorageBase*> > Attributes;
1280+    Attributes _attributes;
1281+
1282+  public:
1283+
1284+    /// \e
1285+    DigraphWriter(std::ostream& is, Digraph& digraph)
1286+      : _os(&is), local_os(false), _digraph(digraph) {}
1287+
1288+    /// \e
1289+    DigraphWriter(const std::string& fn, Digraph& digraph)
1290+      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph) {}
1291+
1292+    /// \e
1293+    DigraphWriter(const char* fn, Digraph& digraph)
1294+      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph) {}
1295+
1296+    DigraphWriter(DigraphWriter& other)
1297+      : _os(other._os), local_os(other.local_os), _digraph(other._digraph) {
1298+
1299+      other.is = 0;
1300+      other.local_os = false;
1301+
1302+      _node_index.swap(other._node_index);
1303+      _arc_index.swap(other._arc_index);
1304+
1305+      _node_maps.swap(other._node_maps);
1306+      _arc_maps.swap(other._arc_maps);
1307+      _attributes.swap(other._attributes);
1308+
1309+      _node_set_caption = other._node_set_caption;
1310+      _arc_set_caption = other._arc_set_caption;
1311+      _attributes_caption = other._attributes_caption;
1312+    }
1313+
1314+    /// \e
1315+    ~DigraphWriter() {
1316+      for (typename NodeMaps::iterator it = _node_maps.begin();
1317+          it != _node_maps.end(); ++it) {
1318+       delete it->second;
1319+      }
1320+
1321+      for (typename ArcMaps::iterator it = _arc_maps.begin();
1322+          it != _arc_maps.end(); ++it) {
1323+       delete it->second;
1324+      }
1325+
1326+      for (typename Attributes::iterator it = _attributes.begin();
1327+          it != _attributes.end(); ++it) {
1328+       delete it->second;
1329+      }
1330+
1331+      if (local_os) {
1332+       delete _os;
1333+      }
1334+    }
1335+
1336+  private:
1337+   
1338+    DigraphWriter& operator=(const DigraphWriter&);
1339+
1340+  public:
1341+
1342+    /// \e
1343+    template <typename Map>
1344+    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
1345+      _writer_bits::MapStorageBase<Node>* storage =
1346+       new _writer_bits::MapStorage<Node, Map>(map);
1347+      _node_maps.push_back(std::make_pair(caption, storage));
1348+      return *this;
1349+    }
1350+
1351+    /// \e
1352+    template <typename Map, typename Converter>
1353+    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
1354+                          const Converter& converter = Converter()) {
1355+      _writer_bits::MapStorageBase<Node>* storage =
1356+       new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1357+      _node_maps.push_back(std::make_pair(caption, storage));
1358+      return *this;
1359+    }
1360+
1361+    /// \e
1362+    template <typename Map>
1363+    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
1364+      _writer_bits::MapStorageBase<Arc>* storage =
1365+       new _writer_bits::MapStorage<Arc, Map>(map);
1366+      _arc_maps.push_back(std::make_pair(caption, storage));
1367+      return *this;
1368+    }
1369+
1370+    /// \e
1371+    template <typename Map, typename Converter>
1372+    DigraphWriter& arcMap(const std::string& caption, const Map& map,
1373+                         const Converter& converter = Converter()) {
1374+      _writer_bits::MapStorageBase<Arc>* storage =
1375+       new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
1376+      _arc_maps.push_back(std::make_pair(caption, storage));
1377+      return *this;
1378+    }
1379+
1380+    /// \e
1381+    template <typename Value>
1382+    DigraphWriter& attribute(const std::string& caption, const Value& value) {
1383+      _writer_bits::ValueStorageBase* storage =
1384+       new _writer_bits::ValueStorage<Value>(value);
1385+      _attributes.push_back(std::make_pair(caption, storage));
1386+      return *this;
1387+    }
1388+
1389+    /// \e
1390+    template <typename Value, typename Converter>
1391+    DigraphWriter& attribute(const std::string& caption, const Value& value,
1392+                            const Converter& converter = Converter()) {
1393+      _writer_bits::ValueStorageBase* storage =
1394+       new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1395+      _attributes.push_back(std::make_pair(caption, storage));
1396+      return *this;
1397+    }
1398+
1399+    /// \e
1400+    DigraphWriter& node(const std::string& caption, const Node& node) {
1401+      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1402+      Converter converter(_node_index);
1403+      _writer_bits::ValueStorageBase* storage =
1404+       new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1405+      _attributes.push_back(std::make_pair(caption, storage));
1406+      return *this;
1407+    }
1408+
1409+    /// \e
1410+    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
1411+      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
1412+      Converter converter(_arc_index);
1413+      _writer_bits::ValueStorageBase* storage =
1414+       new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1415+      _attributes.push_back(std::make_pair(caption, storage));
1416+      return *this;
1417+    }
1418+
1419+    /// \e
1420+    DigraphWriter& nodeSet(const std::string& caption) {
1421+      _node_set_caption = caption;
1422+      return *this;
1423+    }
1424+
1425+    /// \e
1426+    DigraphWriter& arcSet(const std::string& caption) {
1427+      _arc_set_caption = caption;
1428+      return *this;
1429+    }
1430+
1431+    /// \e
1432+    DigraphWriter& attributes(const std::string& caption) {
1433+      _attributes_caption = caption;
1434+      return *this;
1435+    }
1436+
1437+  private:
1438+
1439+    void writeNodeSet() {
1440+      bool _write_label = true;
1441+      for (typename NodeMaps::iterator it = _node_maps.begin();
1442+          it != _node_maps.end(); ++it) {
1443+        if (it->first == "label") {
1444+         _write_label = false;
1445+       }
1446+      }
1447+
1448+      *_os << "@nodeset";
1449+      if (!_node_set_caption.empty()) {
1450+       *_os << ' ' << _node_set_caption;
1451+      }
1452+      *_os << std::endl;
1453+
1454+      if (_write_label) {
1455+       *_os << "label" << '\t';
1456+      }
1457+      for (typename NodeMaps::iterator it = _node_maps.begin();
1458+          it != _node_maps.end(); ++it) {
1459+       *_os << it->first << '\t';
1460+      }
1461+      *_os << std::endl;
1462+
1463+      for (NodeIt n(_digraph); n != INVALID; ++n) {
1464+       if (_write_label) {
1465+         std::ostringstream os;
1466+         os << _digraph.id(n);
1467+         _writer_bits::writeToken(*_os, os.str());
1468+         *_os << '\t';
1469+         _node_index.insert(std::make_pair(n, os.str()));
1470+       }
1471+       for (typename NodeMaps::iterator it = _node_maps.begin();
1472+            it != _node_maps.end(); ++it) {
1473+         std::string value = it->second->get(n);
1474+         _writer_bits::writeToken(*_os, value);
1475+         if (it->first == "label") {
1476+           _node_index.insert(std::make_pair(n, value));
1477+         }
1478+         *_os << '\t';
1479+       }
1480+       *_os << std::endl;
1481+      }
1482+    }
1483+
1484+    void writeArcSet() {
1485+      bool _write_label = true;
1486+      for (typename ArcMaps::iterator it = _arc_maps.begin();
1487+          it != _arc_maps.end(); ++it) {
1488+        if (it->first == "label") {
1489+         _write_label = false;
1490+       }
1491+      }
1492+
1493+      *_os << "@arcset";
1494+      if (!_arc_set_caption.empty()) {
1495+       *_os << ' ' << _arc_set_caption;
1496+      }
1497+      *_os << std::endl;
1498+
1499+      *_os << '\t' << '\t';
1500+      if (_write_label) {
1501+       *_os << "label" << '\t';
1502+      }
1503+      for (typename ArcMaps::iterator it = _arc_maps.begin();
1504+          it != _arc_maps.end(); ++it) {
1505+       *_os << it->first << '\t';
1506+      }
1507+      *_os << std::endl;
1508+
1509+      for (ArcIt a(_digraph); a != INVALID; ++a) {
1510+       _writer_bits::writeToken(*_os, _node_index.
1511+                                find(_digraph.source(a))->second);
1512+       *_os << '\t';
1513+       _writer_bits::writeToken(*_os, _node_index.
1514+                                find(_digraph.target(a))->second);
1515+       *_os << '\t';
1516+       if (_write_label) {
1517+         std::ostringstream os;
1518+         os << _digraph.id(a);
1519+         _writer_bits::writeToken(*_os, os.str());
1520+         *_os << '\t';
1521+         _arc_index.insert(std::make_pair(a, os.str()));
1522+       }
1523+       for (typename ArcMaps::iterator it = _arc_maps.begin();
1524+            it != _arc_maps.end(); ++it) {
1525+         std::string value = it->second->get(a);
1526+         _writer_bits::writeToken(*_os, value);
1527+         if (it->first == "label") {
1528+           _arc_index.insert(std::make_pair(a, value));
1529+         }
1530+         *_os << '\t';
1531+       }
1532+       *_os << std::endl;
1533+      }
1534+    }
1535+
1536+    void writeAttributes() {
1537+      if (_attributes.empty()) return;
1538+      *_os << "@attributes";
1539+      if (!_attributes_caption.empty()) {
1540+       *_os << ' ' << _attributes_caption;
1541+      }
1542+      *_os << std::endl;
1543+      for (typename Attributes::iterator it = _attributes.begin();
1544+          it != _attributes.end(); ++it) {
1545+       *_os << it->first << ' ';
1546+       _writer_bits::writeToken(*_os, it->second->get());
1547+       *_os << std::endl;
1548+      }
1549+    }
1550+   
1551+  public:
1552+   
1553+    /// \e
1554+    void run() {
1555+      writeNodeSet();
1556+      writeArcSet();
1557+      writeAttributes();
1558+    }
1559+   
1560+  };
1561+
1562+  template <typename Digraph>
1563+  DigraphWriter<Digraph> digraphWriter(std::istream& is, Digraph& digraph) {
1564+    return DigraphWriter<Digraph>(is, digraph);
1565+  }
1566+
1567+  template <typename Digraph>
1568+  DigraphWriter<Digraph> digraphWriter(const std::string& fn,
1569+                                      Digraph& digraph) {
1570+    return DigraphWriter<Digraph>(fn, digraph);
1571+  }
1572+
1573+  template <typename Digraph>
1574+  DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
1575+    return DigraphWriter<Digraph>(fn, digraph);
1576+  }
1577+}
1578+
1579+#endif
1580# HG changeset patch
1581# User Balazs Dezso <deba@inf.elte.hu>
1582# Date 1207839002 -7200
1583# Node ID 7174a0d8102dd0ea4c5c84b78bcd75433d839375
1584# Parent  988226bc5e6c092db643ebcb020e0a9e38f08dd0
1585Several changes in lgf IO
1586
1587- Manual handling comments and section delimiters instead of FilterStreamBuf
1588- Renaming nodeset and arcset
1589- Reading full line in attributes
1590
1591diff -r 988226bc5e6c -r 7174a0d8102d lemon/lgf_reader.h
1592--- a/lemon/lgf_reader.h        Thu Apr 10 10:20:00 2008 +0200
1593+++ b/lemon/lgf_reader.h        Thu Apr 10 16:50:02 2008 +0200
1594@@ -134,160 +134,22 @@ namespace lemon {
1595       }
1596     };
1597 
1598-
1599-    class FilterStreamBuf : public std::streambuf {
1600-    public:
1601-
1602-      typedef std::streambuf Parent;
1603-      typedef Parent::char_type char_type;
1604-      FilterStreamBuf(std::istream& is, int& num)
1605-       : _is(is), _base(0), _eptr(0),
1606-         _num(num), skip_state(after_endl) {}
1607-
1608-    protected:
1609-
1610-      enum skip_state_type {
1611-       no_skip,
1612-       after_endl,
1613-       comment_line
1614-      };
1615-
1616-      char_type small_buf[1];
1617-
1618-
1619-      std::istream& _is;
1620-
1621-      char_type* _base;
1622-      char_type* _eptr;
1623-
1624-      int& _num;
1625-
1626-      skip_state_type skip_state;
1627-
1628-
1629-      char_type* base() { return _base; }
1630-      char_type* eptr() { return _eptr; }
1631-      int_type blen() { return _eptr - _base; }
1632-
1633-      void setb(char_type* buf, int_type len) {
1634-       _base = buf;
1635-       _eptr = buf + len;
1636-      }
1637
1638-      virtual std::streambuf* setbuf(char *buf, std::streamsize len) {
1639-       if (base()) return 0;
1640-       if (buf != 0 && len >= int(sizeof(small_buf))) {
1641-         setb(buf, len);
1642-       } else {
1643-         setb(small_buf, sizeof(small_buf));
1644-       }
1645-       setg(0, 0, 0);
1646-       return this;
1647-      }
1648-
1649-      bool put_char(char c) {
1650-       switch (skip_state) {
1651-       case no_skip:
1652-         switch (c) {
1653-         case '\n':
1654-           skip_state = after_endl;
1655-           return true;
1656-         default:
1657-           return true;
1658-         }
1659-       case after_endl:
1660-         switch (c) {
1661-         case '@':
1662-           return false;
1663-         case '\n':
1664-           return false;
1665-         case '#':
1666-           skip_state = comment_line;
1667-           return false;
1668-         default:
1669-           if (!isspace(c)) {
1670-             skip_state = no_skip;
1671-             return true;
1672-           } else {
1673-             return false;
1674-           }
1675-         }
1676-         break;
1677-       case comment_line:
1678-         switch (c) {
1679-         case '\n':
1680-           skip_state = after_endl;
1681-           return false;
1682-         default:
1683-           return false;
1684-         }
1685-       }
1686-       return false;
1687-      }
1688-
1689-      virtual int_type underflow() {
1690-       char c;
1691-       if ((c = _is.peek()) != EOF) {
1692-         if (c == '@') {
1693-           return EOF;
1694-         }
1695-       } else {
1696-         return EOF;
1697-       }
1698-       char_type *ptr;
1699-       for (ptr = base(); ptr != eptr(); ++ptr) {
1700-         if ((c = _is.get()) != EOF) {
1701-           if (c == '\n') ++_num;
1702-           if (put_char(c)) {
1703-             *ptr = c;
1704-           } else {
1705-             if (skip_state == after_endl && c == '@') {
1706-               _is.putback(c);
1707-               break;
1708-             }
1709-             --ptr;
1710-           }
1711-         } else {
1712-           break;
1713-         }
1714-       }
1715-       setg(base(), base(), ptr);
1716-       return *base();
1717-      }
1718-
1719-      virtual int_type sync() {
1720-       return EOF;
1721-      }
1722-
1723-    public:
1724-
1725-      int line_num() const {
1726-       int r = _num;
1727-       for (char_type* p = gptr(); p != egptr(); ++p) {
1728-         if (*p == '\n') --r;
1729-       }
1730-       return r;
1731-      }
1732-
1733-    };
1734-
1735     template <typename Value>
1736     struct MapLookUpConverter {
1737       const std::map<std::string, Value>& _map;
1738-     
1739-      MapLookUpConverter(const std::map<std::string, Value>& map)
1740-       : _map(map) {}
1741-     
1742+
1743+      MapLookUpConverter(const std::map<std::string, Value>& map)
1744+        : _map(map) {}
1745+
1746       Value operator()(const std::string& str) {
1747-       typename std::map<std::string, Value>::const_iterator it =
1748-         _map.find(str);
1749-
1750-       if (it == _map.end()) {
1751-         std::ostringstream msg;
1752-         msg << "Item not found: " << str;
1753-         throw DataFormatError(msg.str().c_str());
1754-       }
1755-       return it->second;
1756+        typename std::map<std::string, Value>::const_iterator it =
1757+          _map.find(str);
1758+        if (it == _map.end()) {
1759+          std::ostringstream msg;
1760+          msg << "Item not found: " << str;
1761+          throw DataFormatError(msg.str().c_str());
1762+        }
1763+        return it->second;
1764       }
1765     };
1766 
1767@@ -369,8 +231,7 @@ namespace lemon {
1768        }             
1769       }
1770     }
1771-
1772-
1773+   
1774     std::istream& readToken(std::istream& is, std::string& str) {
1775       std::ostringstream os;
1776 
1777@@ -396,7 +257,7 @@ namespace lemon {
1778          os << c;
1779        }
1780        if (!is) {
1781-         is.setstate(std::ios_base::goodbit);
1782+         is.clear();
1783        } else {
1784          is.putback(c);
1785        }
1786@@ -423,8 +284,8 @@ namespace lemon {
1787 
1788     Digraph& _digraph;
1789 
1790-    std::string _node_set_caption;
1791-    std::string _arc_set_caption;
1792+    std::string _nodes_caption;
1793+    std::string _arcs_caption;
1794     std::string _attributes_caption;
1795 
1796     typedef std::map<std::string, Node> NodeIndex;
1797@@ -443,6 +304,9 @@ namespace lemon {
1798     typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1799       Attributes;
1800     Attributes _attributes;
1801+
1802+    int line_num;
1803+    std::istringstream line;
1804 
1805   public:
1806 
1807@@ -471,8 +335,8 @@ namespace lemon {
1808       _arc_maps.swap(other._arc_maps);
1809       _attributes.swap(other._attributes);
1810 
1811-      _node_set_caption = other._node_set_caption;
1812-      _arc_set_caption = other._arc_set_caption;
1813+      _nodes_caption = other._nodes_caption;
1814+      _arcs_caption = other._arcs_caption;
1815       _attributes_caption = other._attributes_caption;
1816     }
1817 
1818@@ -582,14 +446,14 @@ namespace lemon {
1819     }
1820 
1821     /// \e
1822-    DigraphReader& nodeSet(const std::string& caption) {
1823-      _node_set_caption = caption;
1824+    DigraphReader& nodes(const std::string& caption) {
1825+      _nodes_caption = caption;
1826       return *this;
1827     }
1828 
1829     /// \e
1830-    DigraphReader& arcSet(const std::string& caption) {
1831-      _arc_set_caption = caption;
1832+    DigraphReader& arcs(const std::string& caption) {
1833+      _arcs_caption = caption;
1834       return *this;
1835     }
1836 
1837@@ -600,49 +464,39 @@ namespace lemon {
1838     }
1839 
1840   private:
1841-   
1842 
1843-    static void skipSection(std::istream& is, int& line_num) {
1844-      enum skip_state_type { skip, after_endl };
1845-
1846-      skip_state_type skip_state = after_endl;
1847-      char c;
1848-     
1849-      while ((c = is.get()) != EOF) {
1850-       if (c == '\n') ++line_num;
1851-
1852-       switch (skip_state) {
1853-       case skip:
1854-         if (c == '\n') skip_state = after_endl;
1855-         break;
1856-       case after_endl:
1857-         switch (c) {
1858-         case '@':
1859-           is.putback(c);
1860-           return;
1861-         case '\n':
1862-           continue;
1863-         default:
1864-           if (!isspace(c)) {
1865-             skip_state = skip;
1866-           }
1867-           break;
1868-         }
1869-       }       
1870+    bool readLine() {
1871+      std::string str;
1872+      while(++line_num, std::getline(*_is, str)) {
1873+       line.clear(); line.str(str);
1874+       char c;
1875+       if (line >> std::ws >> c && c != '#') {
1876+         line.putback(c);
1877+         return true;
1878+       }
1879       }
1880+      return false;
1881     }
1882 
1883-    void readNodeSet(std::istream& is) {
1884+    bool readSuccess() {
1885+      return static_cast<bool>(*_is);
1886+    }
1887+   
1888+    void skipSection() {
1889+      char c;
1890+      while (readSuccess() && line >> std::ws >> c && c != '@') {
1891+       readLine();
1892+      }
1893+      line.putback(c);
1894+    }
1895+
1896+    void readNodes() {
1897 
1898       std::vector<std::string> maps;
1899-      std::string line;
1900 
1901-      {
1902-       std::getline(is, line);
1903-        std::istringstream ls(line);
1904-
1905+      if (readLine()) {
1906        std::string map;
1907-       while (ls >> map) {
1908+       while (line >> map) {
1909          maps.push_back(map);
1910 
1911          typename NodeMaps::iterator it = _node_maps.lower_bound(map);
1912@@ -661,14 +515,15 @@ namespace lemon {
1913          }
1914        }
1915       }
1916-     
1917-      while (getline(is, line)) {
1918+
1919+      char c;
1920+      while (readLine() && line >> c && c != '@') {
1921+       line.putback(c);
1922        Node n = _digraph.addNode();
1923 
1924-       std::istringstream ls(line);
1925        for (int i = 0; i < static_cast<int>(maps.size()); ++i) {
1926          std::string token;
1927-         _reader_bits::readToken(ls, token);
1928+         _reader_bits::readToken(line, token);
1929         
1930          typename NodeMaps::iterator it = _node_maps.lower_bound(maps[i]);
1931          while (it != _node_maps.end() && it->first == maps[i]) {
1932@@ -681,20 +536,18 @@ namespace lemon {
1933          }
1934        }
1935       }
1936+      if (readSuccess()) {
1937+       line.putback(c);
1938+      }
1939     }
1940 
1941-    void readArcSet(std::istream& is) {
1942+    void readArcs() {
1943 
1944       std::vector<std::string> maps;
1945-      std::string line;
1946-
1947-      {
1948-       
1949-       std::getline(is, line);
1950-        std::istringstream ls(line);
1951-
1952+     
1953+      if (readLine()) {       
1954        std::string map;
1955-       while (ls >> map) {
1956+       while (line >> map) {
1957          maps.push_back(map);
1958 
1959          typename ArcMaps::iterator it = _arc_maps.lower_bound(map);
1960@@ -714,15 +567,16 @@ namespace lemon {
1961        }
1962       }
1963       
1964-      while (getline(is, line)) {
1965-       std::istringstream ls(line);
1966+      char c;
1967+      while (readLine() && line >> c && c != '@') {
1968+       line.putback(c);
1969 
1970        Node s, t;
1971        {
1972          std::string token;
1973          typename NodeIndex::iterator it;
1974         
1975-         _reader_bits::readToken(ls, token);
1976+         _reader_bits::readToken(line, token);
1977          it = _node_index.find(token);
1978          if (it == _node_index.end()) {
1979            std::ostringstream msg;
1980@@ -731,7 +585,7 @@ namespace lemon {
1981          }
1982          s = it->second;
1983 
1984-         _reader_bits::readToken(ls, token);
1985+         _reader_bits::readToken(line, token);
1986          it = _node_index.find(token);
1987          if (it == _node_index.end()) {
1988            std::ostringstream msg;
1989@@ -745,7 +599,7 @@ namespace lemon {
1990 
1991        for (int i = 0; i < static_cast<int>(maps.size()); ++i) {
1992          std::string token;
1993-         _reader_bits::readToken(ls, token);
1994+         _reader_bits::readToken(line, token);
1995         
1996          typename ArcMaps::iterator it = _arc_maps.lower_bound(maps[i]);
1997          while (it != _arc_maps.end() && it->first == maps[i]) {
1998@@ -758,21 +612,22 @@ namespace lemon {
1999          }
2000        }
2001       }
2002+      if (readSuccess()) {
2003+       line.putback(c);
2004+      }
2005     }
2006 
2007-    void readAttributes(std::istream& is) {
2008+    void readAttributes() {
2009 
2010       std::vector<std::string> maps;
2011-      std::string line;
2012 
2013-      while (std::getline(is, line)) {
2014-
2015-        std::istringstream ls(line);
2016-
2017+      char c;
2018+      while (readLine() && line >> c && c != '@') {
2019+       line.putback(c);
2020+       
2021        std::string attr, token;
2022-
2023-       ls >> attr;
2024-       _reader_bits::readToken(ls, token);
2025+       line >> attr;
2026+       std::getline(line >> std::ws, token);
2027       
2028        typename Attributes::iterator it = _attributes.lower_bound(attr);
2029        while (it != _attributes.end() && it->first == attr) {
2030@@ -780,6 +635,9 @@ namespace lemon {
2031          it->second->touch();
2032          ++it;
2033        }
2034+      }
2035+      if (readSuccess()) {
2036+       line.putback(c);
2037       }
2038       for (typename Attributes::iterator it = _attributes.begin();
2039           it != _attributes.end(); ++it) {
2040@@ -797,47 +655,39 @@ namespace lemon {
2041     void run() {
2042       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2043       
2044-      bool node_set_done = false;
2045-      bool arc_set_done = false;
2046+      bool nodes_done = false;
2047+      bool arcs_done = false;
2048       bool attributes_done = false;
2049       
2050-      int line_num = 0;
2051-      std::string line;
2052-     
2053-      skipSection(*_is, line_num);
2054+      readLine();
2055 
2056-      while (++line_num, getline(*_is, line)) {
2057-       char buf[2048];
2058-       _reader_bits::FilterStreamBuf buffer(*_is, line_num);
2059+      while (readSuccess()) {
2060+       skipSection();
2061        try {
2062-         buffer.pubsetbuf(buf, sizeof(buf));
2063-         std::istream fs(&buffer);
2064-         
2065-         std::istringstream ls(line);
2066          std::string section, caption;
2067-         ls >> section >> caption;
2068+         line >> section >> caption;
2069 
2070-         if (section == "@nodeset" && !node_set_done) {
2071-           if (_node_set_caption.empty() || _node_set_caption == caption) {
2072-             readNodeSet(fs);
2073-             node_set_done = true;
2074+         if (section == "@nodes" && !nodes_done) {
2075+           if (_nodes_caption.empty() || _nodes_caption == caption) {
2076+             readNodes();
2077+             nodes_done = true;
2078            }
2079-         } else if ((section == "@arcset" || section == "@edgeset") &&
2080-                    !arc_set_done) {
2081-           if (_arc_set_caption.empty() || _arc_set_caption == caption) {
2082-             readArcSet(fs);
2083-             arc_set_done = true;
2084+         } else if ((section == "@arcs" || section == "@edges") &&
2085+                    !arcs_done) {
2086+           if (_arcs_caption.empty() || _arcs_caption == caption) {
2087+             readArcs();
2088+             arcs_done = true;
2089            }
2090          } else if (section == "@attributes" && !attributes_done) {
2091            if (_attributes_caption.empty() || _attributes_caption == caption) {
2092-             readAttributes(fs);
2093+             readAttributes();
2094              attributes_done = true;
2095            }
2096          }
2097         
2098-         skipSection(*_is, line_num);
2099+         skipSection();
2100        } catch (DataFormatError& error) {
2101-         error.line(buffer.line_num());
2102+         error.line(line_num);
2103          throw;
2104        }       
2105       }       
2106diff -r 988226bc5e6c -r 7174a0d8102d lemon/lgf_writer.h
2107--- a/lemon/lgf_writer.h        Thu Apr 10 10:20:00 2008 +0200
2108+++ b/lemon/lgf_writer.h        Thu Apr 10 16:50:02 2008 +0200
2109@@ -120,8 +120,6 @@ namespace lemon {
2110        typename std::map<Value, std::string>::const_iterator it =
2111          _map.find(str);
2112        if (it == _map.end()) {
2113-         std::ostringstream msg;
2114-         msg << "Item not found";
2115          throw DataFormatError("Item not found");
2116        }
2117        return it->second;
2118@@ -221,8 +219,8 @@ namespace lemon {
2119 
2120     Digraph& _digraph;
2121 
2122-    std::string _node_set_caption;
2123-    std::string _arc_set_caption;
2124+    std::string _nodes_caption;
2125+    std::string _arcs_caption;
2126     std::string _attributes_caption;
2127     
2128     typedef std::map<Node, std::string> NodeIndex;
2129@@ -269,8 +267,8 @@ namespace lemon {
2130       _arc_maps.swap(other._arc_maps);
2131       _attributes.swap(other._attributes);
2132 
2133-      _node_set_caption = other._node_set_caption;
2134-      _arc_set_caption = other._arc_set_caption;
2135+      _nodes_caption = other._nodes_caption;
2136+      _arcs_caption = other._arcs_caption;
2137       _attributes_caption = other._attributes_caption;
2138     }
2139 
2140@@ -380,14 +378,14 @@ namespace lemon {
2141     }
2142 
2143     /// \e
2144-    DigraphWriter& nodeSet(const std::string& caption) {
2145-      _node_set_caption = caption;
2146+    DigraphWriter& nodes(const std::string& caption) {
2147+      _nodes_caption = caption;
2148       return *this;
2149     }
2150 
2151     /// \e
2152-    DigraphWriter& arcSet(const std::string& caption) {
2153-      _arc_set_caption = caption;
2154+    DigraphWriter& arcs(const std::string& caption) {
2155+      _arcs_caption = caption;
2156       return *this;
2157     }
2158 
2159@@ -399,7 +397,7 @@ namespace lemon {
2160 
2161   private:
2162 
2163-    void writeNodeSet() {
2164+    void writeNodes() {
2165       bool _write_label = true;
2166       for (typename NodeMaps::iterator it = _node_maps.begin();
2167           it != _node_maps.end(); ++it) {
2168@@ -408,9 +406,9 @@ namespace lemon {
2169        }
2170       }
2171 
2172-      *_os << "@nodeset";
2173-      if (!_node_set_caption.empty()) {
2174-       *_os << ' ' << _node_set_caption;
2175+      *_os << "@nodes";
2176+      if (!_nodes_caption.empty()) {
2177+       *_os << ' ' << _nodes_caption;
2178       }
2179       *_os << std::endl;
2180 
2181@@ -444,7 +442,7 @@ namespace lemon {
2182       }
2183     }
2184 
2185-    void writeArcSet() {
2186+    void writeArcs() {
2187       bool _write_label = true;
2188       for (typename ArcMaps::iterator it = _arc_maps.begin();
2189           it != _arc_maps.end(); ++it) {
2190@@ -453,9 +451,9 @@ namespace lemon {
2191        }
2192       }
2193 
2194-      *_os << "@arcset";
2195-      if (!_arc_set_caption.empty()) {
2196-       *_os << ' ' << _arc_set_caption;
2197+      *_os << "@arcs";
2198+      if (!_arcs_caption.empty()) {
2199+       *_os << ' ' << _arcs_caption;
2200       }
2201       *_os << std::endl;
2202 
2203@@ -515,8 +513,8 @@ namespace lemon {
2204     
2205     /// \e
2206     void run() {
2207-      writeNodeSet();
2208-      writeArcSet();
2209+      writeNodes();
2210+      writeArcs();
2211       writeAttributes();
2212     }
2213     
2214# HG changeset patch
2215# User Balazs Dezso <deba@inf.elte.hu>
2216# Date 1207906639 -7200
2217# Node ID 80086ce5c586577faaa0dba778d0ecbd4c5450ad
2218# Parent  7174a0d8102dd0ea4c5c84b78bcd75433d839375
2219Several improvments in lgf IO
2220- More format checking code
2221- Better node and arc map reading
2222- Sorting arcs and nodes by label on writing
2223
2224diff -r 7174a0d8102d -r 80086ce5c586 lemon/lgf_reader.h
2225--- a/lemon/lgf_reader.h        Thu Apr 10 16:50:02 2008 +0200
2226+++ b/lemon/lgf_reader.h        Fri Apr 11 11:37:19 2008 +0200
2227@@ -484,7 +484,7 @@ namespace lemon {
2228     
2229     void skipSection() {
2230       char c;
2231-      while (readSuccess() && line >> std::ws >> c && c != '@') {
2232+      while (readSuccess() && line >> c && c != '@') {
2233        readLine();
2234       }
2235       line.putback(c);
2236@@ -492,26 +492,39 @@ namespace lemon {
2237 
2238     void readNodes() {
2239 
2240-      std::vector<std::string> maps;
2241+      std::vector<std::vector<_reader_bits::MapStorageBase<Node>*> > maps;
2242+      int label = -1;
2243 
2244       if (readLine()) {
2245        std::string map;
2246        while (line >> map) {
2247-         maps.push_back(map);
2248+
2249+         if (map == "label") {
2250+           label = maps.size();
2251+         }
2252+
2253+         maps.push_back(std::vector<_reader_bits::MapStorageBase<Node>*>());
2254 
2255          typename NodeMaps::iterator it = _node_maps.lower_bound(map);
2256          while (it != _node_maps.end() && it->first == map) {
2257+           if (it->second->touched()) {
2258+             std::ostringstream msg;
2259+             msg << "Multiple occurence of node map " << map;
2260+             throw DataFormatError(msg.str().c_str());
2261+           }
2262+           maps.back().push_back(it->second);
2263            it->second->touch();
2264            ++it;
2265          }
2266+
2267        }
2268 
2269        for (typename NodeMaps::iterator it = _node_maps.begin();
2270             it != _node_maps.end(); ++it) {
2271          if (!it->second->touched()) {
2272-           ErrorMessage msg;
2273+           std::ostringstream msg;
2274            msg << "Map not found in file: " << it->first;
2275-           throw IoParameterError(msg.message());
2276+           throw IoParameterError(msg.str().c_str());
2277          }
2278        }
2279       }
2280@@ -524,16 +537,19 @@ namespace lemon {
2281        for (int i = 0; i < static_cast<int>(maps.size()); ++i) {
2282          std::string token;
2283          _reader_bits::readToken(line, token);
2284-         
2285-         typename NodeMaps::iterator it = _node_maps.lower_bound(maps[i]);
2286-         while (it != _node_maps.end() && it->first == maps[i]) {
2287-           it->second->set(n, token);
2288-           ++it;
2289+
2290+         for (int j = 0; j < static_cast<int>(maps[i].size()); ++j) {
2291+           maps[i][j]->set(n, token);
2292          }
2293         
2294-         if (maps[i] == "label") {
2295-           _node_index[token] = n;
2296+         if (label == i) {
2297+           _node_index.insert(std::make_pair(token, n));
2298          }
2299+
2300+       }
2301+
2302+       if (line >> std::ws >> c) {
2303+         throw DataFormatError("Extra character on the end of line");
2304        }
2305       }
2306       if (readSuccess()) {
2307@@ -543,15 +559,27 @@ namespace lemon {
2308 
2309     void readArcs() {
2310 
2311-      std::vector<std::string> maps;
2312-     
2313-      if (readLine()) {       
2314+      std::vector<std::vector<_reader_bits::MapStorageBase<Arc>*> > maps;
2315+      int label = -1;
2316+
2317+      if (readLine()) {
2318        std::string map;
2319        while (line >> map) {
2320-         maps.push_back(map);
2321+
2322+         if (map == "label") {
2323+           label = maps.size();
2324+         }
2325+
2326+         maps.push_back(std::vector<_reader_bits::MapStorageBase<Arc>*>());
2327 
2328          typename ArcMaps::iterator it = _arc_maps.lower_bound(map);
2329          while (it != _arc_maps.end() && it->first == map) {
2330+           if (it->second->touched()) {
2331+             std::ostringstream msg;
2332+             msg << "Multiple occurence of arc map " << map;
2333+             throw DataFormatError(msg.str().c_str());
2334+           }
2335+           maps.back().push_back(it->second);
2336            it->second->touch();
2337            ++it;
2338          }
2339@@ -560,9 +588,9 @@ namespace lemon {
2340        for (typename ArcMaps::iterator it = _arc_maps.begin();
2341             it != _arc_maps.end(); ++it) {
2342          if (!it->second->touched()) {
2343-           ErrorMessage msg;
2344+           std::ostringstream msg;
2345            msg << "Map not found in file: " << it->first;
2346-           throw IoParameterError(msg.message());
2347+           throw IoParameterError(msg.str().c_str());
2348          }
2349        }
2350       }
2351@@ -600,16 +628,19 @@ namespace lemon {
2352        for (int i = 0; i < static_cast<int>(maps.size()); ++i) {
2353          std::string token;
2354          _reader_bits::readToken(line, token);
2355-         
2356-         typename ArcMaps::iterator it = _arc_maps.lower_bound(maps[i]);
2357-         while (it != _arc_maps.end() && it->first == maps[i]) {
2358-           it->second->set(a, token);
2359-           ++it;
2360+                 
2361+         for (int j = 0; j < static_cast<int>(maps[i].size()); ++j) {
2362+           maps[i][j]->set(a, token);
2363+         }
2364+
2365+         if (label == i) {
2366+           _arc_index.insert(std::make_pair(token, a));
2367          }
2368         
2369-         if (maps[i] == "label") {
2370-           _arc_index[token] = a;
2371-         }
2372+       }
2373+
2374+       if (line >> std::ws >> c) {
2375+         throw DataFormatError("Extra character on the end of line");
2376        }
2377       }
2378       if (readSuccess()) {
2379@@ -631,6 +662,11 @@ namespace lemon {
2380       
2381        typename Attributes::iterator it = _attributes.lower_bound(attr);
2382        while (it != _attributes.end() && it->first == attr) {
2383+         if (it->second->touched()) {
2384+           std::ostringstream msg;
2385+           msg << "Multiple occurence of attribute " << attr;
2386+           throw DataFormatError(msg.str().c_str());
2387+         }
2388          it->second->set(token);
2389          it->second->touch();
2390          ++it;
2391@@ -642,9 +678,9 @@ namespace lemon {
2392       for (typename Attributes::iterator it = _attributes.begin();
2393           it != _attributes.end(); ++it) {
2394        if (!it->second->touched()) {
2395-         ErrorMessage msg;
2396+         std::ostringstream msg;
2397          msg << "Attribute not found in file: " << it->first;
2398-         throw IoParameterError(msg.message());
2399+         throw IoParameterError(msg.str().c_str());
2400        }       
2401       }
2402     }
2403@@ -690,7 +726,19 @@ namespace lemon {
2404          error.line(line_num);
2405          throw;
2406        }       
2407-      }       
2408+      }
2409+
2410+      if (!nodes_done) {
2411+       throw DataFormatError("Section @nodes not found");
2412+      }
2413+
2414+      if (!arcs_done) {
2415+       throw DataFormatError("Section @arcs not found");
2416+      }
2417+
2418+      if (!attributes_done && !_attributes.empty()) {
2419+       throw DataFormatError("Section @attributes not found");
2420+      }
2421 
2422     }
2423     
2424diff -r 7174a0d8102d -r 80086ce5c586 lemon/lgf_writer.h
2425--- a/lemon/lgf_writer.h        Thu Apr 10 16:50:02 2008 +0200
2426+++ b/lemon/lgf_writer.h        Fri Apr 11 11:37:19 2008 +0200
2427@@ -28,6 +28,8 @@
2428 #include <fstream>
2429 #include <sstream>
2430 
2431+#include <algorithm>
2432+
2433 #include <vector>
2434 #include <functional>
2435 
2436@@ -47,6 +49,28 @@ namespace lemon {
2437       }
2438     };
2439 
2440+    template <typename T>
2441+    bool operator<(const T&, const T&) {
2442+      throw DataFormatError("Label map is not comparable");
2443+    }
2444+
2445+    template <typename _Map>
2446+    class MapLess {
2447+    public:
2448+      typedef _Map Map;
2449+      typedef typename Map::Key Item;
2450+
2451+    private:
2452+      const Map& _map;
2453+     
2454+    public:
2455+      MapLess(const Map& map) : _map(map) {}
2456+
2457+      bool operator()(const Item& left, const Item& right) {
2458+       return _map[left] < _map[right];
2459+      }
2460+    };
2461+
2462     template <typename _Item>   
2463     class MapStorageBase {
2464     public:
2465@@ -57,7 +81,7 @@ namespace lemon {
2466       virtual ~MapStorageBase() {}
2467 
2468       virtual std::string get(const Item& item) = 0;
2469-
2470+      virtual void sort(std::vector<Item>&) = 0;
2471     };
2472 
2473     template <typename _Item, typename _Map,
2474@@ -80,6 +104,10 @@ namespace lemon {
2475       virtual std::string get(const Item& item) {
2476        return _converter(_map[item]);
2477       }
2478+      virtual void sort(std::vector<Item>& items) {
2479+       MapLess<Map> less(_map);
2480+       std::sort(items.begin(), items.end(), less);
2481+      }
2482     };
2483 
2484     class ValueStorageBase {
2485@@ -87,7 +115,7 @@ namespace lemon {
2486       ValueStorageBase() {}
2487       virtual ~ValueStorageBase() {}
2488 
2489-      virtual std::string get() = 0;
2490+      virtual std::string get() = 0;     
2491     };
2492 
2493     template <typename _Value, typename _Converter = DefaultConverter<_Value> >
2494@@ -398,11 +426,12 @@ namespace lemon {
2495   private:
2496 
2497     void writeNodes() {
2498-      bool _write_label = true;
2499+      _writer_bits::MapStorageBase<Node>* label = 0;
2500       for (typename NodeMaps::iterator it = _node_maps.begin();
2501           it != _node_maps.end(); ++it) {
2502         if (it->first == "label") {
2503-         _write_label = false;
2504+         label = it->second;
2505+         break;
2506        }
2507       }
2508 
2509@@ -412,7 +441,7 @@ namespace lemon {
2510       }
2511       *_os << std::endl;
2512 
2513-      if (_write_label) {
2514+      if (label == 0) {
2515        *_os << "label" << '\t';
2516       }
2517       for (typename NodeMaps::iterator it = _node_maps.begin();
2518@@ -421,8 +450,22 @@ namespace lemon {
2519       }
2520       *_os << std::endl;
2521 
2522+      std::vector<Node> nodes;
2523       for (NodeIt n(_digraph); n != INVALID; ++n) {
2524-       if (_write_label) {
2525+       nodes.push_back(n);
2526+      }
2527+     
2528+      if (label == 0) {
2529+       IdMap<Digraph, Node> id_map(_digraph);
2530+       _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
2531+       std::sort(nodes.begin(), nodes.end(), id_less);
2532+      } else {
2533+       label->sort(nodes);
2534+      }
2535+
2536+      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
2537+       Node n = nodes[i];
2538+       if (label == 0) {
2539          std::ostringstream os;
2540          os << _digraph.id(n);
2541          _writer_bits::writeToken(*_os, os.str());
2542@@ -443,11 +486,12 @@ namespace lemon {
2543     }
2544 
2545     void writeArcs() {
2546-      bool _write_label = true;
2547+      _writer_bits::MapStorageBase<Arc>* label = 0;
2548       for (typename ArcMaps::iterator it = _arc_maps.begin();
2549           it != _arc_maps.end(); ++it) {
2550         if (it->first == "label") {
2551-         _write_label = false;
2552+         label = it->second;
2553+         break;
2554        }
2555       }
2556 
2557@@ -458,7 +502,7 @@ namespace lemon {
2558       *_os << std::endl;
2559 
2560       *_os << '\t' << '\t';
2561-      if (_write_label) {
2562+      if (label == 0) {
2563        *_os << "label" << '\t';
2564       }
2565       for (typename ArcMaps::iterator it = _arc_maps.begin();
2566@@ -467,14 +511,28 @@ namespace lemon {
2567       }
2568       *_os << std::endl;
2569 
2570-      for (ArcIt a(_digraph); a != INVALID; ++a) {
2571+      std::vector<Arc> arcs;
2572+      for (ArcIt n(_digraph); n != INVALID; ++n) {
2573+       arcs.push_back(n);
2574+      }
2575+     
2576+      if (label == 0) {
2577+       IdMap<Digraph, Arc> id_map(_digraph);
2578+       _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
2579+       std::sort(arcs.begin(), arcs.end(), id_less);
2580+      } else {
2581+       label->sort(arcs);
2582+      }
2583+
2584+      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
2585+       Arc a = arcs[i];
2586        _writer_bits::writeToken(*_os, _node_index.
2587                                 find(_digraph.source(a))->second);
2588        *_os << '\t';
2589        _writer_bits::writeToken(*_os, _node_index.
2590                                 find(_digraph.target(a))->second);
2591        *_os << '\t';
2592-       if (_write_label) {
2593+       if (label == 0) {
2594          std::ostringstream os;
2595          os << _digraph.id(a);
2596          _writer_bits::writeToken(*_os, os.str());
2597# HG changeset patch
2598# User Balazs Dezso <deba@inf.elte.hu>
2599# Date 1207908422 -7200
2600# Node ID 676fb304b549e57446844f189efcdffd3f78bffa
2601# Parent  80086ce5c586577faaa0dba778d0ecbd4c5450ad
2602Bug fix with attributes
2603
2604diff -r 80086ce5c586 -r 676fb304b549 demo/lgf_demo.cc
2605--- a/demo/lgf_demo.cc  Fri Apr 11 11:37:19 2008 +0200
2606+++ b/demo/lgf_demo.cc  Fri Apr 11 12:07:02 2008 +0200
2607@@ -47,6 +47,7 @@ int main(int argc, const char *argv[]) {
2608     typedef Digraph::Arc Arc;
2609     typedef Digraph::ArcIt ArcIt;
2610 
2611+    typedef Digraph::NodeMap<int> PotentialMap;
2612     typedef Digraph::ArcMap<int> CapacityMap;
2613     typedef Digraph::ArcMap<std::string> NameMap;
2614 
2615@@ -55,14 +56,18 @@ int main(int argc, const char *argv[]) {
2616     const int m = argc > 3 ? std::atoi(argv[3]) : 100;
2617 
2618     Digraph digraph;
2619+    PotentialMap potential(digraph);
2620     CapacityMap capacity(digraph);
2621     NameMap name(digraph);
2622 
2623     std::vector<Node> nodes;
2624+    for (int i = 0; i < n; ++i) {
2625+      Node node = digraph.addNode();
2626+      potential[node] = rnd[m];
2627+      nodes.push_back(node);
2628+    }
2629 
2630-    for (int i = 0; i < n; ++i) {
2631-      nodes.push_back(digraph.addNode());
2632-    }
2633+    std::vector<Arc> arcs;
2634     for (int i = 0; i < e; ++i) {
2635       int s = rnd[n];
2636       int t = rnd[n];
2637@@ -72,14 +77,18 @@ int main(int argc, const char *argv[]) {
2638       std::ostringstream os;
2639       os << "arc \t" << i << std::endl;
2640       name[arc] = os.str();
2641+      arcs.push_back(arc);
2642     }
2643 
2644 
2645     DigraphWriter<Digraph>(ss, digraph).
2646+      nodeMap("potential", potential).
2647       arcMap("capacity", capacity).
2648       arcMap("name", name).
2649       node("source", nodes[0]).
2650       node("target", nodes[1]).
2651+      arc("bottleneck", arcs[e / 2]).
2652+      attribute("creator", "lemon library").
2653       run();
2654 
2655   } catch (DataFormatError& error) {
2656@@ -93,27 +102,38 @@ int main(int argc, const char *argv[]) {
2657     typedef Digraph::Arc Arc;
2658     typedef Digraph::ArcIt ArcIt;
2659 
2660+    typedef Digraph::NodeMap<int> PotentialMap;
2661     typedef Digraph::ArcMap<int> CapacityMap;
2662     typedef Digraph::ArcMap<std::string> NameMap;
2663 
2664     Digraph digraph;
2665+    PotentialMap potential(digraph);
2666     CapacityMap capacity(digraph);
2667     NameMap name(digraph);
2668 
2669     Node s, t;
2670+    Arc a;
2671+   
2672+    std::string creator;
2673 
2674     DigraphReader<Digraph>(ss, digraph).
2675+      nodeMap("potential", potential).
2676       arcMap("capacity", capacity).
2677       arcMap("name", name).
2678       node("source", s).
2679       node("target", t).
2680+      arc("bottleneck", a).
2681+      attribute("creator", creator).
2682       run();
2683 
2684     DigraphWriter<Digraph>(std::cout, digraph).
2685+      nodeMap("potential", potential).
2686       arcMap("capacity", capacity).
2687       arcMap("name", name).
2688       node("source", s).
2689       node("target", t).
2690+      arc("bottleneck", a).
2691+      attribute("creator", creator).
2692       run();
2693 
2694   } catch (DataFormatError& error) {
2695diff -r 80086ce5c586 -r 676fb304b549 lemon/lgf_reader.h
2696--- a/lemon/lgf_reader.h        Fri Apr 11 11:37:19 2008 +0200
2697+++ b/lemon/lgf_reader.h        Fri Apr 11 12:07:02 2008 +0200
2698@@ -658,7 +658,10 @@ namespace lemon {
2699       
2700        std::string attr, token;
2701        line >> attr;
2702-       std::getline(line >> std::ws, token);
2703+       _reader_bits::readToken(line, token);
2704+       if (line >> c) {
2705+         throw DataFormatError("Extra character on the end of line");   
2706+       }
2707       
2708        typename Attributes::iterator it = _attributes.lower_bound(attr);
2709        while (it != _attributes.end() && it->first == attr) {
2710# HG changeset patch
2711# User Balazs Dezso <deba@inf.elte.hu>
2712# Date 1207924771 -7200
2713# Node ID b553a184f119055b4e6c4e8462363fc461fa5f1c
2714# Parent  676fb304b549e57446844f189efcdffd3f78bffa
2715Checking map concepts
2716
2717diff -r 676fb304b549 -r b553a184f119 lemon/lgf_reader.h
2718--- a/lemon/lgf_reader.h        Fri Apr 11 12:07:02 2008 +0200
2719+++ b/lemon/lgf_reader.h        Fri Apr 11 16:39:31 2008 +0200
2720@@ -33,6 +33,9 @@
2721 
2722 #include <lemon/assert.h>
2723 #include <lemon/graph_utils.h>
2724+
2725+#include <lemon/concept_check.h>
2726+#include <lemon/concepts/maps.h>
2727 
2728 namespace lemon {
2729 
2730@@ -371,6 +374,7 @@ namespace lemon {
2731     /// \e
2732     template <typename Map>
2733     DigraphReader& nodeMap(const std::string& caption, Map& map) {
2734+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
2735       _reader_bits::MapStorageBase<Node>* storage =
2736        new _reader_bits::MapStorage<Node, Map>(map);
2737       _node_maps.insert(std::make_pair(caption, storage));
2738@@ -381,6 +385,7 @@ namespace lemon {
2739     template <typename Map, typename Converter>
2740     DigraphReader& nodeMap(const std::string& caption, Map& map,
2741                           const Converter& converter = Converter()) {
2742+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
2743       _reader_bits::MapStorageBase<Node>* storage =
2744        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
2745       _node_maps.insert(std::make_pair(caption, storage));
2746@@ -390,6 +395,7 @@ namespace lemon {
2747     /// \e
2748     template <typename Map>
2749     DigraphReader& arcMap(const std::string& caption, Map& map) {
2750+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
2751       _reader_bits::MapStorageBase<Arc>* storage =
2752        new _reader_bits::MapStorage<Arc, Map>(map);
2753       _arc_maps.insert(std::make_pair(caption, storage));
2754@@ -400,6 +406,7 @@ namespace lemon {
2755     template <typename Map, typename Converter>
2756     DigraphReader& arcMap(const std::string& caption, Map& map,
2757                          const Converter& converter = Converter()) {
2758+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
2759       _reader_bits::MapStorageBase<Arc>* storage =
2760        new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
2761       _arc_maps.insert(std::make_pair(caption, storage));
2762diff -r 676fb304b549 -r b553a184f119 lemon/lgf_writer.h
2763--- a/lemon/lgf_writer.h        Fri Apr 11 12:07:02 2008 +0200
2764+++ b/lemon/lgf_writer.h        Fri Apr 11 16:39:31 2008 +0200
2765@@ -331,6 +331,7 @@ namespace lemon {
2766     /// \e
2767     template <typename Map>
2768     DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
2769+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
2770       _writer_bits::MapStorageBase<Node>* storage =
2771        new _writer_bits::MapStorage<Node, Map>(map);
2772       _node_maps.push_back(std::make_pair(caption, storage));
2773@@ -341,6 +342,7 @@ namespace lemon {
2774     template <typename Map, typename Converter>
2775     DigraphWriter& nodeMap(const std::string& caption, const Map& map,
2776                           const Converter& converter = Converter()) {
2777+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
2778       _writer_bits::MapStorageBase<Node>* storage =
2779        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
2780       _node_maps.push_back(std::make_pair(caption, storage));
2781@@ -350,6 +352,7 @@ namespace lemon {
2782     /// \e
2783     template <typename Map>
2784     DigraphWriter& arcMap(const std::string& caption, const Map& map) {
2785+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
2786       _writer_bits::MapStorageBase<Arc>* storage =
2787        new _writer_bits::MapStorage<Arc, Map>(map);
2788       _arc_maps.push_back(std::make_pair(caption, storage));
2789@@ -360,6 +363,7 @@ namespace lemon {
2790     template <typename Map, typename Converter>
2791     DigraphWriter& arcMap(const std::string& caption, const Map& map,
2792                          const Converter& converter = Converter()) {
2793+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
2794       _writer_bits::MapStorageBase<Arc>* storage =
2795        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
2796       _arc_maps.push_back(std::make_pair(caption, storage));