src/lemon/lemon_writer.h
changeset 1421 7a21e1414c38
parent 1411 5d161e08bda8
child 1429 4283998fb2be
     1.1 --- a/src/lemon/lemon_writer.h	Sat May 14 17:37:33 2005 +0000
     1.2 +++ b/src/lemon/lemon_writer.h	Sat May 14 17:39:37 2005 +0000
     1.3 @@ -31,7 +31,10 @@
     1.4  
     1.5  #include <lemon/error.h>
     1.6  #include <lemon/invalid.h>
     1.7 +#include <lemon/graph_utils.h>
     1.8  #include <lemon/bits/item_writer.h>
     1.9 +#include <lemon/utility.h>
    1.10 +#include <lemon/maps.h>
    1.11  
    1.12  
    1.13  namespace lemon {
    1.14 @@ -163,8 +166,6 @@
    1.15      CommonSectionWriterBase(LemonWriter& _writer) 
    1.16        : Parent(_writer) {}
    1.17  
    1.18 -    // Writers
    1.19 -
    1.20      template <typename _Item>    
    1.21      class WriterBase {
    1.22      public:
    1.23 @@ -184,7 +185,7 @@
    1.24        typedef typename Writer::Value Value;
    1.25        typedef _Item Item;
    1.26        
    1.27 -      const Map& map;
    1.28 +      typename SmartConstReference<Map>::Type map;
    1.29        Writer writer;
    1.30  
    1.31        MapWriter(const Map& _map, const Writer& _writer) 
    1.32 @@ -306,8 +307,8 @@
    1.33      ///
    1.34      /// Add a new node map writer command for the writer.
    1.35      template <typename Map>
    1.36 -    NodeSetWriter& writeMap(std::string name, const Map& map) {
    1.37 -      return writeMap<typename Traits::
    1.38 +    NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
    1.39 +      return writeNodeMap<typename Traits::
    1.40  	template Writer<typename Map::Value>, Map>(name, map);
    1.41      }
    1.42  
    1.43 @@ -315,8 +316,8 @@
    1.44      ///
    1.45      /// Add a new node map writer command for the writer.
    1.46      template <typename Writer, typename Map>
    1.47 -    NodeSetWriter& writeMap(std::string name, const Map& map, 
    1.48 -			     const Writer& writer = Writer()) {
    1.49 +    NodeSetWriter& writeNodeMap(std::string name, const Map& map, 
    1.50 +			    const Writer& writer = Writer()) {
    1.51        writers.push_back(
    1.52  	make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
    1.53        return *this;
    1.54 @@ -394,15 +395,15 @@
    1.55      WriterBase<Item>* idMap;
    1.56      bool forceIdMap;
    1.57     
    1.58 -    const Graph& graph;   
    1.59 +    typename SmartConstReference<Graph>::Type graph;   
    1.60      std::string id;
    1.61  
    1.62    };
    1.63  
    1.64    /// \ingroup io_group
    1.65 -  /// \brief SectionWriter for writing a graph's edgeset.
    1.66 +  /// \brief SectionWriter for writing a graph's edgesets.
    1.67    ///
    1.68 -  /// The lemon format can store multiple graph edgesets with several maps.
    1.69 +  /// The lemon format can store multiple graph edgesets with several maps. 
    1.70    /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
    1.71    /// \c edgeset_id may be empty.
    1.72    ///
    1.73 @@ -413,7 +414,7 @@
    1.74    ///
    1.75    /// If the edgeset contains an \c "id" named map then it will be regarded
    1.76    /// as id map. This map should contain only unique values and when the 
    1.77 -  /// \c writeId() member will be called with a edge it will write it's id.
    1.78 +  /// \c writeId() member will be called with an edge it will write it's id.
    1.79    /// Otherwise if the \c _forceIdMap constructor parameter is true then
    1.80    /// the id map will be the id in the graph.
    1.81    ///
    1.82 @@ -436,7 +437,7 @@
    1.83      /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
    1.84      /// attach it into the given LemonWriter. It will write node ids by
    1.85      /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true 
    1.86 -    /// then the writer will write own id map when the user does not give 
    1.87 +    /// then the writer will write own id map if the user does not give 
    1.88      /// "id" named map.
    1.89      template <typename NodeIdWriter>
    1.90      EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
    1.91 @@ -464,21 +465,21 @@
    1.92  
    1.93    public:
    1.94  
    1.95 -    /// \brief Add a new node map writer command for the writer.
    1.96 +    /// \brief Add a new edge map writer command for the writer.
    1.97      ///
    1.98 -    /// Add a new node map writer command for the writer.
    1.99 +    /// Add a new edge map writer command for the writer.
   1.100      template <typename Map>
   1.101 -    EdgeSetWriter& writeMap(std::string name, const Map& map) {
   1.102 -      return writeMap<typename Traits::
   1.103 +    EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
   1.104 +      return writeEdgeMap<typename Traits::
   1.105  	template Writer<typename Map::Value>, Map>(name, map);
   1.106      }
   1.107  
   1.108 -    /// \brief Add a new node map writer command for the writer.
   1.109 +    /// \brief Add a new edge map writer command for the writer.
   1.110      ///
   1.111 -    /// Add a new node map writer command for the writer.
   1.112 +    /// Add a new edge map writer command for the writer.
   1.113      template <typename Writer, typename Map>
   1.114 -    EdgeSetWriter& writeMap(std::string name, const Map& map, 
   1.115 -			     const Writer& writer = Writer()) {
   1.116 +    EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
   1.117 +			    const Writer& writer = Writer()) {
   1.118        writers.push_back(
   1.119  	make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
   1.120        return *this;
   1.121 @@ -561,7 +562,203 @@
   1.122      WriterBase<Item>* idMap;
   1.123      bool forceIdMap;
   1.124     
   1.125 -    const Graph& graph;   
   1.126 +    typename SmartConstReference<Graph>::Type graph;   
   1.127 +    std::string id;
   1.128 +
   1.129 +    std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter;
   1.130 +  };
   1.131 +
   1.132 +  /// \ingroup io_group
   1.133 +  /// \brief SectionWriter for writing a undirected edgeset.
   1.134 +  ///
   1.135 +  /// The lemon format can store multiple undirected edgesets with several 
   1.136 +  /// maps. The undirected edgeset section's header line is \c \@undiredgeset 
   1.137 +  /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
   1.138 +  ///
   1.139 +  /// The first line of the section contains the names of the maps separated
   1.140 +  /// with white spaces. Each next lines describes an undirected edge in the 
   1.141 +  /// edgeset. The line contains the two connected nodes' id and the mapped 
   1.142 +  /// values for each undirected map.
   1.143 +  ///
   1.144 +  /// The section can handle the directed as a syntactical sugar. Two
   1.145 +  /// undirected edge map describes one directed edge map. This two maps
   1.146 +  /// are the forward map and the backward map and the names of this map
   1.147 +  /// is near the same just with a prefix \c '+' or \c '-' character 
   1.148 +  /// difference.
   1.149 +  ///
   1.150 +  /// If the edgeset contains an \c "id" named map then it will be regarded
   1.151 +  /// as id map. This map should contain only unique values and when the 
   1.152 +  /// \c writeId() member will be called with an undirected edge it will 
   1.153 +  /// write it's id. Otherwise if the \c _forceIdMap constructor parameter
   1.154 +  /// is true then the id map will be the id in the graph.
   1.155 +  ///
   1.156 +  /// The undirected edgeset writer needs a node id writer to identify 
   1.157 +  /// which nodes have to be connected. If a NodeSetWriter can write the 
   1.158 +  /// nodes' id, it will be able to use with this class.
   1.159 +  ///
   1.160 +  /// \relates LemonWriter
   1.161 +  template <typename _Graph, typename _Traits = DefaultWriterTraits>
   1.162 +  class UndirEdgeSetWriter : public CommonSectionWriterBase {
   1.163 +    typedef CommonSectionWriterBase Parent;
   1.164 +  public:
   1.165 +
   1.166 +    typedef _Graph Graph;
   1.167 +    typedef _Traits Traits;
   1.168 +    typedef typename Graph::UndirEdge Item;
   1.169 +
   1.170 +    /// \brief Constructor.
   1.171 +    ///
   1.172 +    /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
   1.173 +    /// and attach it into the given LemonWriter. It will write node ids by
   1.174 +    /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true 
   1.175 +    /// then the writer will write own id map if the user does not give 
   1.176 +    /// "id" named map.
   1.177 +    template <typename NodeIdWriter>
   1.178 +    UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 
   1.179 +		       const NodeIdWriter& _nodeIdWriter, 
   1.180 +		       const std::string& _id = std::string(),
   1.181 +		       bool _forceIdMap = true)
   1.182 +      : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
   1.183 +	graph(_graph), id(_id),
   1.184 +	nodeIdWriter(new IdWriter<typename Graph::Node, NodeIdWriter>
   1.185 +		     (_nodeIdWriter)) {} 
   1.186 +
   1.187 +    /// \brief Destructor.
   1.188 +    ///
   1.189 +    /// Destructor for UndirEdgeSetWriter.
   1.190 +    virtual ~UndirEdgeSetWriter() {
   1.191 +      typename MapWriters::iterator it;
   1.192 +      for (it = writers.begin(); it != writers.end(); ++it) {
   1.193 +	delete it->second;
   1.194 +      }
   1.195 +    }
   1.196 +
   1.197 +  private:
   1.198 +    UndirEdgeSetWriter(const UndirEdgeSetWriter&);
   1.199 +    void operator=(const UndirEdgeSetWriter&);
   1.200 +
   1.201 +  public:
   1.202 +
   1.203 +    /// \brief Add a new undirected edge map writer command for the writer.
   1.204 +    ///
   1.205 +    /// Add a new undirected map writer command for the writer.
   1.206 +    template <typename Map>
   1.207 +    UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
   1.208 +      return writeUndirEdgeMap<typename Traits::
   1.209 +	template Writer<typename Map::Value>, Map>(name, map);
   1.210 +    }
   1.211 +
   1.212 +    /// \brief Add a new undirected map writer command for the writer.
   1.213 +    ///
   1.214 +    /// Add a new undirected map writer command for the writer.
   1.215 +    template <typename Writer, typename Map>
   1.216 +    UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, 
   1.217 +					  const Writer& writer = Writer()) {
   1.218 +      writers.push_back(
   1.219 +	make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
   1.220 +      return *this;
   1.221 +    }
   1.222 +
   1.223 +    /// \brief Add a new directed edge map writer command for the writer.
   1.224 +    ///
   1.225 +    /// Add a new directed map writer command for the writer.
   1.226 +    template <typename Map>
   1.227 +    UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
   1.228 +      writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
   1.229 +      writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
   1.230 +      return *this;
   1.231 +    }
   1.232 +
   1.233 +    /// \brief Add a new directed map writer command for the writer.
   1.234 +    ///
   1.235 +    /// Add a new directed map writer command for the writer.
   1.236 +    template <typename Writer, typename Map>
   1.237 +    UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
   1.238 +				     const Writer& writer = Writer()) {
   1.239 +      writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
   1.240 +      writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
   1.241 +      return *this;
   1.242 +    }
   1.243 +
   1.244 +  protected:
   1.245 +
   1.246 +    /// \brief The header of the section.
   1.247 +    ///
   1.248 +    /// It gives back the header of the section.
   1.249 +    virtual std::string header() {
   1.250 +      return "@undiredgeset " + id;
   1.251 +    }
   1.252 +
   1.253 +    /// \brief  Writer function of the section.
   1.254 +    ///
   1.255 +    /// Write the content of the section.
   1.256 +    virtual void write(std::ostream& os) {
   1.257 +      for (int i = 0; i < (int)writers.size(); ++i) {
   1.258 +	if (writers[i].first == "id") {
   1.259 +	  idMap = writers[i].second;
   1.260 +	  forceIdMap = false;
   1.261 +	  break;
   1.262 +	}
   1.263 +      }
   1.264 +      os << "\t\t";
   1.265 +      if (forceIdMap) {
   1.266 +	os << "id\t";
   1.267 +      }
   1.268 +      for (int i = 0; i < (int)writers.size(); ++i) {
   1.269 +	os << writers[i].first << '\t';
   1.270 +      }
   1.271 +      os << std::endl;
   1.272 +      for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
   1.273 +	nodeIdWriter->write(os, graph.source(it));
   1.274 +	os << '\t';
   1.275 +	nodeIdWriter->write(os, graph.target(it));
   1.276 +	os << '\t';
   1.277 +	if (forceIdMap) {
   1.278 +	  os << graph.id(it) << '\t';
   1.279 +	}
   1.280 +	for (int i = 0; i < (int)writers.size(); ++i) {
   1.281 +	  writers[i].second->write(os, it);
   1.282 +	  os << '\t';
   1.283 +	}
   1.284 +	os << std::endl;
   1.285 +      }
   1.286 +    }
   1.287 +
   1.288 +  public:
   1.289 +
   1.290 +    /// \brief Returns true if the undirected edgeset can write the ids of 
   1.291 +    /// the edges.
   1.292 +    ///
   1.293 +    /// Returns true if the undirected edgeset can write the ids of the 
   1.294 +    /// undirected edges. It is possible only if an "id" named map was 
   1.295 +    /// written or the \c _forceIdMap constructor parameter was true.
   1.296 +    bool isIdWriter() const {
   1.297 +      return forceIdMap || idMap != 0;
   1.298 +    }
   1.299 +
   1.300 +    /// \brief Write the id of the given undirected edge.
   1.301 +    ///
   1.302 +    /// It writes the id of the given undirected edge. If there was written 
   1.303 +    /// an "id" named map then it will write the map value belongs to the 
   1.304 +    /// undirected edge. Otherwise if the \c forceId parameter was true it 
   1.305 +    /// will write its id in the graph. 
   1.306 +    void writeId(std::ostream& os, const Item& item) const {
   1.307 +      if (forceIdMap) {
   1.308 +	os << graph.id(item);
   1.309 +      } else {
   1.310 +	idMap->write(os, item);
   1.311 +      }
   1.312 +    } 
   1.313 +
   1.314 +  private:
   1.315 +
   1.316 +    typedef std::vector<std::pair<std::string, WriterBase<Item>*> > MapWriters;
   1.317 +    MapWriters writers;
   1.318 +
   1.319 +    WriterBase<Item>* idMap;
   1.320 +    bool forceIdMap;
   1.321 +   
   1.322 +    typename SmartConstReference<Graph>::Type graph;   
   1.323      std::string id;
   1.324  
   1.325      std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter;
   1.326 @@ -617,7 +814,7 @@
   1.327  
   1.328      /// \brief Header checking function.
   1.329      ///
   1.330 -    /// It gives back true when the header line start with \c @nodes,
   1.331 +    /// It gives back true when the header line start with \c \@nodes,
   1.332      /// and the header line's id and the writer's id are the same.
   1.333      virtual std::string header() {
   1.334        return "@nodes " + id;
   1.335 @@ -644,7 +841,7 @@
   1.336    };
   1.337  
   1.338    /// \ingroup io_group
   1.339 -  /// \brief SectionWriter for writeing labeled edges.
   1.340 +  /// \brief SectionWriter for writing labeled edges.
   1.341    ///
   1.342    /// The edges section's header line is \c \@edges \c edges_id, but the
   1.343    /// \c edges_id may be empty.
   1.344 @@ -681,9 +878,9 @@
   1.345  
   1.346    public:
   1.347  
   1.348 -    /// \brief Add an edge writer command for the NodeWriter.
   1.349 +    /// \brief Add an edge writer command for the EdgeWriter.
   1.350      ///
   1.351 -    /// Add an edge writer command for the NodeWriter.
   1.352 +    /// Add an edge writer command for the EdgeWriter.
   1.353      void writeEdge(const std::string& name, const Item& item) {
   1.354        writers.push_back(make_pair(name, &item));
   1.355      }
   1.356 @@ -692,7 +889,85 @@
   1.357  
   1.358      /// \brief Header checking function.
   1.359      ///
   1.360 -    /// It gives back true when the header line start with \c @nodes,
   1.361 +    /// It gives back true when the header line start with \c \@edges,
   1.362 +    /// and the header line's id and the writer's id are the same.
   1.363 +    virtual std::string header() {
   1.364 +      return "@edges " + id;
   1.365 +    }
   1.366 +
   1.367 +    /// \brief  Writer function of the section.
   1.368 +    ///
   1.369 +    /// Write the content of the section.
   1.370 +    virtual void write(std::ostream& os) {
   1.371 +      for (int i = 0; i < (int)writers.size(); ++i) {
   1.372 +	os << writers[i].first << ' ';
   1.373 +	idWriter->write(os, *(writers[i].second));
   1.374 +	os << std::endl;
   1.375 +      }
   1.376 +    }
   1.377 +    
   1.378 +  private:
   1.379 +
   1.380 +    std::string id;
   1.381 +
   1.382 +    typedef std::vector<std::pair<std::string, const Item*> > ItemWriters;
   1.383 +    ItemWriters writers;
   1.384 +
   1.385 +    std::auto_ptr<IdWriterBase<Item> > idWriter;
   1.386 +  };
   1.387 +
   1.388 +  /// \ingroup io_group
   1.389 +  /// \brief SectionWriter for writing labeled undirected edges.
   1.390 +  ///
   1.391 +  /// The undirected edges section's header line is \c \@undiredges 
   1.392 +  /// \c undiredges_id, but the \c undiredges_id may be empty.
   1.393 +  ///
   1.394 +  /// Each line in the section contains the label of the undirected edge and 
   1.395 +  /// then the undirected edge id. 
   1.396 +  ///
   1.397 +  /// \relates LemonWriter
   1.398 +  template <typename _Graph>
   1.399 +  class UndirEdgeWriter : public CommonSectionWriterBase {
   1.400 +    typedef CommonSectionWriterBase Parent;
   1.401 +    typedef _Graph Graph;
   1.402 +    typedef typename Graph::UndirEdge Item;
   1.403 +  public:
   1.404 +    
   1.405 +    /// \brief Constructor.
   1.406 +    ///
   1.407 +    /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
   1.408 +    /// attach it into the given LemonWriter. The given \c _IdWriter
   1.409 +    /// will write the undirected edges' id what can be an undirected 
   1.410 +    /// edgeset writer.
   1.411 +    template <typename _IdWriter>
   1.412 +    UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
   1.413 +	       const std::string& _id = std::string()) 
   1.414 +      : Parent(_writer), id(_id), 
   1.415 +	idWriter(new IdWriter<typename Graph::UndirEdge, _IdWriter>
   1.416 +		 (_idWriter)) {} 
   1.417 +
   1.418 +    /// \brief Destructor.
   1.419 +    ///
   1.420 +    /// Destructor for UndirEdgeWriter.
   1.421 +    virtual ~UndirEdgeWriter() {}
   1.422 +  private:
   1.423 +    UndirEdgeWriter(const UndirEdgeWriter&);
   1.424 +    void operator=(const UndirEdgeWriter&);
   1.425 +
   1.426 +  public:
   1.427 +
   1.428 +    /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
   1.429 +    ///
   1.430 +    /// Add an edge writer command for the UndirEdgeWriter.
   1.431 +    void writeUndirEdge(const std::string& name, const Item& item) {
   1.432 +      writers.push_back(make_pair(name, &item));
   1.433 +    }
   1.434 +
   1.435 +  protected:
   1.436 +
   1.437 +    /// \brief Header checking function.
   1.438 +    ///
   1.439 +    /// It gives back true when the header line start with \c \@undiredges,
   1.440      /// and the header line's id and the writer's id are the same.
   1.441      virtual std::string header() {
   1.442        return "@edges " + id;