PathNodeIt
authordeba
Tue, 28 Aug 2007 14:00:42 +0000
changeset 24672025a571895e
parent 2466 feb7974cf4ec
child 2468 16615642ac7b
PathNodeIt

PathWriter/Reader structures
Distinict MapSet readers and writers
lemon/bits/path_dump.h
lemon/graph_reader.h
lemon/graph_writer.h
lemon/lemon_reader.h
lemon/lemon_writer.h
lemon/path_utils.h
     1.1 --- a/lemon/bits/path_dump.h	Tue Aug 28 13:58:54 2007 +0000
     1.2 +++ b/lemon/bits/path_dump.h	Tue Aug 28 14:00:42 2007 +0000
     1.3 @@ -54,7 +54,9 @@
     1.4        RevEdgeIt() {}
     1.5        RevEdgeIt(Invalid) : path(0), current(INVALID) {}
     1.6        RevEdgeIt(const PredMapPath& _path) 
     1.7 -        : path(&_path), current(_path.target) {}
     1.8 +        : path(&_path), current(_path.target) {
     1.9 +        if (path->predMap[current] == INVALID) current = INVALID;
    1.10 +      }
    1.11  
    1.12        operator const typename Graph::Edge() const {
    1.13          return path->predMap[current];
    1.14 @@ -126,7 +128,10 @@
    1.15        RevEdgeIt() {}
    1.16        RevEdgeIt(Invalid) : path(0), current(INVALID) {}
    1.17        RevEdgeIt(const PredMatrixMapPath& _path) 
    1.18 -        : path(&_path), current(_path.target) {}
    1.19 +        : path(&_path), current(_path.target) {
    1.20 +        if (path->predMatrixMap(path->source, current) == INVALID) 
    1.21 +          current = INVALID;
    1.22 +      }
    1.23  
    1.24        operator const typename Graph::Edge() const {
    1.25          return path->predMatrixMap(path->source, current);
     2.1 --- a/lemon/graph_reader.h	Tue Aug 28 13:58:54 2007 +0000
     2.2 +++ b/lemon/graph_reader.h	Tue Aug 28 14:00:42 2007 +0000
     2.3 @@ -324,7 +324,7 @@
     2.4      /// It reads an label from the stream and gives back which edge belongs to
     2.5      /// it. It is possible only if there was read a "label" named edge map.
     2.6      void readLabel(std::istream& is, Edge& edge) const {
     2.7 -      return edgeset_reader.readLabel(is, edge);
     2.8 +      edgeset_reader.readLabel(is, edge);
     2.9      } 
    2.10  
    2.11    private:
    2.12 @@ -443,10 +443,10 @@
    2.13  		     const DefaultSkipper& _skipper = DefaultSkipper()) 
    2.14        : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
    2.15  	nodeset_reader(*reader, _graph, std::string(), skipper),
    2.16 -	u_edgeset_reader(*reader, _graph, nodeset_reader, 
    2.17 +	uedgeset_reader(*reader, _graph, nodeset_reader, 
    2.18  			     std::string(), skipper),
    2.19  	node_reader(*reader, nodeset_reader, std::string()),
    2.20 -	u_edge_reader(*reader, u_edgeset_reader, std::string()),
    2.21 +	uedge_reader(*reader, uedgeset_reader, std::string()),
    2.22  	attribute_reader(*reader, std::string()) {}
    2.23  
    2.24      /// \brief Construct a new UGraphReader.
    2.25 @@ -458,10 +458,10 @@
    2.26        : reader(new LemonReader(_filename)), own_reader(true), 
    2.27  	skipper(_skipper),
    2.28  	nodeset_reader(*reader, _graph, std::string(), skipper),
    2.29 -	u_edgeset_reader(*reader, _graph, nodeset_reader, 
    2.30 +	uedgeset_reader(*reader, _graph, nodeset_reader, 
    2.31  			     std::string(), skipper),
    2.32  	node_reader(*reader, nodeset_reader, std::string()),
    2.33 -	u_edge_reader(*reader, u_edgeset_reader, std::string()),
    2.34 +	uedge_reader(*reader, uedgeset_reader, std::string()),
    2.35  	attribute_reader(*reader, std::string()) {}
    2.36  
    2.37      /// \brief Construct a new UGraphReader.
    2.38 @@ -472,10 +472,10 @@
    2.39  		     const DefaultSkipper& _skipper = DefaultSkipper()) 
    2.40        : reader(_reader), own_reader(false), skipper(_skipper),
    2.41  	nodeset_reader(*reader, _graph, std::string(), skipper),
    2.42 -	u_edgeset_reader(*reader, _graph, nodeset_reader, 
    2.43 +	uedgeset_reader(*reader, _graph, nodeset_reader, 
    2.44  			     std::string(), skipper),
    2.45  	node_reader(*reader, nodeset_reader, std::string()),
    2.46 -	u_edge_reader(*reader, u_edgeset_reader, std::string()),
    2.47 +	uedge_reader(*reader, uedgeset_reader, std::string()),
    2.48  	attribute_reader(*reader, std::string()) {}
    2.49  
    2.50      /// \brief Destruct the graph reader.
    2.51 @@ -533,13 +533,13 @@
    2.52      /// Give a new undirected edge map reading command to the reader.
    2.53      template <typename Map>
    2.54      UGraphReader& readUEdgeMap(std::string name, Map& map) { 
    2.55 -      u_edgeset_reader.readUEdgeMap(name, map);
    2.56 +      uedgeset_reader.readUEdgeMap(name, map);
    2.57        return *this;
    2.58      }
    2.59  
    2.60      template <typename Map>
    2.61      UGraphReader& readUEdgeMap(std::string name, const Map& map) { 
    2.62 -      u_edgeset_reader.readUEdgeMap(name, map);
    2.63 +      uedgeset_reader.readUEdgeMap(name, map);
    2.64        return *this;
    2.65      }
    2.66  
    2.67 @@ -550,14 +550,14 @@
    2.68      template <typename ItemReader, typename Map>
    2.69      UGraphReader& readUEdgeMap(std::string name, Map& map,
    2.70                                 const ItemReader& ir = ItemReader()) {
    2.71 -      u_edgeset_reader.readUEdgeMap(name, map, ir);
    2.72 +      uedgeset_reader.readUEdgeMap(name, map, ir);
    2.73        return *this;
    2.74      }
    2.75  
    2.76      template <typename ItemReader, typename Map>
    2.77      UGraphReader& readUEdgeMap(std::string name, const Map& map,
    2.78                                 const ItemReader& ir = ItemReader()) {
    2.79 -      u_edgeset_reader.readUEdgeMap(name, map, ir);
    2.80 +      uedgeset_reader.readUEdgeMap(name, map, ir);
    2.81        return *this;
    2.82      }
    2.83  
    2.84 @@ -567,7 +567,7 @@
    2.85      template <typename ItemReader>
    2.86      UGraphReader& skipUEdgeMap(std::string name,
    2.87  				       const ItemReader& ir = ItemReader()) {
    2.88 -      u_edgeset_reader.skipUMap(name, ir);
    2.89 +      uedgeset_reader.skipUMap(name, ir);
    2.90        return *this;
    2.91      }
    2.92  
    2.93 @@ -577,13 +577,13 @@
    2.94      /// Give a new edge map reading command to the reader.
    2.95      template <typename Map>
    2.96      UGraphReader& readEdgeMap(std::string name, Map& map) { 
    2.97 -      u_edgeset_reader.readEdgeMap(name, map);
    2.98 +      uedgeset_reader.readEdgeMap(name, map);
    2.99        return *this;
   2.100      }
   2.101  
   2.102      template <typename Map>
   2.103      UGraphReader& readEdgeMap(std::string name, const Map& map) { 
   2.104 -      u_edgeset_reader.readEdgeMap(name, map);
   2.105 +      uedgeset_reader.readEdgeMap(name, map);
   2.106        return *this;
   2.107      }
   2.108  
   2.109 @@ -594,14 +594,14 @@
   2.110      template <typename ItemReader, typename Map>
   2.111      UGraphReader& readEdgeMap(std::string name, Map& map,
   2.112                                const ItemReader& ir = ItemReader()) {
   2.113 -      u_edgeset_reader.readEdgeMap(name, map, ir);
   2.114 +      uedgeset_reader.readEdgeMap(name, map, ir);
   2.115        return *this;
   2.116      }
   2.117  
   2.118      template <typename ItemReader, typename Map>
   2.119      UGraphReader& readEdgeMap(std::string name, const Map& map,
   2.120                                const ItemReader& ir = ItemReader()) {
   2.121 -      u_edgeset_reader.readEdgeMap(name, map, ir);
   2.122 +      uedgeset_reader.readEdgeMap(name, map, ir);
   2.123        return *this;
   2.124      }
   2.125  
   2.126 @@ -611,7 +611,7 @@
   2.127      template <typename ItemReader>
   2.128      UGraphReader& skipEdgeMap(std::string name,
   2.129                                const ItemReader& ir = ItemReader()) {
   2.130 -      u_edgeset_reader.skipEdgeMap(name, ir);
   2.131 +      uedgeset_reader.skipEdgeMap(name, ir);
   2.132        return *this;
   2.133      }
   2.134  
   2.135 @@ -627,7 +627,7 @@
   2.136      ///
   2.137      /// Give a new labeled edge reading command to the reader.
   2.138      UGraphReader& readEdge(std::string name, Edge& edge) {
   2.139 -      u_edge_reader.readEdge(name, edge);
   2.140 +      uedge_reader.readEdge(name, edge);
   2.141      }
   2.142  
   2.143      /// \brief Give a new labeled undirected edge reading command to the
   2.144 @@ -635,7 +635,7 @@
   2.145      ///
   2.146      /// Give a new labeled undirected edge reading command to the reader.
   2.147      UGraphReader& readUEdge(std::string name, UEdge& edge) {
   2.148 -      u_edge_reader.readUEdge(name, edge);
   2.149 +      uedge_reader.readUEdge(name, edge);
   2.150      }
   2.151  
   2.152      /// \brief Give a new attribute reading command.
   2.153 @@ -677,10 +677,10 @@
   2.154  
   2.155      /// \brief Returns true if the reader can give back the items by its label.
   2.156      ///
   2.157 -    /// \brief Returns true if the reader can give back the items by its label.
   2.158 +    /// Returns true if the reader can give back the items by its label.
   2.159      bool isLabelReader() const {
   2.160        return nodeset_reader.isLabelReader() && 
   2.161 -        u_edgeset_reader.isLabelReader();
   2.162 +        uedgeset_reader.isLabelReader();
   2.163      }
   2.164  
   2.165      /// \brief Gives back the node by its label.
   2.166 @@ -696,7 +696,7 @@
   2.167      /// It reads an label from the stream and gives back which edge belongs to
   2.168      /// it. It is possible only if there was read a "label" named edge map.
   2.169      void readLabel(std::istream& is, Edge& edge) const {
   2.170 -      return u_edgeset_reader.readLabel(is, edge);
   2.171 +      return uedgeset_reader.readLabel(is, edge);
   2.172      } 
   2.173  
   2.174      /// \brief Gives back the undirected edge by its label.
   2.175 @@ -705,7 +705,7 @@
   2.176      /// belongs to it. It is possible only if there was read a "label" named 
   2.177      /// edge map.
   2.178      void readLabel(std::istream& is, UEdge& uedge) const {
   2.179 -      return u_edgeset_reader.readLabel(is, uedge);
   2.180 +      return uedgeset_reader.readLabel(is, uedge);
   2.181      } 
   2.182      
   2.183  
   2.184 @@ -717,10 +717,10 @@
   2.185      DefaultSkipper skipper;
   2.186  
   2.187      NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   2.188 -    UEdgeSetReader<Graph, ReaderTraits> u_edgeset_reader;
   2.189 +    UEdgeSetReader<Graph, ReaderTraits> uedgeset_reader;
   2.190  
   2.191      NodeReader<Graph> node_reader;
   2.192 -    UEdgeReader<Graph> u_edge_reader;
   2.193 +    UEdgeReader<Graph> uedge_reader;
   2.194      
   2.195      AttributeReader<ReaderTraits> attribute_reader;
   2.196    };
     3.1 --- a/lemon/graph_writer.h	Tue Aug 28 13:58:54 2007 +0000
     3.2 +++ b/lemon/graph_writer.h	Tue Aug 28 14:00:42 2007 +0000
     3.3 @@ -251,9 +251,17 @@
     3.4        writer->run();
     3.5      }
     3.6  
     3.7 +    /// \brief Returns true if the writer can give back the labels by the items.
     3.8 +    ///
     3.9 +    /// Returns true if the writer can give back the the labels by the items.
    3.10 +    bool isLabelWriter() const {
    3.11 +      return nodeset_writer.isLabelWriter() && 
    3.12 +        edgeset_writer.isLabelWriter();
    3.13 +    }
    3.14 +
    3.15      /// \brief Write the label of the given node.
    3.16      ///
    3.17 -    /// It writes the label of the given node. If there was written an "label"
    3.18 +    /// It writes the label of the given node. If there was written a "label"
    3.19      /// named node map then it will write the map value belonging to the node.
    3.20      void writeLabel(std::ostream& os, const Node& item) const {
    3.21        nodeset_writer.writeLabel(os, item);
    3.22 @@ -261,12 +269,32 @@
    3.23  
    3.24      /// \brief Write the label of the given edge.
    3.25      ///
    3.26 -    /// It writes the label of the given edge. If there was written an "label"
    3.27 +    /// It writes the label of the given edge. If there was written a "label"
    3.28      /// named edge map then it will write the map value belonging to the edge.
    3.29      void writeLabel(std::ostream& os, const Edge& item) const {
    3.30        edgeset_writer.writeLabel(os, item);
    3.31      } 
    3.32  
    3.33 +    /// \brief Sorts the given node vector by label.
    3.34 +    ///
    3.35 +    /// Sorts the given node vector by label. If there was written an
    3.36 +    /// "label" named map then the vector will be sorted by the values
    3.37 +    /// of this map. Otherwise if the \c forceLabel parameter was true
    3.38 +    /// it will be sorted by its id in the graph.
    3.39 +    void sortByLabel(std::vector<Node>& nodes) const {
    3.40 +      nodeset_writer.sortByLabel(nodes);
    3.41 +    }
    3.42 +
    3.43 +    /// \brief Sorts the given edge vector by label.
    3.44 +    ///
    3.45 +    /// Sorts the given edge vector by label. If there was written an
    3.46 +    /// "label" named map then the vector will be sorted by the values
    3.47 +    /// of this map. Otherwise if the \c forceLabel parameter was true
    3.48 +    /// it will be sorted by its id in the graph.
    3.49 +    void sortByLabel(std::vector<Edge>& edges) const {
    3.50 +      edgeset_writer.sortByLabel(edges);
    3.51 +    }
    3.52 +
    3.53    private:
    3.54  
    3.55      LemonWriter* writer;
    3.56 @@ -370,9 +398,9 @@
    3.57      UGraphWriter(std::ostream& _os, const Graph& _graph) 
    3.58        : writer(new LemonWriter(_os)), own_writer(true), 
    3.59  	nodeset_writer(*writer, _graph, std::string()),
    3.60 -	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
    3.61 +	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
    3.62  	node_writer(*writer, nodeset_writer, std::string()),
    3.63 -	u_edge_writer(*writer, u_edgeset_writer, std::string()),
    3.64 +	uedge_writer(*writer, uedgeset_writer, std::string()),
    3.65  	attribute_writer(*writer, std::string()) {}
    3.66  
    3.67      /// \brief Construct a new UGraphWriter.
    3.68 @@ -382,21 +410,21 @@
    3.69      UGraphWriter(const std::string& _filename, const Graph& _graph) 
    3.70        : writer(new LemonWriter(_filename)), own_writer(true), 
    3.71  	nodeset_writer(*writer, _graph, std::string()),
    3.72 -	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
    3.73 +	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
    3.74  	node_writer(*writer, nodeset_writer, std::string()),
    3.75 -	u_edge_writer(*writer, u_edgeset_writer, std::string()),
    3.76 +	uedge_writer(*writer, uedgeset_writer, std::string()),
    3.77  	attribute_writer(*writer, std::string()) {}
    3.78  
    3.79      /// \brief Construct a new UGraphWriter.
    3.80      ///
    3.81      /// Construct a new UGraphWriter. It writes the given graph
    3.82 -    /// to given LemonReader.
    3.83 +    /// to given LemonWriter.
    3.84      UGraphWriter(LemonWriter& _writer, const Graph& _graph)
    3.85        : writer(_writer), own_writer(false), 
    3.86  	nodeset_writer(*writer, _graph, std::string()),
    3.87 -	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
    3.88 +	uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
    3.89  	node_writer(*writer, nodeset_writer, std::string()),
    3.90 -	u_edge_writer(*writer, u_edgeset_writer, std::string()),
    3.91 +	uedge_writer(*writer, uedgeset_writer, std::string()),
    3.92  	attribute_writer(*writer, std::string()) {}
    3.93  
    3.94      /// \brief Destruct the graph writer.
    3.95 @@ -434,7 +462,7 @@
    3.96      /// the writer.
    3.97      template <typename Map>
    3.98      UGraphWriter& writeEdgeMap(std::string label, const Map& map) { 
    3.99 -      u_edgeset_writer.writeEdgeMap(label, map);
   3.100 +      uedgeset_writer.writeEdgeMap(label, map);
   3.101        return *this;
   3.102      }
   3.103  
   3.104 @@ -445,7 +473,7 @@
   3.105      template <typename ItemWriter, typename Map>
   3.106      UGraphWriter& writeEdgeMap(std::string label, const Map& map,
   3.107  				   const ItemWriter& iw = ItemWriter()) {
   3.108 -      u_edgeset_writer.writeEdgeMap(label, map, iw);
   3.109 +      uedgeset_writer.writeEdgeMap(label, map, iw);
   3.110        return *this;
   3.111      }
   3.112  
   3.113 @@ -455,7 +483,7 @@
   3.114      /// command</i> to the writer.
   3.115      template <typename Map>
   3.116      UGraphWriter& writeUEdgeMap(std::string label, const Map& map) { 
   3.117 -      u_edgeset_writer.writeUEdgeMap(label, map);
   3.118 +      uedgeset_writer.writeUEdgeMap(label, map);
   3.119        return *this;
   3.120      }
   3.121  
   3.122 @@ -466,7 +494,7 @@
   3.123     template <typename ItemWriter, typename Map>
   3.124      UGraphWriter& writeUEdgeMap(std::string label, const Map& map,
   3.125  					const ItemWriter& iw = ItemWriter()) {
   3.126 -      u_edgeset_writer.writeUEdgeMap(label, map, iw);
   3.127 +      uedgeset_writer.writeUEdgeMap(label, map, iw);
   3.128        return *this;
   3.129      }
   3.130  
   3.131 @@ -484,7 +512,7 @@
   3.132      /// This function issues a new <i> labeled edge writing
   3.133      /// command</i> to the writer.
   3.134      UGraphWriter& writeEdge(std::string label, const Edge& edge) {
   3.135 -      u_edge_writer.writeEdge(label, edge);
   3.136 +      uedge_writer.writeEdge(label, edge);
   3.137      }
   3.138  
   3.139      /// \brief Issue a new labeled undirected edge writing command to
   3.140 @@ -493,7 +521,7 @@
   3.141      /// Issue a new <i>labeled undirected edge writing command</i> to
   3.142      /// the writer.
   3.143      UGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
   3.144 -      u_edge_writer.writeUEdge(label, edge);
   3.145 +      uedge_writer.writeUEdge(label, edge);
   3.146      }
   3.147  
   3.148      /// \brief Issue a new attribute writing command.
   3.149 @@ -534,9 +562,17 @@
   3.150        writer->run();
   3.151      }
   3.152  
   3.153 +    /// \brief Returns true if the writer can give back the labels by the items.
   3.154 +    ///
   3.155 +    /// Returns true if the writer can give back the the labels by the items.
   3.156 +    bool isLabelWriter() const {
   3.157 +      return nodeset_writer.isLabelWriter() && 
   3.158 +        uedgeset_writer.isLabelWriter();
   3.159 +    }
   3.160 +
   3.161      /// \brief Write the label of the given node.
   3.162      ///
   3.163 -    /// It writes the label of the given node. If there was written an "label"
   3.164 +    /// It writes the label of the given node. If there was written a "label"
   3.165      /// named node map then it will write the map value belonging to the node.
   3.166      void writeLabel(std::ostream& os, const Node& item) const {
   3.167        nodeset_writer.writeLabel(os, item);
   3.168 @@ -544,21 +580,50 @@
   3.169  
   3.170      /// \brief Write the label of the given edge.
   3.171      ///
   3.172 -    /// It writes the label of the given edge. If there was written an "label"
   3.173 +    /// It writes the label of the given edge. If there was written a "label"
   3.174      /// named edge map then it will write the map value belonging to the edge.
   3.175      void writeLabel(std::ostream& os, const Edge& item) const {
   3.176 -      u_edgeset_writer.writeLabel(os, item);
   3.177 +      uedgeset_writer.writeLabel(os, item);
   3.178      } 
   3.179  
   3.180      /// \brief Write the label of the given undirected edge.
   3.181      ///
   3.182      /// It writes the label of the given undirected edge. If there was
   3.183 -    /// written an "label" named edge map then it will write the map
   3.184 +    /// written a "label" named edge map then it will write the map
   3.185      /// value belonging to the edge.
   3.186      void writeLabel(std::ostream& os, const UEdge& item) const {
   3.187 -      u_edgeset_writer.writeLabel(os, item);
   3.188 +      uedgeset_writer.writeLabel(os, item);
   3.189      } 
   3.190  
   3.191 +    /// \brief Sorts the given node vector by label.
   3.192 +    ///
   3.193 +    /// Sorts the given node vector by label. If there was written an
   3.194 +    /// "label" named map then the vector will be sorted by the values
   3.195 +    /// of this map. Otherwise if the \c forceLabel parameter was true
   3.196 +    /// it will be sorted by its id in the graph.
   3.197 +    void sortByLabel(std::vector<Node>& nodes) const {
   3.198 +      nodeset_writer.sortByLabel(nodes);
   3.199 +    }
   3.200 +
   3.201 +    /// \brief Sorts the given edge vector by label.
   3.202 +    ///
   3.203 +    /// Sorts the given edge vector by label. If there was written an
   3.204 +    /// "label" named map then the vector will be sorted by the values
   3.205 +    /// of this map. Otherwise if the \c forceLabel parameter was true
   3.206 +    /// it will be sorted by its id in the graph.
   3.207 +    void sortByLabel(std::vector<Edge>& edges) const {
   3.208 +      uedgeset_writer.sortByLabel(edges);
   3.209 +    }
   3.210 +
   3.211 +    /// \brief Sorts the given undirected edge vector by label.
   3.212 +    ///
   3.213 +    /// Sorts the given undirected edge vector by label. If there was
   3.214 +    /// written an "label" named map then the vector will be sorted by
   3.215 +    /// the values of this map. Otherwise if the \c forceLabel
   3.216 +    /// parameter was true it will be sorted by its id in the graph.
   3.217 +    void sortByLabel(std::vector<UEdge>& uedges) const {
   3.218 +      uedgeset_writer.sortByLabel(uedges);
   3.219 +    }
   3.220  
   3.221    private:
   3.222  
   3.223 @@ -566,10 +631,10 @@
   3.224      bool own_writer;
   3.225  
   3.226      NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   3.227 -    UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
   3.228 +    UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
   3.229  
   3.230      NodeWriter<Graph> node_writer;
   3.231 -    UEdgeWriter<Graph> u_edge_writer;
   3.232 +    UEdgeWriter<Graph> uedge_writer;
   3.233      
   3.234      AttributeWriter<WriterTraits> attribute_writer;
   3.235    };
     4.1 --- a/lemon/lemon_reader.h	Tue Aug 28 13:58:54 2007 +0000
     4.2 +++ b/lemon/lemon_reader.h	Tue Aug 28 14:00:42 2007 +0000
     4.3 @@ -58,7 +58,7 @@
     4.4  	return p < q;
     4.5        }
     4.6      };
     4.7 -
     4.8 +    
     4.9      template <typename Item>
    4.10      class ItemLabelReader {
    4.11      public:
    4.12 @@ -255,7 +255,7 @@
    4.13  	  return it->second;
    4.14  	} else {
    4.15  	  ErrorMessage msg;
    4.16 -	  msg << "Invalid label error: " << value; 
    4.17 +	  msg << "Invalid label error"; 
    4.18  	  throw DataFormatError(msg.message());
    4.19  	}
    4.20        }      
    4.21 @@ -289,7 +289,7 @@
    4.22  
    4.23        virtual Item read(std::istream& is) const {
    4.24  	Value value;
    4.25 -	reader.read(is, value);	
    4.26 +	reader.read(is, value);
    4.27  	typename Inverse::const_iterator it = inverse.find(value);
    4.28  	if (it != inverse.end()) {
    4.29  	  return it->second;
    4.30 @@ -382,6 +382,7 @@
    4.31        virtual ~LabelReaderBase() {}
    4.32        virtual Item read(std::istream& is) const = 0;
    4.33        virtual bool isLabelReader() const = 0;
    4.34 +      virtual LabelReaderBase<_Item>* clone() const = 0;
    4.35      };
    4.36  
    4.37      template <typename _Item, typename _BoxedLabelReader>
    4.38 @@ -390,19 +391,23 @@
    4.39        typedef _Item Item;
    4.40        typedef _BoxedLabelReader BoxedLabelReader;
    4.41        
    4.42 -      const BoxedLabelReader& boxedLabelReader;
    4.43 -
    4.44 -      LabelReader(const BoxedLabelReader& _boxedLabelReader) 
    4.45 -	: boxedLabelReader(_boxedLabelReader) {}
    4.46 +      const BoxedLabelReader& labelReader;
    4.47 +
    4.48 +      LabelReader(const BoxedLabelReader& _labelReader) 
    4.49 +	: labelReader(_labelReader) {}
    4.50  
    4.51        virtual Item read(std::istream& is) const {
    4.52  	Item item;
    4.53 -	boxedLabelReader.readLabel(is, item);
    4.54 +	labelReader.readLabel(is, item);
    4.55  	return item;
    4.56        }
    4.57  
    4.58        virtual bool isLabelReader() const {
    4.59 -	return boxedLabelReader.isLabelReader();
    4.60 +	return labelReader.isLabelReader();
    4.61 +      }
    4.62 +      
    4.63 +      LabelReader<Item, BoxedLabelReader>* clone() const {
    4.64 +	return new LabelReader<Item, BoxedLabelReader>(labelReader);
    4.65        }
    4.66      };
    4.67  
    4.68 @@ -723,7 +728,6 @@
    4.69  	    it->second = true;
    4.70  	    char buf[2048];
    4.71  	    FilterStreamBuf buffer(*is, line_num);
    4.72 -
    4.73  	    try {
    4.74  	      buffer.pubsetbuf(buf, sizeof(buf));
    4.75  	      std::istream ss(&buffer);
    4.76 @@ -1511,8 +1515,8 @@
    4.77      ///
    4.78      /// It reads an id from the stream and gives back which undirected edge 
    4.79      /// belongs to it. It is possible only if there was read an "label" named map.
    4.80 -    void readLabel(std::istream& is, UEdge& uEdge) const {
    4.81 -      uEdge = inverter->read(is);
    4.82 +    void readLabel(std::istream& is, UEdge& uedge) const {
    4.83 +      uedge = inverter->read(is);
    4.84      } 
    4.85  
    4.86      /// \brief Gives back the directed edge by its label.
    4.87 @@ -1524,11 +1528,11 @@
    4.88      void readLabel(std::istream& is, Edge& edge) const {
    4.89        char c;
    4.90        is >> c;
    4.91 -      UEdge uEdge = inverter->read(is);
    4.92 +      UEdge uedge = inverter->read(is);
    4.93        if (c == '+') {
    4.94 -	edge = graph.direct(uEdge, true);
    4.95 +	edge = graph.direct(uedge, true);
    4.96        } else if (c == '-') {
    4.97 -        edge = graph.direct(uEdge, false);
    4.98 +        edge = graph.direct(uedge, false);
    4.99        } else {
   4.100  	throw DataFormatError("Wrong id format for edge "
   4.101  			      "in undirected edgeset");
   4.102 @@ -1807,10 +1811,10 @@
   4.103        : Parent(_reader), name(_name) {
   4.104        checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
   4.105        checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
   4.106 -      uEdgeLabelReader.reset(new _reader_bits::
   4.107 -			      LabelReader<UEdge, _LabelReader>(_labelReader));
   4.108 +      uedgeLabelReader.reset(new _reader_bits::
   4.109 +			     LabelReader<UEdge, _LabelReader>(_labelReader));
   4.110        edgeLabelReader.reset(new _reader_bits::
   4.111 -			 LabelReader<Edge, _LabelReader>(_labelReader));
   4.112 +			    LabelReader<Edge, _LabelReader>(_labelReader));
   4.113      }
   4.114  
   4.115      /// \brief Destructor.
   4.116 @@ -1827,12 +1831,12 @@
   4.117      ///
   4.118      /// Add an undirected edge reader command for the UEdgeReader.
   4.119      void readUEdge(std::string label, UEdge& item) {
   4.120 -      if (uEdgeReaders.find(label) != uEdgeReaders.end()) {
   4.121 +      if (uedgeReaders.find(label) != uedgeReaders.end()) {
   4.122  	ErrorMessage msg;
   4.123  	msg << "Multiple read rule for undirected edge: " << label;
   4.124  	throw IoParameterError(msg.message());
   4.125        }
   4.126 -      uEdgeReaders.insert(make_pair(label, _reader_bits::
   4.127 +      uedgeReaders.insert(make_pair(label, _reader_bits::
   4.128  					ItemStore<UEdge>(item)));
   4.129      }
   4.130  
   4.131 @@ -1870,7 +1874,7 @@
   4.132        if (!edgeLabelReader->isLabelReader()) {
   4.133  	throw DataFormatError("Cannot find undirected edgeset or label map");
   4.134        }
   4.135 -      if (!uEdgeLabelReader->isLabelReader()) {
   4.136 +      if (!uedgeLabelReader->isLabelReader()) {
   4.137  	throw DataFormatError("Cannot find undirected edgeset or label map");
   4.138        }
   4.139        std::string line;
   4.140 @@ -1879,9 +1883,9 @@
   4.141  	std::string id;
   4.142  	ls >> id;
   4.143  	{
   4.144 -	  typename UEdgeReaders::iterator it = uEdgeReaders.find(id);
   4.145 -	  if (it != uEdgeReaders.end()) {
   4.146 -	    it->second.read(uEdgeLabelReader->read(ls));
   4.147 +	  typename UEdgeReaders::iterator it = uedgeReaders.find(id);
   4.148 +	  if (it != uedgeReaders.end()) {
   4.149 +	    it->second.read(uedgeLabelReader->read(ls));
   4.150  	    it->second.touch();
   4.151  	    continue;
   4.152  	  }	
   4.153 @@ -1902,8 +1906,8 @@
   4.154  	  throw IoParameterError(msg.message());
   4.155  	}
   4.156        }
   4.157 -      for (typename UEdgeReaders::iterator it = uEdgeReaders.begin();
   4.158 -	   it != uEdgeReaders.end(); ++it) {
   4.159 +      for (typename UEdgeReaders::iterator it = uedgeReaders.begin();
   4.160 +	   it != uedgeReaders.end(); ++it) {
   4.161  	if (!it->second.touched()) {
   4.162  	  ErrorMessage msg;
   4.163  	  msg << "UEdge not found in file: " << it->first;
   4.164 @@ -1913,7 +1917,7 @@
   4.165      }
   4.166  
   4.167      virtual void missing() {
   4.168 -      if (edgeReaders.empty() && uEdgeReaders.empty()) return;
   4.169 +      if (edgeReaders.empty() && uedgeReaders.empty()) return;
   4.170        ErrorMessage msg;
   4.171        msg << "UEdges section not found in file: @uedges " << name;
   4.172        throw IoParameterError(msg.message());
   4.173 @@ -1925,8 +1929,8 @@
   4.174  
   4.175      typedef std::map<std::string, 
   4.176  		     _reader_bits::ItemStore<UEdge> > UEdgeReaders;
   4.177 -    UEdgeReaders uEdgeReaders;
   4.178 -    std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uEdgeLabelReader;
   4.179 +    UEdgeReaders uedgeReaders;
   4.180 +    std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uedgeLabelReader;
   4.181  
   4.182      typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
   4.183      EdgeReaders edgeReaders;
   4.184 @@ -2054,6 +2058,671 @@
   4.185    };
   4.186  
   4.187    /// \ingroup section_io
   4.188 +  /// \brief SectionReader for reading extra node maps.
   4.189 +  ///
   4.190 +  /// The lemon format can store maps in the nodeset sections. This
   4.191 +  /// class let you make distinict section to store maps.  The main
   4.192 +  /// purpose of this class is a logical separation of some maps. The
   4.193 +  /// other useful application could be to store paths in node maps.
   4.194 +  ///
   4.195 +  /// The first line of the section contains the names of the maps
   4.196 +  /// separated with white spaces. Each next line describes an item
   4.197 +  /// in the itemset, and contains in the first column the label of
   4.198 +  /// the item and then the mapped values for each map.
   4.199 +  ///
   4.200 +  /// \relates LemonReader
   4.201 +  template <typename _Graph, typename _Traits = DefaultReaderTraits>
   4.202 +  class NodeMapReader : public LemonReader::SectionReader {
   4.203 +    typedef LemonReader::SectionReader Parent;
   4.204 +  public:
   4.205 +
   4.206 +    typedef _Graph Graph;
   4.207 +    typedef typename Graph::Node Node;
   4.208 +    typedef _Traits Traits;
   4.209 +    typedef typename Traits::Skipper DefaultSkipper;
   4.210 +
   4.211 +    /// \brief Constructor.
   4.212 +    ///
   4.213 +    /// Constructor for NodeMapReader. It creates the NodeMapReader and
   4.214 +    /// attach it into the given LemonReader. The reader will read
   4.215 +    /// the section when the \c section_name and the \c _name are the same.
   4.216 +    template <typename _LabelReader>
   4.217 +    NodeMapReader(LemonReader& _reader, 
   4.218 +		  const Graph& _graph, 
   4.219 +		  const _LabelReader& _labelReader,
   4.220 +		  const std::string& _name = std::string(),
   4.221 +		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   4.222 +      : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
   4.223 +      labelReader.reset(new _reader_bits::
   4.224 +			LabelReader<Node, _LabelReader>(_labelReader));
   4.225 +    } 
   4.226 +
   4.227 +
   4.228 +    /// \brief Destructor.
   4.229 +    ///
   4.230 +    /// Destructor for NodeMapReader.
   4.231 +    virtual ~NodeMapReader() {
   4.232 +      for (typename MapReaders::iterator it = readers.begin(); 
   4.233 +	   it != readers.end(); ++it) {
   4.234 +	delete it->second;
   4.235 +      }
   4.236 +    }
   4.237 +
   4.238 +  private:
   4.239 +    NodeMapReader(const NodeMapReader&);
   4.240 +    void operator=(const NodeMapReader&);
   4.241 +  
   4.242 +  public:
   4.243 +
   4.244 +    /// \brief Add a new node map reader command for the reader.
   4.245 +    ///
   4.246 +    /// Add a new node map reader command for the reader.
   4.247 +    template <typename Map>
   4.248 +    NodeMapReader& readNodeMap(std::string label, Map& map) {
   4.249 +      return _readMap<
   4.250 +	typename Traits::template Reader<typename Map::Value>, Map,
   4.251 +	typename _reader_bits::Arg<Map>::Type>(label, map);
   4.252 +    }
   4.253 +
   4.254 +    template <typename Map>
   4.255 +    NodeMapReader& readNodeMap(std::string label, const Map& map) {
   4.256 +      return _readMap<
   4.257 +	typename Traits::template Reader<typename Map::Value>, Map,
   4.258 +	typename _reader_bits::Arg<Map>::Type>(label, map);
   4.259 +    }
   4.260 +
   4.261 +    /// \brief Add a new node map reader command for the reader.
   4.262 +    ///
   4.263 +    /// Add a new node map reader command for the reader.
   4.264 +    template <typename ItemReader, typename Map>
   4.265 +    NodeMapReader& readNodeMap(std::string label, Map& map, 
   4.266 +			       const ItemReader& ir = ItemReader()) {
   4.267 +      return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
   4.268 +	(label, map, ir);
   4.269 +    }
   4.270 +
   4.271 +    template <typename ItemReader, typename Map>
   4.272 +    NodeMapReader& readNodeMap(std::string label, const Map& map, 
   4.273 +			       const ItemReader& ir = ItemReader()) {
   4.274 +      return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
   4.275 +	(label, map, ir);
   4.276 +    }
   4.277 +
   4.278 +  private:
   4.279 +
   4.280 +    template <typename ItemReader, typename Map, typename MapParameter>
   4.281 +    NodeMapReader& _readMap(std::string label, MapParameter map, 
   4.282 +			   const ItemReader& ir = ItemReader()) {
   4.283 +      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   4.284 +      checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
   4.285 +      if (readers.find(label) != readers.end()) {
   4.286 +	ErrorMessage msg;
   4.287 +	msg << "Multiple read rule for map: " << label;
   4.288 +	throw IoParameterError(msg.message());
   4.289 +      }      
   4.290 +      readers.insert(
   4.291 +	make_pair(label, new _reader_bits::
   4.292 +		  MapReader<Node, Map, ItemReader>(map, ir)));
   4.293 +      return *this;
   4.294 +    }
   4.295 +
   4.296 +  public:
   4.297 +
   4.298 +    /// \brief Add a new node map skipper command for the reader.
   4.299 +    ///
   4.300 +    /// Add a new node map skipper command for the reader.
   4.301 +    template <typename ItemReader>
   4.302 +    NodeMapReader& skipNodeMap(std::string label, 
   4.303 +			       const ItemReader& ir = ItemReader()) {
   4.304 +      if (readers.find(label) != readers.end()) {
   4.305 +	ErrorMessage msg;
   4.306 +	msg << "Multiple read rule for map: " << label;
   4.307 +	throw IoParameterError(msg.message());
   4.308 +      }
   4.309 +      readers.insert(make_pair(label, new _reader_bits::
   4.310 +			       SkipReader<Node, ItemReader>(ir)));
   4.311 +      return *this;
   4.312 +    }
   4.313 +
   4.314 +  protected:
   4.315 +
   4.316 +    /// \brief Gives back true when the SectionReader can process 
   4.317 +    /// the section with the given header line.
   4.318 +    ///
   4.319 +    /// It gives back true when the header line starts with \c \@mapset,
   4.320 +    /// and the header line's name and the mapset's name are the same.
   4.321 +    virtual bool header(const std::string& line) {
   4.322 +      std::istringstream ls(line);
   4.323 +      std::string command;
   4.324 +      std::string id;
   4.325 +      ls >> command >> id;
   4.326 +      return command == "@nodemaps" && name == id;
   4.327 +    }
   4.328 +
   4.329 +    /// \brief Reader function of the section.
   4.330 +    ///
   4.331 +    /// It reads the content of the section.
   4.332 +    virtual void read(std::istream& is) {
   4.333 +      std::vector<_reader_bits::MapReaderBase<Node>* > index;
   4.334 +      std::string line;
   4.335 +
   4.336 +      {
   4.337 +        getline(is, line);
   4.338 +        std::istringstream ls(line);
   4.339 +        std::string id;
   4.340 +        while (ls >> id) {
   4.341 +          typename MapReaders::iterator it = readers.find(id);
   4.342 +          if (it != readers.end()) {
   4.343 +            it->second->touch();
   4.344 +            index.push_back(it->second);
   4.345 +          } else {
   4.346 +            index.push_back(&skipper);
   4.347 +          }
   4.348 +        }
   4.349 +      }
   4.350 +      for (typename MapReaders::iterator it = readers.begin();
   4.351 +	   it != readers.end(); ++it) {
   4.352 +	if (!it->second->touched()) {
   4.353 +	  ErrorMessage msg;
   4.354 +	  msg << "Map not found in file: " << it->first;
   4.355 +	  throw IoParameterError(msg.message());
   4.356 +	}
   4.357 +      }
   4.358 +      while (getline(is, line)) {	
   4.359 +	std::istringstream ls(line);
   4.360 +	Node node = labelReader->read(ls);
   4.361 +	for (int i = 0; i < int(index.size()); ++i) {
   4.362 +	  index[i]->read(ls, node);
   4.363 +	}
   4.364 +      }
   4.365 +    }
   4.366 +
   4.367 +    virtual void missing() {
   4.368 +      if (readers.empty()) return;
   4.369 +      ErrorMessage msg;
   4.370 +      msg << "NodeMap section not found in file: @nodemaps " << name;
   4.371 +      throw IoParameterError(msg.message());
   4.372 +    }
   4.373 +
   4.374 +  private:
   4.375 +
   4.376 +    typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
   4.377 +    MapReaders readers;
   4.378 +   
   4.379 +    const Graph& graph;   
   4.380 +    std::string name;
   4.381 +    _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
   4.382 +    std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader;
   4.383 +
   4.384 +  };
   4.385 +
   4.386 +  /// \ingroup section_io
   4.387 +  /// \brief SectionReader for reading extra edge maps.
   4.388 +  ///
   4.389 +  /// The lemon format can store maps in the edgeset sections. This
   4.390 +  /// class let you make distinict section to store maps.  The main
   4.391 +  /// purpose of this class is a logical separation of some maps. The
   4.392 +  /// other useful application could be to store paths in edge maps.
   4.393 +  ///
   4.394 +  /// The first line of the section contains the names of the maps
   4.395 +  /// separated with white spaces. Each next line describes an item
   4.396 +  /// in the itemset, and contains in the first column the label of
   4.397 +  /// the item and then the mapped values for each map.
   4.398 +  ///
   4.399 +  /// \relates LemonReader
   4.400 +  template <typename _Graph, typename _Traits = DefaultReaderTraits>
   4.401 +  class EdgeMapReader : public LemonReader::SectionReader {
   4.402 +    typedef LemonReader::SectionReader Parent;
   4.403 +  public:
   4.404 +
   4.405 +    typedef _Graph Graph;
   4.406 +    typedef typename Graph::Edge Edge;
   4.407 +    typedef _Traits Traits;
   4.408 +    typedef typename Traits::Skipper DefaultSkipper;
   4.409 +
   4.410 +    /// \brief Constructor.
   4.411 +    ///
   4.412 +    /// Constructor for EdgeMapReader. It creates the EdgeMapReader and
   4.413 +    /// attach it into the given LemonReader. The reader will read
   4.414 +    /// the section when the \c section_name and the \c _name are the same.
   4.415 +    template <typename _LabelReader>
   4.416 +    EdgeMapReader(LemonReader& _reader, 
   4.417 +		   const Graph& _graph, 
   4.418 +		   const _LabelReader& _labelReader,
   4.419 +		   const std::string& _name = std::string(),
   4.420 +		   const DefaultSkipper& _skipper = DefaultSkipper()) 
   4.421 +      : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
   4.422 +      labelReader.reset(new _reader_bits::
   4.423 +			LabelReader<Edge, _LabelReader>(_labelReader));
   4.424 +    } 
   4.425 +
   4.426 +
   4.427 +    /// \brief Destructor.
   4.428 +    ///
   4.429 +    /// Destructor for EdgeMapReader.
   4.430 +    virtual ~EdgeMapReader() {
   4.431 +      for (typename MapReaders::iterator it = readers.begin(); 
   4.432 +	   it != readers.end(); ++it) {
   4.433 +	delete it->second;
   4.434 +      }
   4.435 +    }
   4.436 +
   4.437 +  private:
   4.438 +    EdgeMapReader(const EdgeMapReader&);
   4.439 +    void operator=(const EdgeMapReader&);
   4.440 +  
   4.441 +  public:
   4.442 +
   4.443 +    /// \brief Add a new edge map reader command for the reader.
   4.444 +    ///
   4.445 +    /// Add a new edge map reader command for the reader.
   4.446 +    template <typename Map>
   4.447 +    EdgeMapReader& readEdgeMap(std::string label, Map& map) {
   4.448 +      return _readMap<
   4.449 +	typename Traits::template Reader<typename Map::Value>, Map,
   4.450 +	typename _reader_bits::Arg<Map>::Type>(label, map);
   4.451 +    }
   4.452 +
   4.453 +    template <typename Map>
   4.454 +    EdgeMapReader& readEdgeMap(std::string label, const Map& map) {
   4.455 +      return _readMap<
   4.456 +	typename Traits::template Reader<typename Map::Value>, Map,
   4.457 +	typename _reader_bits::Arg<Map>::Type>(label, map);
   4.458 +    }
   4.459 +
   4.460 +    /// \brief Add a new edge map reader command for the reader.
   4.461 +    ///
   4.462 +    /// Add a new edge map reader command for the reader.
   4.463 +    template <typename ItemReader, typename Map>
   4.464 +    EdgeMapReader& readEdgeMap(std::string label, Map& map, 
   4.465 +			  const ItemReader& ir = ItemReader()) {
   4.466 +      return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
   4.467 +	(label, map, ir);
   4.468 +    }
   4.469 +
   4.470 +    template <typename ItemReader, typename Map>
   4.471 +    EdgeMapReader& readEdgeMap(std::string label, const Map& map, 
   4.472 +			  const ItemReader& ir = ItemReader()) {
   4.473 +      return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
   4.474 +	(label, map, ir);
   4.475 +    }
   4.476 +
   4.477 +  private:
   4.478 +
   4.479 +    template <typename ItemReader, typename Map, typename MapParameter>
   4.480 +    EdgeMapReader& _readMap(std::string label, MapParameter map, 
   4.481 +				const ItemReader& ir = ItemReader()) {
   4.482 +      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
   4.483 +      checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
   4.484 +      if (readers.find(label) != readers.end()) {
   4.485 +	ErrorMessage msg;
   4.486 +	msg << "Multiple read rule for map: " << label;
   4.487 +	throw IoParameterError(msg.message());
   4.488 +      }      
   4.489 +      readers.insert(
   4.490 +	make_pair(label, new _reader_bits::
   4.491 +		  MapReader<Edge, Map, ItemReader>(map, ir)));
   4.492 +      return *this;
   4.493 +    }
   4.494 +
   4.495 +  public:
   4.496 +
   4.497 +    /// \brief Add a new edge map skipper command for the reader.
   4.498 +    ///
   4.499 +    /// Add a new edge map skipper command for the reader.
   4.500 +    template <typename ItemReader>
   4.501 +    EdgeMapReader& skipEdgeMap(std::string label, 
   4.502 +			  const ItemReader& ir = ItemReader()) {
   4.503 +      if (readers.find(label) != readers.end()) {
   4.504 +	ErrorMessage msg;
   4.505 +	msg << "Multiple read rule for map: " << label;
   4.506 +	throw IoParameterError(msg.message());
   4.507 +      }
   4.508 +      readers.insert(make_pair(label, new _reader_bits::
   4.509 +			       SkipReader<Edge, ItemReader>(ir)));
   4.510 +      return *this;
   4.511 +    }
   4.512 +
   4.513 +  protected:
   4.514 +
   4.515 +    /// \brief Gives back true when the SectionReader can process 
   4.516 +    /// the section with the given header line.
   4.517 +    ///
   4.518 +    /// It gives back true when the header line starts with \c \@mapset,
   4.519 +    /// and the header line's name and the mapset's name are the same.
   4.520 +    virtual bool header(const std::string& line) {
   4.521 +      std::istringstream ls(line);
   4.522 +      std::string command;
   4.523 +      std::string id;
   4.524 +      ls >> command >> id;
   4.525 +      return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
   4.526 +    }
   4.527 +
   4.528 +    /// \brief Reader function of the section.
   4.529 +    ///
   4.530 +    /// It reads the content of the section.
   4.531 +    virtual void read(std::istream& is) {
   4.532 +      std::vector<_reader_bits::MapReaderBase<Edge>* > index;
   4.533 +      std::string line;
   4.534 +
   4.535 +      {
   4.536 +        getline(is, line);
   4.537 +        std::istringstream ls(line);
   4.538 +        std::string id;
   4.539 +        while (ls >> id) {
   4.540 +          typename MapReaders::iterator it = readers.find(id);
   4.541 +          if (it != readers.end()) {
   4.542 +            it->second->touch();
   4.543 +            index.push_back(it->second);
   4.544 +          } else {
   4.545 +            index.push_back(&skipper);
   4.546 +          }
   4.547 +        }
   4.548 +      }
   4.549 +      for (typename MapReaders::iterator it = readers.begin();
   4.550 +	   it != readers.end(); ++it) {
   4.551 +	if (!it->second->touched()) {
   4.552 +	  ErrorMessage msg;
   4.553 +	  msg << "Map not found in file: " << it->first;
   4.554 +	  throw IoParameterError(msg.message());
   4.555 +	}
   4.556 +      }
   4.557 +      while (getline(is, line)) {	
   4.558 +	std::istringstream ls(line);
   4.559 +	Edge edge = labelReader->read(ls);
   4.560 +	for (int i = 0; i < int(index.size()); ++i) {
   4.561 +	  index[i]->read(ls, edge);
   4.562 +	}
   4.563 +      }
   4.564 +    }
   4.565 +
   4.566 +    virtual void missing() {
   4.567 +      if (readers.empty()) return;
   4.568 +      ErrorMessage msg;
   4.569 +      msg << "EdgeMap section not found in file: @edgemaps " << name;
   4.570 +      throw IoParameterError(msg.message());
   4.571 +    }
   4.572 +
   4.573 +  private:
   4.574 +
   4.575 +    typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
   4.576 +    MapReaders readers;
   4.577 +   
   4.578 +    const Graph& graph;   
   4.579 +    std::string name;
   4.580 +    _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
   4.581 +    std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader;
   4.582 +
   4.583 +  };
   4.584 +
   4.585 +  /// \ingroup section_io
   4.586 +  /// \brief SectionReader for reading extra undirected edge maps.
   4.587 +  ///
   4.588 +  /// The lemon format can store maps in the uedgeset sections. This
   4.589 +  /// class let you make distinict section to store maps.  The main
   4.590 +  /// purpose of this class is a logical separation of some maps. The
   4.591 +  /// other useful application could be to store paths in undirected
   4.592 +  /// edge maps.
   4.593 +  ///
   4.594 +  /// The first line of the section contains the names of the maps
   4.595 +  /// separated with white spaces. Each next line describes an item
   4.596 +  /// in the itemset, and contains in the first column the label of
   4.597 +  /// the item and then the mapped values for each map.
   4.598 +  ///
   4.599 +  /// \relates LemonReader
   4.600 +  template <typename _Graph, typename _Traits = DefaultReaderTraits>
   4.601 +  class UEdgeMapReader : public LemonReader::SectionReader {
   4.602 +    typedef LemonReader::SectionReader Parent;
   4.603 +  public:
   4.604 +
   4.605 +    typedef _Graph Graph;
   4.606 +    typedef typename Graph::Edge Edge;
   4.607 +    typedef typename Graph::UEdge UEdge;
   4.608 +    typedef _Traits Traits;
   4.609 +    typedef typename Traits::Skipper DefaultSkipper;
   4.610 +
   4.611 +    /// \brief Constructor.
   4.612 +    ///
   4.613 +    /// Constructor for UEdgeMapReader. It creates the UEdgeMapReader and
   4.614 +    /// attach it into the given LemonReader. The reader will read
   4.615 +    /// the section when the \c section_name and the \c _name are the same.
   4.616 +    template <typename _LabelReader>
   4.617 +    UEdgeMapReader(LemonReader& _reader, const Graph& _graph, 
   4.618 +		   const _LabelReader& _labelReader,
   4.619 +		   const std::string& _name = std::string(),
   4.620 +		   const DefaultSkipper& _skipper = DefaultSkipper()) 
   4.621 +      : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
   4.622 +      labelReader.reset(new _reader_bits::
   4.623 +			LabelReader<UEdge, _LabelReader>(_labelReader));
   4.624 +    } 
   4.625 +
   4.626 +
   4.627 +    /// \brief Destructor.
   4.628 +    ///
   4.629 +    /// Destructor for UEdgeMapReader.
   4.630 +    virtual ~UEdgeMapReader() {
   4.631 +      for (typename MapReaders::iterator it = readers.begin(); 
   4.632 +	   it != readers.end(); ++it) {
   4.633 +	delete it->second;
   4.634 +      }
   4.635 +    }
   4.636 +
   4.637 +  private:
   4.638 +    UEdgeMapReader(const UEdgeMapReader&);
   4.639 +    void operator=(const UEdgeMapReader&);
   4.640 +  
   4.641 +  public:
   4.642 +
   4.643 +    /// \brief Add a new undirected edge map reader command for the
   4.644 +    /// reader.
   4.645 +    ///
   4.646 +    /// Add a new undirected edge map reader command for the reader.
   4.647 +    template <typename Map>
   4.648 +    UEdgeMapReader& readUEdgeMap(std::string label, Map& map) {
   4.649 +      return _readMap<
   4.650 +	typename Traits::template Reader<typename Map::Value>, Map,
   4.651 +	typename _reader_bits::Arg<Map>::Type>(label, map);
   4.652 +    }
   4.653 +
   4.654 +    template <typename Map>
   4.655 +    UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) {
   4.656 +      return _readMap<
   4.657 +	typename Traits::template Reader<typename Map::Value>, Map,
   4.658 +	typename _reader_bits::Arg<Map>::Type>(label, map);
   4.659 +    }
   4.660 +
   4.661 +    /// \brief Add a new undirected edge map reader command for the
   4.662 +    /// reader.
   4.663 +    ///
   4.664 +    /// Add a new undirected edge map reader command for the reader.
   4.665 +    template <typename ItemReader, typename Map>
   4.666 +    UEdgeMapReader& readUEdgeMap(std::string label, Map& map, 
   4.667 +			  const ItemReader& ir = ItemReader()) {
   4.668 +      return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
   4.669 +	(label, map, ir);
   4.670 +    }
   4.671 +
   4.672 +    template <typename ItemReader, typename Map>
   4.673 +    UEdgeMapReader& readUEdgeMap(std::string label, const Map& map, 
   4.674 +			  const ItemReader& ir = ItemReader()) {
   4.675 +      return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
   4.676 +	(label, map, ir);
   4.677 +    }
   4.678 +
   4.679 +  private:
   4.680 +
   4.681 +    template <typename ItemReader, typename Map, typename MapParameter>
   4.682 +    UEdgeMapReader& _readMap(std::string label, MapParameter map, 
   4.683 +				const ItemReader& ir = ItemReader()) {
   4.684 +      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
   4.685 +      checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
   4.686 +      if (readers.find(label) != readers.end()) {
   4.687 +	ErrorMessage msg;
   4.688 +	msg << "Multiple read rule for map: " << label;
   4.689 +	throw IoParameterError(msg.message());
   4.690 +      }      
   4.691 +      readers.insert(
   4.692 +	make_pair(label, new _reader_bits::
   4.693 +		  MapReader<UEdge, Map, ItemReader>(map, ir)));
   4.694 +      return *this;
   4.695 +    }
   4.696 +
   4.697 +  public:
   4.698 +
   4.699 +    /// \brief Add a new undirected edge map skipper command for the
   4.700 +    /// reader.
   4.701 +    ///
   4.702 +    /// Add a new undirected edge map skipper command for the reader.
   4.703 +    template <typename ItemReader>
   4.704 +    UEdgeMapReader& skipUEdgeMap(std::string label, 
   4.705 +			  const ItemReader& ir = ItemReader()) {
   4.706 +      if (readers.find(label) != readers.end()) {
   4.707 +	ErrorMessage msg;
   4.708 +	msg << "Multiple read rule for map: " << label;
   4.709 +	throw IoParameterError(msg.message());
   4.710 +      }
   4.711 +      readers.insert(make_pair(label, new _reader_bits::
   4.712 +			       SkipReader<Edge, ItemReader>(ir)));
   4.713 +      return *this;
   4.714 +    }
   4.715 +
   4.716 +    /// \brief Add a new directed edge map reader command for the reader.
   4.717 +    ///
   4.718 +    /// Add a new directed edge map reader command for the reader.
   4.719 +    template <typename Map>
   4.720 +    UEdgeMapReader& readEdgeMap(std::string label, Map& map) {
   4.721 +      return _readDirMap<
   4.722 +	typename Traits::template Reader<typename Map::Value>, Map,
   4.723 +	typename _reader_bits::Arg<Map>::Type>(label, map);
   4.724 +    }
   4.725 +
   4.726 +    template <typename Map>
   4.727 +    UEdgeMapReader& readEdgeMap(std::string label, const Map& map) {
   4.728 +      return _readDirMap<
   4.729 +	typename Traits::template Reader<typename Map::Value>, Map,
   4.730 +	typename _reader_bits::Arg<Map>::Type>(label, map);
   4.731 +    }
   4.732 +
   4.733 +    /// \brief Add a new directed edge map reader command for the reader.
   4.734 +    ///
   4.735 +    /// Add a new directed edge map reader command for the reader.
   4.736 +    template <typename ItemReader, typename Map>
   4.737 +    UEdgeMapReader& readEdgeMap(std::string label, Map& map, 
   4.738 +				    const ItemReader& ir = ItemReader()) {
   4.739 +      return _readDirMap<ItemReader, Map, 
   4.740 +        typename _reader_bits::Arg<Map>::Type>(label, map, ir);
   4.741 +    }
   4.742 +
   4.743 +    template <typename ItemReader, typename Map>
   4.744 +    UEdgeMapReader& readEdgeMap(std::string label, const Map& map, 
   4.745 +				    const ItemReader& ir = ItemReader()) {
   4.746 +      return _readDirMap<ItemReader, Map, 
   4.747 +        typename _reader_bits::Arg<Map>::Type>(label, map, ir);
   4.748 +    }
   4.749 +
   4.750 +  private:
   4.751 +
   4.752 +    template <typename ItemReader, typename Map, typename MapParameter>
   4.753 +    UEdgeMapReader& _readDirMap(std::string label, MapParameter map,
   4.754 +				    const ItemReader& ir = ItemReader()) { 
   4.755 +      checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
   4.756 +      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
   4.757 +      readUEdgeMap("+" + label, 
   4.758 +                   _reader_bits::forwardComposeMap(graph, map), ir);
   4.759 +      readUEdgeMap("-" + label, 
   4.760 +                   _reader_bits::backwardComposeMap(graph, map), ir);
   4.761 +      return *this;      
   4.762 +    }
   4.763 +
   4.764 +  public:
   4.765 +
   4.766 +    /// \brief Add a new directed edge map skipper command for the reader.
   4.767 +    ///
   4.768 +    /// Add a new directed edge map skipper command for the reader.
   4.769 +    template <typename ItemReader>
   4.770 +    UEdgeMapReader& skipEdgeMap(std::string label, 
   4.771 +                                const ItemReader& ir = ItemReader()) {
   4.772 +      skipUEdgeMap("+" + label, ir);
   4.773 +      skipUEdgeMap("-" + label, ir);
   4.774 +      return *this;
   4.775 +    }
   4.776 +
   4.777 +  protected:
   4.778 +
   4.779 +    /// \brief Gives back true when the SectionReader can process 
   4.780 +    /// the section with the given header line.
   4.781 +    ///
   4.782 +    /// It gives back true when the header line starts with \c \@mapset,
   4.783 +    /// and the header line's name and the mapset's name are the same.
   4.784 +    virtual bool header(const std::string& line) {
   4.785 +      std::istringstream ls(line);
   4.786 +      std::string command;
   4.787 +      std::string id;
   4.788 +      ls >> command >> id;
   4.789 +      return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
   4.790 +    }
   4.791 +
   4.792 +    /// \brief Reader function of the section.
   4.793 +    ///
   4.794 +    /// It reads the content of the section.
   4.795 +    virtual void read(std::istream& is) {
   4.796 +      std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
   4.797 +      std::string line;
   4.798 +
   4.799 +      {
   4.800 +        getline(is, line);
   4.801 +        std::istringstream ls(line);
   4.802 +        std::string id;
   4.803 +        while (ls >> id) {
   4.804 +          typename MapReaders::iterator it = readers.find(id);
   4.805 +          if (it != readers.end()) {
   4.806 +            it->second->touch();
   4.807 +            index.push_back(it->second);
   4.808 +          } else {
   4.809 +            index.push_back(&skipper);
   4.810 +          }
   4.811 +        }
   4.812 +      }
   4.813 +      for (typename MapReaders::iterator it = readers.begin();
   4.814 +	   it != readers.end(); ++it) {
   4.815 +	if (!it->second->touched()) {
   4.816 +	  ErrorMessage msg;
   4.817 +	  msg << "Map not found in file: " << it->first;
   4.818 +	  throw IoParameterError(msg.message());
   4.819 +	}
   4.820 +      }
   4.821 +      while (getline(is, line)) {	
   4.822 +	std::istringstream ls(line);
   4.823 +	UEdge uedge = labelReader->read(ls);
   4.824 +	for (int i = 0; i < int(index.size()); ++i) {
   4.825 +	  index[i]->read(ls, uedge);
   4.826 +	}
   4.827 +      }
   4.828 +    }
   4.829 +
   4.830 +    virtual void missing() {
   4.831 +      if (readers.empty()) return;
   4.832 +      ErrorMessage msg;
   4.833 +      msg << "UEdgeMap section not found in file: @uedgemaps " << name;
   4.834 +      throw IoParameterError(msg.message());
   4.835 +    }
   4.836 +
   4.837 +  private:
   4.838 +
   4.839 +    const Graph& graph;   
   4.840 +    std::string name;
   4.841 +
   4.842 +    typedef std::map<std::string, 
   4.843 +		     _reader_bits::MapReaderBase<UEdge>*> MapReaders;
   4.844 +   
   4.845 +    MapReaders readers;
   4.846 +    _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
   4.847 +
   4.848 +    std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader;
   4.849 +
   4.850 +  };
   4.851 +
   4.852 +  /// \ingroup section_io
   4.853    /// \brief SectionReader for retrieve what is in the file.
   4.854    ///
   4.855    /// SectionReader for retrieve what is in the file. If you want
     5.1 --- a/lemon/lemon_writer.h	Tue Aug 28 13:58:54 2007 +0000
     5.2 +++ b/lemon/lemon_writer.h	Tue Aug 28 14:00:42 2007 +0000
     5.3 @@ -71,6 +71,22 @@
     5.4        Less<typename Map::Value> less;
     5.5      };
     5.6  
     5.7 +    template <typename UGraph, typename Map>
     5.8 +    struct UEdgeComposeLess {
     5.9 +      UEdgeComposeLess(const UGraph& _ugraph, const Map& _map) 
    5.10 +	: ugraph(_ugraph), map(_map), less() {}
    5.11 +
    5.12 +      bool operator()(const typename UGraph::Edge& p, 
    5.13 +                      const typename UGraph::Edge& q) const {
    5.14 +	return p != q ? less(map[p], map[q]) : 
    5.15 +	  (!ugraph.direction(p) && ugraph.direction(q));
    5.16 +      }
    5.17 +
    5.18 +      const UGraph& ugraph;
    5.19 +      const Map& map;
    5.20 +      Less<typename Map::Value> less;
    5.21 +    };
    5.22 +
    5.23      template <typename Item>
    5.24      class ItemLabelWriter {
    5.25      public:
    5.26 @@ -123,8 +139,8 @@
    5.27        ForwardComposeMap(const Graph& _graph, const Map& _map) 
    5.28  	: graph(_graph), map(_map) {}
    5.29        
    5.30 -      Value operator[](const Key& key) {
    5.31 -	return map[graph.direct(key, false)];
    5.32 +      Value operator[](const Key& key) const {
    5.33 +	return map[graph.direct(key, true)];
    5.34        }
    5.35  
    5.36      private:
    5.37 @@ -147,7 +163,7 @@
    5.38        BackwardComposeMap(const Graph& _graph, const Map& _map) 
    5.39  	: graph(_graph), map(_map) {}
    5.40        
    5.41 -      Value operator[](const Key& key) {
    5.42 +      Value operator[](const Key& key) const {
    5.43  	return map[graph.direct(key, false)];
    5.44        }
    5.45  
    5.46 @@ -199,7 +215,7 @@
    5.47        virtual ~MapWriterBase() {}
    5.48  
    5.49        virtual void write(std::ostream& os, const Item& item) const = 0;
    5.50 -      virtual void sortByMap(std::vector<Item>&) const = 0;
    5.51 +      virtual void sort(std::vector<Item>&) const = 0;
    5.52      };
    5.53  
    5.54  
    5.55 @@ -224,7 +240,59 @@
    5.56  	writer.write(os, value);
    5.57        }
    5.58  
    5.59 -      virtual void sortByMap(std::vector<Item>& items) const {
    5.60 +      virtual void sort(std::vector<Item>& items) const {
    5.61 +        ComposeLess<Map> less(map);
    5.62 +        std::sort(items.begin(), items.end(), less);
    5.63 +      }
    5.64 +
    5.65 +    };
    5.66 +
    5.67 +    template <typename _UGraph>    
    5.68 +    class UEdgeMapWriterBase {
    5.69 +    public:
    5.70 +      typedef typename _UGraph::Edge Edge;
    5.71 +      typedef typename _UGraph::UEdge UEdge;
    5.72 +
    5.73 +      typedef UEdge Item;
    5.74 +
    5.75 +      virtual ~UEdgeMapWriterBase() {}
    5.76 +
    5.77 +      virtual void write(std::ostream& os, const Item& item) const = 0;
    5.78 +      virtual void sort(const _UGraph&, std::vector<Edge>&) const = 0;
    5.79 +      virtual void sort(std::vector<UEdge>&) const = 0;
    5.80 +    };
    5.81 +
    5.82 +
    5.83 +    template <typename _UGraph, typename _Map, typename _Writer>
    5.84 +    class UEdgeMapWriter : public UEdgeMapWriterBase<_UGraph> {
    5.85 +    public:
    5.86 +      typedef _Map Map;
    5.87 +      typedef _Writer Writer;
    5.88 +      typedef typename Writer::Value Value;
    5.89 +
    5.90 +      typedef typename _UGraph::Edge Edge;
    5.91 +      typedef typename _UGraph::UEdge UEdge;
    5.92 +      typedef UEdge Item;
    5.93 +      
    5.94 +      typename _writer_bits::Ref<Map>::Type map;
    5.95 +      Writer writer;
    5.96 +
    5.97 +      UEdgeMapWriter(const Map& _map, const Writer& _writer) 
    5.98 +	: map(_map), writer(_writer) {}
    5.99 +
   5.100 +      virtual ~UEdgeMapWriter() {}
   5.101 +
   5.102 +      virtual void write(std::ostream& os, const Item& item) const {
   5.103 +	Value value = map[item];
   5.104 +	writer.write(os, value);
   5.105 +      }
   5.106 +
   5.107 +      virtual void sort(const _UGraph& ugraph, std::vector<Edge>& items) const {
   5.108 +        UEdgeComposeLess<_UGraph, Map> less(ugraph, map);
   5.109 +        std::sort(items.begin(), items.end(), less);
   5.110 +      }
   5.111 +
   5.112 +      virtual void sort(std::vector<UEdge>& items) const {
   5.113          ComposeLess<Map> less(map);
   5.114          std::sort(items.begin(), items.end(), less);
   5.115        }
   5.116 @@ -262,7 +330,9 @@
   5.117        typedef _Item Item;
   5.118        virtual ~LabelWriterBase() {}
   5.119        virtual void write(std::ostream&, const Item&) const = 0;
   5.120 +      virtual void sort(std::vector<Item>&) const = 0;
   5.121        virtual bool isLabelWriter() const = 0;
   5.122 +      virtual LabelWriterBase* clone() const = 0;
   5.123      };
   5.124  
   5.125      template <typename _Item, typename _BoxedLabelWriter>
   5.126 @@ -279,10 +349,17 @@
   5.127        virtual void write(std::ostream& os, const Item& item) const {
   5.128  	labelWriter.writeLabel(os, item);
   5.129        }
   5.130 +      virtual void sort(std::vector<Item>& items) const {
   5.131 +	labelWriter.sortByLabel(items);
   5.132 +      }
   5.133  
   5.134        virtual bool isLabelWriter() const {
   5.135  	return labelWriter.isLabelWriter();
   5.136        }
   5.137 +
   5.138 +      virtual LabelWriter* clone() const {
   5.139 +	return new LabelWriter(labelWriter);
   5.140 +      }
   5.141      };
   5.142  
   5.143    }
   5.144 @@ -425,7 +502,7 @@
   5.145    /// \c writeLabel() member will be called with a node it will write it's 
   5.146    /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   5.147    /// then the label map will be the id in the graph. In addition if the
   5.148 -  /// the \c _sortByLabel is true then the writer will write the edges
   5.149 +  /// the \c _forceSort is true then the writer will write the edges
   5.150    /// sorted by the labels.
   5.151    ///
   5.152    /// \relates LemonWriter
   5.153 @@ -444,13 +521,13 @@
   5.154      /// attach it into the given LemonWriter. If the \c _forceLabelMap
   5.155      /// parameter is true then the writer will write own label map when
   5.156      /// the user does not give "label" named map. In addition if the
   5.157 -    /// the \c _sortByLabel is true then the writer will write the edges
   5.158 +    /// the \c _forceSort is true then the writer will write the edges
   5.159      /// sorted by the labels.
   5.160      NodeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   5.161  		  const std::string& _name = std::string(), 
   5.162 -		  bool _forceLabelMap = true, bool _sortByLabel = true) 
   5.163 +		  bool _forceLabelMap = true, bool _forceSort = true) 
   5.164        : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), 
   5.165 -	sortByLabel(_sortByLabel), graph(_graph), name(_name) {}
   5.166 +	forceSort(_forceSort), graph(_graph), name(_name) {}
   5.167  
   5.168      /// \brief Destructor.
   5.169      ///
   5.170 @@ -515,9 +592,9 @@
   5.171        for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
   5.172          items.push_back(it);
   5.173        }
   5.174 -      if (sortByLabel) {
   5.175 +      if (forceSort) {
   5.176          if (labelMap) {
   5.177 -          labelMap->sortByMap(items);
   5.178 +          labelMap->sort(items);
   5.179          } else {
   5.180            typedef IdMap<Graph, Node> Map;
   5.181            Map map(graph);
   5.182 @@ -550,7 +627,7 @@
   5.183      /// \brief Returns true if the nodeset can write the labels of the nodes.
   5.184      ///
   5.185      /// Returns true if the nodeset can write the labels of the nodes.
   5.186 -    /// It is possible only if an "label" named map was written or the 
   5.187 +    /// It is possible only if a "label" named map was written or the 
   5.188      /// \c _forceLabelMap constructor parameter was true.
   5.189      bool isLabelWriter() const {
   5.190        return labelMap != 0 || forceLabelMap;
   5.191 @@ -558,7 +635,7 @@
   5.192  
   5.193      /// \brief Write the label of the given node.
   5.194      ///
   5.195 -    /// It writes the label of the given node. If there was written an "label"
   5.196 +    /// It writes the label of the given node. If there was written a "label"
   5.197      /// named map then it will write the map value belongs to the node.
   5.198      /// Otherwise if the \c forceLabel parameter was true it will write
   5.199      /// its label in the graph. 
   5.200 @@ -570,6 +647,23 @@
   5.201        }
   5.202      }
   5.203  
   5.204 +    /// \brief Sorts the given node vector by label.
   5.205 +    ///
   5.206 +    /// Sorts the given node vector by label. If there was written an
   5.207 +    /// "label" named map then the vector will be sorted by the values
   5.208 +    /// of this map. Otherwise if the \c forceLabel parameter was true
   5.209 +    /// it will be sorted by its id in the graph.
   5.210 +    void sortByLabel(std::vector<Node>& nodes) const {
   5.211 +      if (labelMap) {
   5.212 +	labelMap->sort(nodes);
   5.213 +      } else {
   5.214 +	typedef IdMap<Graph, Node> Map;
   5.215 +	Map map(graph);
   5.216 +	_writer_bits::ComposeLess<Map> less(map);
   5.217 +	std::sort(nodes.begin(), nodes.end(), less);
   5.218 +      }
   5.219 +    }
   5.220 +
   5.221    private:
   5.222  
   5.223      typedef std::vector<std::pair<std::string, _writer_bits::
   5.224 @@ -578,7 +672,7 @@
   5.225  
   5.226      _writer_bits::MapWriterBase<Node>* labelMap;
   5.227      bool forceLabelMap;
   5.228 -    bool sortByLabel;
   5.229 +    bool forceSort;
   5.230     
   5.231      const Graph& graph;   
   5.232      std::string name;
   5.233 @@ -602,7 +696,7 @@
   5.234    /// \c writeLabel() member will be called with an edge it will write it's 
   5.235    /// label. Otherwise if the \c _forceLabelMap constructor parameter is true 
   5.236    /// then the label map will be the id in the graph. In addition if the
   5.237 -  /// the \c _sortByLabel is true then the writer will write the edges
   5.238 +  /// the \c _forceSort is true then the writer will write the edges
   5.239    /// sorted by the labels.
   5.240    ///
   5.241    /// The edgeset writer needs a node label writer to identify which nodes
   5.242 @@ -627,15 +721,15 @@
   5.243      /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
   5.244      /// parameter is true then the writer will write own label map if
   5.245      /// the user does not give "label" named map. In addition if the
   5.246 -    /// the \c _sortByLabel is true then the writer will write the
   5.247 +    /// the \c _forceSort is true then the writer will write the
   5.248      /// edges sorted by the labels.
   5.249      template <typename NodeLabelWriter>
   5.250      EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   5.251  		  const NodeLabelWriter& _nodeLabelWriter, 
   5.252  		  const std::string& _name = std::string(),
   5.253 -		  bool _forceLabelMap = true, bool _sortByLabel = true)
   5.254 +		  bool _forceLabelMap = true, bool _forceSort = true)
   5.255        : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
   5.256 -	sortByLabel(_sortByLabel), graph(_graph), name(_name) {
   5.257 +	forceSort(_forceSort), graph(_graph), name(_name) {
   5.258        checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
   5.259        nodeLabelWriter.reset(new _writer_bits::
   5.260  			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   5.261 @@ -707,9 +801,9 @@
   5.262        for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
   5.263          items.push_back(it);
   5.264        }
   5.265 -      if (sortByLabel) {
   5.266 +      if (forceSort) {
   5.267          if (labelMap) {
   5.268 -          labelMap->sortByMap(items);
   5.269 +          labelMap->sort(items);
   5.270          } else {
   5.271            typedef IdMap<Graph, Edge> Map;
   5.272            Map map(graph);
   5.273 @@ -747,7 +841,7 @@
   5.274      /// \brief Returns true if the edgeset can write the labels of the edges.
   5.275      ///
   5.276      /// Returns true if the edgeset can write the labels of the edges.
   5.277 -    /// It is possible only if an "label" named map was written or the 
   5.278 +    /// It is possible only if a "label" named map was written or the 
   5.279      /// \c _forceLabelMap constructor parameter was true.
   5.280      bool isLabelWriter() const {
   5.281        return forceLabelMap || labelMap != 0;
   5.282 @@ -755,7 +849,7 @@
   5.283  
   5.284      /// \brief Write the label of the given edge.
   5.285      ///
   5.286 -    /// It writes the label of the given edge. If there was written an "label"
   5.287 +    /// It writes the label of the given edge. If there was written a "label"
   5.288      /// named map then it will write the map value belongs to the edge.
   5.289      /// Otherwise if the \c forceLabel parameter was true it will write
   5.290      /// its label in the graph. 
   5.291 @@ -767,6 +861,23 @@
   5.292        }
   5.293      } 
   5.294  
   5.295 +    /// \brief Sorts the given edge vector by label.
   5.296 +    ///
   5.297 +    /// Sorts the given edge vector by label. If there was written an
   5.298 +    /// "label" named map then the vector will be sorted by the values
   5.299 +    /// of this map. Otherwise if the \c forceLabel parameter was true
   5.300 +    /// it will be sorted by its id in the graph.
   5.301 +    void sortByLabel(std::vector<Edge>& edges) const {
   5.302 +      if (labelMap) {
   5.303 +	labelMap->sort(edges);
   5.304 +      } else {
   5.305 +	typedef IdMap<Graph, Edge> Map;
   5.306 +	Map map(graph);
   5.307 +	_writer_bits::ComposeLess<Map> less(map);
   5.308 +	std::sort(edges.begin(), edges.end(), less);
   5.309 +      }
   5.310 +    }
   5.311 +
   5.312    private:
   5.313  
   5.314      typedef std::vector<std::pair<std::string, _writer_bits::
   5.315 @@ -775,7 +886,7 @@
   5.316  
   5.317      _writer_bits::MapWriterBase<Edge>* labelMap;
   5.318      bool forceLabelMap;
   5.319 -    bool sortByLabel;
   5.320 +    bool forceSort;
   5.321     
   5.322      const Graph& graph;   
   5.323      std::string name;
   5.324 @@ -807,7 +918,7 @@
   5.325    /// an undirected edge it will write it's label. Otherwise if the \c
   5.326    /// _forceLabelMap constructor parameter is true then the label map
   5.327    /// will be the id in the graph.  In addition if the the \c
   5.328 -  /// _sortByLabel is true then the writer will write the edges sorted
   5.329 +  /// _forceSort is true then the writer will write the edges sorted
   5.330    /// by the labels.
   5.331    ///
   5.332    /// The undirected edgeset writer needs a node label writer to identify 
   5.333 @@ -833,18 +944,18 @@
   5.334      /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
   5.335      /// parameter is true then the writer will write own label map if
   5.336      /// the user does not give "label" named map. In addition if the
   5.337 -    /// the \c _sortByLabel is true then the writer will write the
   5.338 +    /// the \c _forceSort is true then the writer will write the
   5.339      /// edges sorted by the labels.
   5.340      template <typename NodeLabelWriter>
   5.341      UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   5.342  		       const NodeLabelWriter& _nodeLabelWriter, 
   5.343  		       const std::string& _name = std::string(),
   5.344 -		       bool _forceLabelMap = true, bool _sortByLabel = true)
   5.345 +		       bool _forceLabelMap = true, bool _forceSort = true)
   5.346        : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
   5.347 -	sortByLabel(_sortByLabel), graph(_graph), name(_name) {
   5.348 +	forceSort(_forceSort), graph(_graph), name(_name) {
   5.349        checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
   5.350        nodeLabelWriter.reset(new _writer_bits::
   5.351 -			 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   5.352 +	LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
   5.353      } 
   5.354  
   5.355      /// \brief Destructor.
   5.356 @@ -882,7 +993,7 @@
   5.357        checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
   5.358        writers.push_back(
   5.359  	make_pair(label, new _writer_bits::
   5.360 -		  MapWriter<UEdge, Map, ItemWriter>(map, iw)));
   5.361 +		  UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
   5.362        return *this;
   5.363      }
   5.364  
   5.365 @@ -903,9 +1014,9 @@
   5.366                                   const ItemWriter& iw = ItemWriter()) {
   5.367        checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
   5.368        checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
   5.369 -      writeUEdgeMap("+" + name, 
   5.370 +      writeUEdgeMap("+" + label, 
   5.371                      _writer_bits::forwardComposeMap(graph, map), iw);
   5.372 -      writeUEdgeMap("-" + name, 
   5.373 +      writeUEdgeMap("-" + label, 
   5.374                      _writer_bits::backwardComposeMap(graph, map), iw);
   5.375        return *this;
   5.376      }
   5.377 @@ -937,9 +1048,9 @@
   5.378        for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
   5.379          items.push_back(it);
   5.380        }
   5.381 -      if (sortByLabel) {
   5.382 +      if (forceSort) {
   5.383          if (labelMap) {
   5.384 -          labelMap->sortByMap(items);
   5.385 +          labelMap->sort(items);
   5.386          } else {
   5.387            typedef IdMap<Graph, UEdge> Map;
   5.388            Map map(graph);
   5.389 @@ -978,7 +1089,7 @@
   5.390      /// the edges.
   5.391      ///
   5.392      /// Returns true if the undirected edgeset can write the labels of the 
   5.393 -    /// undirected edges. It is possible only if an "label" named map was 
   5.394 +    /// undirected edges. It is possible only if a "label" named map was 
   5.395      /// written or the \c _forceLabelMap constructor parameter was true.
   5.396      bool isLabelWriter() const {
   5.397        return forceLabelMap || labelMap != 0;
   5.398 @@ -987,7 +1098,7 @@
   5.399      /// \brief Write the label of the given undirected edge.
   5.400      ///
   5.401      /// It writes the label of the given undirected edge. If there was written 
   5.402 -    /// an "label" named map then it will write the map value belongs to the 
   5.403 +    /// a "label" named map then it will write the map value belongs to the 
   5.404      /// undirected edge. Otherwise if the \c forceLabel parameter was true it 
   5.405      /// will write its id in the graph. 
   5.406      void writeLabel(std::ostream& os, const UEdge& item) const {
   5.407 @@ -1001,32 +1112,66 @@
   5.408      /// \brief Write the label of the given edge.
   5.409      ///
   5.410      /// It writes the label of the given edge. If there was written 
   5.411 -    /// an "label" named map then it will write the map value belongs to the 
   5.412 +    /// a "label" named map then it will write the map value belongs to the 
   5.413      /// edge. Otherwise if the \c forceLabel parameter was true it 
   5.414      /// will write its id in the graph. If the edge is forward map
   5.415      /// then its prefix character is \c '+' elsewhere \c '-'.
   5.416      void writeLabel(std::ostream& os, const Edge& item) const {
   5.417        if (graph.direction(item)) {
   5.418 -	os << "+ ";
   5.419 +	os << "+";
   5.420        } else {
   5.421 -	os << "- ";
   5.422 +	os << "-";
   5.423        }
   5.424        if (forceLabelMap) {
   5.425 -	os << graph.id(item);
   5.426 +	os << graph.id(static_cast<const UEdge&>(item));
   5.427        } else {
   5.428  	labelMap->write(os, item);
   5.429        }
   5.430      } 
   5.431  
   5.432 +    /// \brief Sorts the given undirected edge vector by label.
   5.433 +    ///
   5.434 +    /// Sorts the given undirected edge vector by label. If there was
   5.435 +    /// written a "label" named map then the vector will be sorted by
   5.436 +    /// the values of this map. Otherwise if the \c forceLabel
   5.437 +    /// parameter was true it will be sorted by its id in the graph.
   5.438 +    void sortByLabel(std::vector<UEdge>& uedges) const {
   5.439 +      if (labelMap) {
   5.440 +	labelMap->sort(uedges);
   5.441 +      } else {
   5.442 +	typedef IdMap<Graph, UEdge> Map;
   5.443 +	Map map(graph);
   5.444 +	_writer_bits::ComposeLess<Map> less(map);
   5.445 +	std::sort(uedges.begin(), uedges.end(), less);
   5.446 +      }
   5.447 +    }
   5.448 +
   5.449 +    /// \brief Sorts the given edge vector by label.
   5.450 +    ///
   5.451 +    /// Sorts the given edge vector by label. If there was written a
   5.452 +    /// "label" named map then the vector will be sorted by the values
   5.453 +    /// of this map. Otherwise if the \c forceLabel parameter was true
   5.454 +    /// it will be sorted by its id in the graph.
   5.455 +    void sortByLabel(std::vector<Edge>& edges) const {
   5.456 +      if (labelMap) {
   5.457 +	labelMap->sort(graph, edges);
   5.458 +      } else {
   5.459 +	typedef IdMap<Graph, Edge> Map;
   5.460 +	Map map(graph);
   5.461 +	_writer_bits::ComposeLess<Map> less(map);
   5.462 +	std::sort(edges.begin(), edges.end(), less);
   5.463 +      }
   5.464 +    }
   5.465 +
   5.466    private:
   5.467  
   5.468      typedef std::vector<std::pair<std::string, _writer_bits::
   5.469 -				  MapWriterBase<UEdge>*> > MapWriters;
   5.470 +				  UEdgeMapWriterBase<Graph>*> > MapWriters;
   5.471      MapWriters writers;
   5.472  
   5.473 -    _writer_bits::MapWriterBase<UEdge>* labelMap;
   5.474 +    _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
   5.475      bool forceLabelMap;
   5.476 -    bool sortByLabel;
   5.477 +    bool forceSort;
   5.478     
   5.479      const Graph& graph;   
   5.480      std::string name;
   5.481 @@ -1206,6 +1351,7 @@
   5.482      std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
   5.483    };
   5.484  
   5.485 +
   5.486    /// \ingroup section_io
   5.487    /// \brief SectionWriter for writing named undirected edges.
   5.488    ///
   5.489 @@ -1321,6 +1467,429 @@
   5.490    };
   5.491  
   5.492    /// \ingroup section_io
   5.493 +  /// \brief SectionWriter for writing extra node maps.
   5.494 +  ///
   5.495 +  /// The lemon format can store maps in the nodeset. This class let
   5.496 +  /// you make distinict section to store maps. The main purpose of
   5.497 +  /// this class is a logical separation of some maps. The other
   5.498 +  /// useful application could be to store paths in node maps.
   5.499 +  ///
   5.500 +  /// The first line of the section contains the names of the maps
   5.501 +  /// separated with white spaces. Each next line describes an item
   5.502 +  /// in the itemset, and contains in the first column the label of
   5.503 +  /// the item and then the mapped values for each map.
   5.504 +  ///
   5.505 +  /// \relates LemonWriter
   5.506 +  template <typename _Graph, typename _Traits = DefaultWriterTraits>
   5.507 +  class NodeMapWriter : public LemonWriter::SectionWriter {
   5.508 +    typedef LemonWriter::SectionWriter Parent;
   5.509 +  public:
   5.510 +
   5.511 +    typedef _Graph Graph;
   5.512 +    typedef _Traits Traits;
   5.513 +    typedef typename Graph::Node Node;
   5.514 +
   5.515 +    /// \brief Constructor.
   5.516 +    ///
   5.517 +    /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
   5.518 +    /// attach it into the given LemonWriter. If the the
   5.519 +    /// \c _forceSort is true then the writer will write the edges
   5.520 +    /// sorted by the labels.
   5.521 +    template <typename _LabelWriter>
   5.522 +    NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
   5.523 +		 const _LabelWriter& _labelWriter,
   5.524 +		 const std::string& _name = std::string(),
   5.525 +		 bool _forceSort = true) 
   5.526 +      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
   5.527 +      checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
   5.528 +      labelWriter.reset(new _writer_bits::LabelWriter<Node, 
   5.529 +			_LabelWriter>(_labelWriter));
   5.530 +    }
   5.531 +
   5.532 +    /// \brief Destructor.
   5.533 +    ///
   5.534 +    /// Destructor for NodeMapWriter.
   5.535 +    virtual ~NodeMapWriter() {
   5.536 +      typename MapWriters::iterator it;
   5.537 +      for (it = writers.begin(); it != writers.end(); ++it) {
   5.538 +	delete it->second;
   5.539 +      }
   5.540 +    }
   5.541 +
   5.542 +  private:
   5.543 +    NodeMapWriter(const NodeMapWriter&);
   5.544 +    void operator=(const NodeMapWriter&);
   5.545 +  
   5.546 +  public:
   5.547 +
   5.548 +    /// \brief Add a new node map writer command for the writer.
   5.549 +    ///
   5.550 +    /// Add a new node map writer command for the writer.
   5.551 +    template <typename Map>
   5.552 +    NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
   5.553 +      return writeNodeMap<typename Traits::
   5.554 +	template Writer<typename Map::Value>, Map>(label, map);
   5.555 +    }
   5.556 +
   5.557 +    /// \brief Add a new node map writer command for the writer.
   5.558 +    ///
   5.559 +    /// Add a new node map writer command for the writer.
   5.560 +    template <typename ItemWriter, typename Map>
   5.561 +    NodeMapWriter& writeNodeMap(std::string label, const Map& map, 
   5.562 +			   const ItemWriter& iw = ItemWriter()) {
   5.563 +      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   5.564 +      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
   5.565 +      writers.push_back(
   5.566 +	make_pair(label, new _writer_bits::
   5.567 +		  MapWriter<Node, Map, ItemWriter>(map, iw)));
   5.568 +      return *this;
   5.569 +    }
   5.570 +
   5.571 +  protected:
   5.572 +
   5.573 +    /// \brief The header of the section.
   5.574 +    ///
   5.575 +    /// It gives back the header of the section.
   5.576 +    virtual std::string header() {
   5.577 +      return "@nodemaps " + name;
   5.578 +    }
   5.579 +
   5.580 +    /// \brief  Writer function of the section.
   5.581 +    ///
   5.582 +    /// Write the content of the section.
   5.583 +    virtual void write(std::ostream& os) {
   5.584 +      std::vector<Node> nodes;
   5.585 +      for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
   5.586 +        nodes.push_back(it);
   5.587 +      }
   5.588 +      if (forceSort) {
   5.589 +	labelWriter->sort(nodes);
   5.590 +      }
   5.591 +      os << '\t';
   5.592 +      for (int i = 0; i < int(writers.size()); ++i) {
   5.593 +	os << writers[i].first << '\t';
   5.594 +      }
   5.595 +      os << std::endl;
   5.596 +      for (typename std::vector<Node>::iterator it = nodes.begin();
   5.597 +           it != nodes.end(); ++it) {
   5.598 +
   5.599 +	labelWriter->write(os, *it); os << '\t';
   5.600 +	for (int i = 0; i < int(writers.size()); ++i) {
   5.601 +	  writers[i].second->write(os, *it);
   5.602 +	  os << '\t';
   5.603 +	}
   5.604 +	os << std::endl;
   5.605 +      }
   5.606 +    }
   5.607 +
   5.608 +
   5.609 +  private:
   5.610 +
   5.611 +    typedef std::vector<std::pair<std::string, _writer_bits::
   5.612 +				  MapWriterBase<Node>*> > MapWriters;
   5.613 +    MapWriters writers;
   5.614 +
   5.615 +    _writer_bits::MapWriterBase<Node>* labelMap;
   5.616 +
   5.617 +    const Graph& graph;   
   5.618 +    std::string name;
   5.619 +    bool forceSort;
   5.620 +
   5.621 +    std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
   5.622 +  };
   5.623 +
   5.624 +  /// \ingroup section_io
   5.625 +  /// \brief SectionWriter for writing extra edge maps.
   5.626 +  ///
   5.627 +  /// The lemon format can store maps in the edgeset. This class let
   5.628 +  /// you make distinict section to store maps. The main purpose of
   5.629 +  /// this class is a logical separation of some maps. The other
   5.630 +  /// useful application could be to store paths in edge maps.
   5.631 +  ///
   5.632 +  /// The first line of the section contains the names of the maps
   5.633 +  /// separated with white spaces. Each next line describes an item
   5.634 +  /// in the itemset, and contains in the first column the label of
   5.635 +  /// the item and then the mapped values for each map.
   5.636 +  ///
   5.637 +  /// \relates LemonWriter
   5.638 +  template <typename _Graph, typename _Traits = DefaultWriterTraits>
   5.639 +  class EdgeMapWriter : public LemonWriter::SectionWriter {
   5.640 +    typedef LemonWriter::SectionWriter Parent;
   5.641 +  public:
   5.642 +
   5.643 +    typedef _Graph Graph;
   5.644 +    typedef _Traits Traits;
   5.645 +    typedef typename Graph::Edge Edge;
   5.646 +
   5.647 +    /// \brief Constructor.
   5.648 +    ///
   5.649 +    /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
   5.650 +    /// attach it into the given LemonWriter. If the the
   5.651 +    /// \c _forceSort is true then the writer will write the edges
   5.652 +    /// sorted by the labels.
   5.653 +    template <typename _LabelWriter>
   5.654 +    EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
   5.655 +		 const _LabelWriter& _labelWriter,
   5.656 +		 const std::string& _name = std::string(),
   5.657 +		 bool _forceSort = true) 
   5.658 +      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
   5.659 +      checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
   5.660 +      labelWriter.reset(new _writer_bits::LabelWriter<Edge, 
   5.661 +			_LabelWriter>(_labelWriter));
   5.662 +    }
   5.663 +
   5.664 +    /// \brief Destructor.
   5.665 +    ///
   5.666 +    /// Destructor for EdgeMapWriter.
   5.667 +    virtual ~EdgeMapWriter() {
   5.668 +      typename MapWriters::iterator it;
   5.669 +      for (it = writers.begin(); it != writers.end(); ++it) {
   5.670 +	delete it->second;
   5.671 +      }
   5.672 +    }
   5.673 +
   5.674 +  private:
   5.675 +    EdgeMapWriter(const EdgeMapWriter&);
   5.676 +    void operator=(const EdgeMapWriter&);
   5.677 +  
   5.678 +  public:
   5.679 +
   5.680 +    /// \brief Add a new edge map writer command for the writer.
   5.681 +    ///
   5.682 +    /// Add a new edge map writer command for the writer.
   5.683 +    template <typename Map>
   5.684 +    EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
   5.685 +      return writeEdgeMap<typename Traits::
   5.686 +	template Writer<typename Map::Value>, Map>(label, map);
   5.687 +    }
   5.688 +
   5.689 +    /// \brief Add a new edge map writer command for the writer.
   5.690 +    ///
   5.691 +    /// Add a new edge map writer command for the writer.
   5.692 +    template <typename ItemWriter, typename Map>
   5.693 +    EdgeMapWriter& writeEdgeMap(std::string label, const Map& map, 
   5.694 +				const ItemWriter& iw = ItemWriter()) {
   5.695 +      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
   5.696 +      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
   5.697 +      writers.push_back(
   5.698 +	make_pair(label, new _writer_bits::
   5.699 +		  MapWriter<Edge, Map, ItemWriter>(map, iw)));
   5.700 +      return *this;
   5.701 +    }
   5.702 +
   5.703 +  protected:
   5.704 +
   5.705 +    /// \brief The header of the section.
   5.706 +    ///
   5.707 +    /// It gives back the header of the section.
   5.708 +    virtual std::string header() {
   5.709 +      return "@edgemaps " + name;
   5.710 +    }
   5.711 +
   5.712 +    /// \brief  Writer function of the section.
   5.713 +    ///
   5.714 +    /// Write the content of the section.
   5.715 +    virtual void write(std::ostream& os) {
   5.716 +      std::vector<Edge> edges;
   5.717 +      for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
   5.718 +        edges.push_back(it);
   5.719 +      }
   5.720 +      if (forceSort) {
   5.721 +	labelWriter->sort(edges);
   5.722 +      }
   5.723 +      os << '\t';
   5.724 +      for (int i = 0; i < int(writers.size()); ++i) {
   5.725 +	os << writers[i].first << '\t';
   5.726 +      }
   5.727 +      os << std::endl;
   5.728 +      for (typename std::vector<Edge>::iterator it = edges.begin();
   5.729 +           it != edges.end(); ++it) {
   5.730 +
   5.731 +	labelWriter->write(os, *it); os << '\t';
   5.732 +	for (int i = 0; i < int(writers.size()); ++i) {
   5.733 +	  writers[i].second->write(os, *it);
   5.734 +	  os << '\t';
   5.735 +	}
   5.736 +	os << std::endl;
   5.737 +      }
   5.738 +    }
   5.739 +
   5.740 +
   5.741 +  private:
   5.742 +
   5.743 +    typedef std::vector<std::pair<std::string, _writer_bits::
   5.744 +				  MapWriterBase<Edge>*> > MapWriters;
   5.745 +    MapWriters writers;
   5.746 +
   5.747 +    _writer_bits::MapWriterBase<Edge>* labelMap;
   5.748 +
   5.749 +    const Graph& graph;   
   5.750 +    std::string name;
   5.751 +    bool forceSort;
   5.752 +
   5.753 +    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
   5.754 +  };
   5.755 +
   5.756 +  /// \ingroup section_io
   5.757 +  /// \brief SectionWriter for writing extra undirected edge maps.
   5.758 +  ///
   5.759 +  /// The lemon format can store maps in the uedgeset. This class let
   5.760 +  /// you make distinict section to store maps. The main purpose of
   5.761 +  /// this class is a logical separation of some maps. The other
   5.762 +  /// useful application could be to store paths in undirected edge
   5.763 +  /// maps.
   5.764 +  ///
   5.765 +  /// The first line of the section contains the names of the maps
   5.766 +  /// separated with white spaces. Each next line describes an item
   5.767 +  /// in the itemset, and contains in the first column the label of
   5.768 +  /// the item and then the mapped values for each map.
   5.769 +  ///
   5.770 +  /// \relates LemonWriter
   5.771 +  template <typename _Graph, typename _Traits = DefaultWriterTraits>
   5.772 +  class UEdgeMapWriter : public LemonWriter::SectionWriter {
   5.773 +    typedef LemonWriter::SectionWriter Parent;
   5.774 +  public:
   5.775 +
   5.776 +    typedef _Graph Graph;
   5.777 +    typedef _Traits Traits;
   5.778 +    typedef typename Graph::UEdge UEdge;
   5.779 +    typedef typename Graph::Edge Edge;
   5.780 +
   5.781 +    /// \brief Constructor.
   5.782 +    ///
   5.783 +    /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
   5.784 +    /// attach it into the given LemonWriter. If the the
   5.785 +    /// \c _forceSort is true then the writer will write the uedges
   5.786 +    /// sorted by the labels.
   5.787 +    template <typename _LabelWriter>
   5.788 +    UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
   5.789 +		 const _LabelWriter& _labelWriter,
   5.790 +		 const std::string& _name = std::string(),
   5.791 +		 bool _forceSort = true) 
   5.792 +      : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
   5.793 +      checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
   5.794 +      labelWriter.reset(new _writer_bits::LabelWriter<UEdge, 
   5.795 +			    _LabelWriter>(_labelWriter));
   5.796 +    }
   5.797 +
   5.798 +    /// \brief Destructor.
   5.799 +    ///
   5.800 +    /// Destructor for UEdgeMapWriter.
   5.801 +    virtual ~UEdgeMapWriter() {
   5.802 +      typename MapWriters::iterator it;
   5.803 +      for (it = writers.begin(); it != writers.end(); ++it) {
   5.804 +	delete it->second;
   5.805 +      }
   5.806 +    }
   5.807 +
   5.808 +  private:
   5.809 +    UEdgeMapWriter(const UEdgeMapWriter&);
   5.810 +    void operator=(const UEdgeMapWriter&);
   5.811 +  
   5.812 +  public:
   5.813 +
   5.814 +    /// \brief Add a new undirected edge map writer command for the writer.
   5.815 +    ///
   5.816 +    /// Add a new undirected edge map writer command for the writer.
   5.817 +    template <typename Map>
   5.818 +    UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
   5.819 +      return writeUEdgeMap<typename Traits::
   5.820 +	template Writer<typename Map::Value>, Map>(label, map);
   5.821 +    }
   5.822 +
   5.823 +    /// \brief Add a new undirected edge map writer command for the writer.
   5.824 +    ///
   5.825 +    /// Add a new undirected edge map writer command for the writer.
   5.826 +    template <typename ItemWriter, typename Map>
   5.827 +    UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map, 
   5.828 +			   const ItemWriter& iw = ItemWriter()) {
   5.829 +      checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
   5.830 +      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
   5.831 +      writers.push_back(
   5.832 +	make_pair(label, new _writer_bits::
   5.833 +		  MapWriter<UEdge, Map, ItemWriter>(map, iw)));
   5.834 +      return *this;
   5.835 +    }
   5.836 +
   5.837 +    /// \brief Add a new directed edge map writer command for the writer.
   5.838 +    ///
   5.839 +    /// Add a new directed map writer command for the writer.
   5.840 +    template <typename Map>
   5.841 +    UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
   5.842 +      return writeEdgeMap<typename Traits::
   5.843 +	template Writer<typename Map::Value>, Map>(label, map);
   5.844 +    }
   5.845 +
   5.846 +    /// \brief Add a new directed map writer command for the writer.
   5.847 +    ///
   5.848 +    /// Add a new directed map writer command for the writer.
   5.849 +    template <typename ItemWriter, typename Map>
   5.850 +    UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map, 
   5.851 +                                 const ItemWriter& iw = ItemWriter()) {
   5.852 +      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
   5.853 +      checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
   5.854 +      writeUEdgeMap("+" + label, 
   5.855 +                    _writer_bits::forwardComposeMap(graph, map), iw);
   5.856 +      writeUEdgeMap("-" + label, 
   5.857 +                    _writer_bits::backwardComposeMap(graph, map), iw);
   5.858 +      return *this;
   5.859 +    }
   5.860 +
   5.861 +  protected:
   5.862 +
   5.863 +    /// \brief The header of the section.
   5.864 +    ///
   5.865 +    /// It gives back the header of the section.
   5.866 +    virtual std::string header() {
   5.867 +      return "@uedgemaps " + name;
   5.868 +    }
   5.869 +
   5.870 +    /// \brief  Writer function of the section.
   5.871 +    ///
   5.872 +    /// Write the content of the section.
   5.873 +    virtual void write(std::ostream& os) {
   5.874 +      std::vector<UEdge> uedges;
   5.875 +      for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
   5.876 +        uedges.push_back(it);
   5.877 +      }
   5.878 +      if (forceSort) {
   5.879 +	labelWriter->sort(uedges);
   5.880 +      }
   5.881 +      os << '\t';
   5.882 +      for (int i = 0; i < int(writers.size()); ++i) {
   5.883 +	os << writers[i].first << '\t';
   5.884 +      }
   5.885 +      os << std::endl;
   5.886 +      for (typename std::vector<UEdge>::iterator it = uedges.begin();
   5.887 +           it != uedges.end(); ++it) {
   5.888 +
   5.889 +	labelWriter->write(os, *it); os << '\t';
   5.890 +	for (int i = 0; i < int(writers.size()); ++i) {
   5.891 +	  writers[i].second->write(os, *it);
   5.892 +	  os << '\t';
   5.893 +	}
   5.894 +	os << std::endl;
   5.895 +      }
   5.896 +    }
   5.897 +
   5.898 +
   5.899 +  private:
   5.900 +
   5.901 +    typedef std::vector<std::pair<std::string, _writer_bits::
   5.902 +				  MapWriterBase<UEdge>*> > MapWriters;
   5.903 +    MapWriters writers;
   5.904 +
   5.905 +    _writer_bits::MapWriterBase<UEdge>* labelMap;
   5.906 +
   5.907 +    const Graph& graph;   
   5.908 +    std::string name;
   5.909 +    bool forceSort;
   5.910 +
   5.911 +    std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
   5.912 +  };
   5.913 +
   5.914 +
   5.915 +  /// \ingroup section_io
   5.916    /// \brief SectionWriter for attributes.
   5.917    ///
   5.918    /// The lemon format can store multiple attribute set. Each set has
     6.1 --- a/lemon/path_utils.h	Tue Aug 28 13:58:54 2007 +0000
     6.2 +++ b/lemon/path_utils.h	Tue Aug 28 14:00:42 2007 +0000
     6.3 @@ -25,6 +25,8 @@
     6.4  #define LEMON_PATH_UTILS_H
     6.5  
     6.6  #include <lemon/concepts/path.h>
     6.7 +#include <lemon/lemon_reader.h>
     6.8 +#include <lemon/lemon_writer.h>
     6.9  
    6.10  namespace lemon {
    6.11  
    6.12 @@ -132,6 +134,261 @@
    6.13    typename Graph::Node pathTarget(const Graph& graph, const Path& path) {
    6.14      return graph.target(path.back());
    6.15    }
    6.16 +
    6.17 +  /// \brief Class which helps to iterate the nodes of a path
    6.18 +  ///
    6.19 +  /// In a sense, the path can be treated as a list of edges. The
    6.20 +  /// lemon path type stores just this list. As a consequence it
    6.21 +  /// cannot enumerate the nodes in the path and the zero length paths
    6.22 +  /// cannot store the node.
    6.23 +  ///
    6.24 +  /// This class implements the node iterator of a path structure. To
    6.25 +  /// provide this feature, the underlying graph should be given to
    6.26 +  /// the constructor of the iterator.
    6.27 +  template <typename Path>
    6.28 +  class PathNodeIt {
    6.29 +  private:
    6.30 +    const typename Path::Graph *_graph;
    6.31 +    typename Path::EdgeIt _it;
    6.32 +    typename Path::Graph::Node _nd;
    6.33 +
    6.34 +  public:
    6.35 +
    6.36 +    typedef typename Path::Graph Graph;
    6.37 +    typedef typename Graph::Node Node;
    6.38 +    
    6.39 +    /// Default constructor
    6.40 +    PathNodeIt() {}
    6.41 +    /// Invalid constructor
    6.42 +    PathNodeIt(Invalid) 
    6.43 +      : _graph(0), _it(INVALID), _nd(INVALID) {}
    6.44 +    /// Constructor
    6.45 +    PathNodeIt(const Graph& graph, const Path& path) 
    6.46 +      : _graph(&graph), _it(path) {
    6.47 +      _nd = (_it != INVALID ? _graph->source(_it) : INVALID);
    6.48 +    }
    6.49 +    /// Constructor
    6.50 +    PathNodeIt(const Graph& graph, const Path& path, const Node& src) 
    6.51 +      : _graph(&graph), _it(path), _nd(src) {}
    6.52 +
    6.53 +    ///Conversion to Graph::Node
    6.54 +    operator Node() const {
    6.55 +      return _nd;
    6.56 +    }
    6.57 +
    6.58 +    /// Next node
    6.59 +    PathNodeIt& operator++() {
    6.60 +      if (_it == INVALID) _nd = INVALID;
    6.61 +      else {
    6.62 +	_nd = _graph->target(_it);
    6.63 +	++_it;
    6.64 +      }
    6.65 +      return *this;
    6.66 +    }
    6.67 +
    6.68 +    /// Comparison operator
    6.69 +    bool operator==(const PathNodeIt& n) const { 
    6.70 +      return _it == n._it && _nd == n._nd; 
    6.71 +    }
    6.72 +    /// Comparison operator
    6.73 +    bool operator!=(const PathNodeIt& n) const { 
    6.74 +      return _it != n._it || _nd != n._nd; 
    6.75 +    }
    6.76 +    /// Comparison operator
    6.77 +    bool operator<(const PathNodeIt& n) const { 
    6.78 +      return (_it < n._it && _nd != INVALID);
    6.79 +    }
    6.80 +    
    6.81 +  };
    6.82 +
    6.83 +  /// \brief Item writer for paths
    6.84 +  ///
    6.85 +  /// This class can write paths into files. You can store paths in
    6.86 +  /// distinict mapset or in attributes section.
    6.87 +  ///
    6.88 +  ///\code
    6.89 +  /// GraphWriter<SmartGraph> gw(std::cout, g);
    6.90 +  /// NodeMapWriter<SmartGraph> nmw(gw, g, gw);
    6.91 +  ///
    6.92 +  /// SmartGraph::NodeMap<Path<SmartGraph> > pnm(g);
    6.93 +  /// for (SmartGraph::NodeIt n(g); n != INVALID; ++n) {
    6.94 +  ///   pnm[n] = bfs.path(n);
    6.95 +  /// }
    6.96 +  /// nmw.writeNodeMap("pnm", pnm, PathWriter<Path<SmartGraph> >(gw));
    6.97 +  ///
    6.98 +  /// gw.run();
    6.99 +  ///\endcode
   6.100 +  ///
   6.101 +  /// \warning Do not use this class to write node or edge map values
   6.102 +  /// into usual nodesets or edgesets. You will not be able to read
   6.103 +  /// back your paths. Rather use NodeMapWriter, EdgeSetWriter or
   6.104 +  /// UEdgeSetWriter to dump paths from maps to lemon file.
   6.105 +  template <typename Path>
   6.106 +  class PathWriter {
   6.107 +  private:
   6.108 +
   6.109 +    typedef typename Path::Edge Edge;
   6.110 +    std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
   6.111 +
   6.112 +  public:
   6.113 +
   6.114 +    typedef Path Value;
   6.115 +
   6.116 +    PathWriter(const PathWriter& pw) {
   6.117 +      edgeLabelWriter.reset(pw.edgeLabelWriter->clone());
   6.118 +    }
   6.119 +
   6.120 +    /// \brief Constructor
   6.121 +    ///
   6.122 +    /// The paramter shold be an edge label writer which could
   6.123 +    /// be a GraphWriter or an EdgeSetWriter. 
   6.124 +    template <typename EdgeLabelWriter>
   6.125 +    explicit PathWriter(const EdgeLabelWriter& _edgeLabelWriter) {
   6.126 +      edgeLabelWriter.reset(new _writer_bits::
   6.127 +	LabelWriter<Edge, EdgeLabelWriter>(_edgeLabelWriter));
   6.128 +    }
   6.129 +
   6.130 +    /// \brief Writer function
   6.131 +    ///
   6.132 +    /// Writes the path to the current stream. The representation
   6.133 +    /// is the edge labels beetween parentheses.
   6.134 +    void write(std::ostream& os, const Value& value) const {
   6.135 +      if (!edgeLabelWriter->isLabelWriter()) {
   6.136 +	throw DataFormatError("Cannot find edgeset or label map");
   6.137 +      }
   6.138 +      os << '(' << ' ';
   6.139 +      for (typename Path::EdgeIt e(value); e != INVALID; ++e) {
   6.140 +	edgeLabelWriter->write(os, e);
   6.141 +	os << ' ';
   6.142 +      }
   6.143 +      os << ')';
   6.144 +    }
   6.145 +    
   6.146 +  };
   6.147 +
   6.148 +  namespace _path_bits {
   6.149 +
   6.150 +    template <typename _Graph>
   6.151 +    class PathProxy {
   6.152 +    public:
   6.153 +      typedef False RevPathTag;
   6.154 +
   6.155 +      typedef _Graph Graph;
   6.156 +      typedef typename Graph::Edge Edge;
   6.157 +
   6.158 +      PathProxy(const std::vector<Edge>& edges)
   6.159 +	: _edges(edges) {}
   6.160 +
   6.161 +      int length() const {
   6.162 +	return _edges.size();
   6.163 +      }
   6.164 +
   6.165 +      bool empty() const {
   6.166 +	return _edges.size() == 0;
   6.167 +      }
   6.168 +
   6.169 +      class EdgeIt {
   6.170 +      public:
   6.171 +	EdgeIt() {}
   6.172 +	EdgeIt(const PathProxy& path) 
   6.173 +	  : _path(&path), _index(0) {}
   6.174 +	
   6.175 +	operator const Edge() const {
   6.176 +	  return _path->_edges[_index];
   6.177 +	}
   6.178 +
   6.179 +	EdgeIt& operator++() {
   6.180 +	  ++_index;
   6.181 +	  return *this;
   6.182 +	}
   6.183 +
   6.184 +	bool operator==(Invalid) const { 
   6.185 +	  return int(_path->_edges.size()) == _index; 
   6.186 +	}
   6.187 +	bool operator!=(Invalid) const { 
   6.188 +	  return int(_path->_edges.size()) != _index; 
   6.189 +	}
   6.190 +
   6.191 +      private:
   6.192 +	const PathProxy* _path;
   6.193 +	int _index;
   6.194 +      };
   6.195 +      
   6.196 +    private:
   6.197 +      const std::vector<Edge>& _edges;
   6.198 +      
   6.199 +    };
   6.200 +
   6.201 +  }
   6.202 +
   6.203 +  /// \brief Item reader for paths 
   6.204 +  ///
   6.205 +  /// This class can read paths from files. You can store paths in
   6.206 +  /// distinict mapset or in attributes section.
   6.207 +  ///
   6.208 +  ///\code
   6.209 +  /// GraphReader<SmartGraph> gr(std::cout, g);
   6.210 +  /// NodeMapReader<SmartGraph> nmr(gr, g, gr);
   6.211 +  ///
   6.212 +  /// SmartGraph::NodeMap<Path<SmartGraph> > pnm(g);
   6.213 +  /// nmr.readNodeMap("pnm", pnm, PathReader<Path<SmartGraph> >(gr));
   6.214 +  ///
   6.215 +  /// gr.run();
   6.216 +  ///\endcode
   6.217 +  ///
   6.218 +  /// \warning Do not use this class to read node or edge map values
   6.219 +  /// from nodesets or edgesets. The edges are not surely constructed
   6.220 +  /// when the edge list should be read. Rather use NodeMapReader,
   6.221 +  /// EdgeSetReader or UEdgeSetReader to read distinict map sets from file.
   6.222 +  template <typename Path>
   6.223 +  class PathReader {
   6.224 +  private:
   6.225 +
   6.226 +    typedef typename Path::Edge Edge;
   6.227 +    std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
   6.228 +
   6.229 +  public:
   6.230 +
   6.231 +    typedef Path Value;
   6.232 +
   6.233 +    PathReader(const PathReader& pw) {
   6.234 +      edgeLabelReader.reset(pw.edgeLabelReader->clone());
   6.235 +    }
   6.236 +
   6.237 +    /// \brief Constructor
   6.238 +    ///
   6.239 +    /// The paramter shold be an edge label reader which could
   6.240 +    /// be a GraphReader or an EdgeSetReader. 
   6.241 +    template <typename EdgeLabelReader>
   6.242 +    explicit PathReader(const EdgeLabelReader& _edgeLabelReader) {
   6.243 +      edgeLabelReader.reset(new _reader_bits::
   6.244 +	LabelReader<Edge, EdgeLabelReader>(_edgeLabelReader));
   6.245 +    }
   6.246 +
   6.247 +
   6.248 +    /// \brief Reader function
   6.249 +    ///
   6.250 +    /// Reads the path from the current stream. The representation
   6.251 +    /// is the edge labels beetween parentheses.
   6.252 +    void read(std::istream& is, Value& value) const {
   6.253 +      if (!edgeLabelReader->isLabelReader()) {
   6.254 +	throw DataFormatError("Cannot find edgeset or label map");
   6.255 +      }
   6.256 +      char c;
   6.257 +      if (!(is >> c) || c != '(') 
   6.258 +	throw DataFormatError("PathReader format error");
   6.259 +      std::vector<typename Path::Edge> v;
   6.260 +      while (is >> c && c != ')') {
   6.261 +	is.putback(c);
   6.262 +	Edge edge = edgeLabelReader->read(is);
   6.263 +	v.push_back(edge);
   6.264 +      }
   6.265 +      if (!is) throw DataFormatError("PathReader format error");
   6.266 +      copyPath(value, _path_bits::PathProxy<typename Path::Edge>(v));
   6.267 +    }
   6.268 +    
   6.269 +  };
   6.270 +  
   6.271  }
   6.272  
   6.273  #endif