diff -r e37cca875667 -r 7a21e1414c38 src/lemon/lemon_writer.h --- a/src/lemon/lemon_writer.h Sat May 14 17:37:33 2005 +0000 +++ b/src/lemon/lemon_writer.h Sat May 14 17:39:37 2005 +0000 @@ -31,7 +31,10 @@ #include #include +#include #include +#include +#include namespace lemon { @@ -163,8 +166,6 @@ CommonSectionWriterBase(LemonWriter& _writer) : Parent(_writer) {} - // Writers - template class WriterBase { public: @@ -184,7 +185,7 @@ typedef typename Writer::Value Value; typedef _Item Item; - const Map& map; + typename SmartConstReference::Type map; Writer writer; MapWriter(const Map& _map, const Writer& _writer) @@ -306,8 +307,8 @@ /// /// Add a new node map writer command for the writer. template - NodeSetWriter& writeMap(std::string name, const Map& map) { - return writeMap, Map>(name, map); } @@ -315,8 +316,8 @@ /// /// Add a new node map writer command for the writer. template - NodeSetWriter& writeMap(std::string name, const Map& map, - const Writer& writer = Writer()) { + NodeSetWriter& writeNodeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { writers.push_back( make_pair(name, new MapWriter(map, writer))); return *this; @@ -394,15 +395,15 @@ WriterBase* idMap; bool forceIdMap; - const Graph& graph; + typename SmartConstReference::Type graph; std::string id; }; /// \ingroup io_group - /// \brief SectionWriter for writing a graph's edgeset. + /// \brief SectionWriter for writing a graph's edgesets. /// - /// The lemon format can store multiple graph edgesets with several maps. + /// The lemon format can store multiple graph edgesets with several maps. /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the /// \c edgeset_id may be empty. /// @@ -413,7 +414,7 @@ /// /// If the edgeset contains an \c "id" named map then it will be regarded /// as id map. This map should contain only unique values and when the - /// \c writeId() member will be called with a edge it will write it's id. + /// \c writeId() member will be called with an edge it will write it's id. /// Otherwise if the \c _forceIdMap constructor parameter is true then /// the id map will be the id in the graph. /// @@ -436,7 +437,7 @@ /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and /// attach it into the given LemonWriter. It will write node ids by /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true - /// then the writer will write own id map when the user does not give + /// then the writer will write own id map if the user does not give /// "id" named map. template EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, @@ -464,21 +465,21 @@ public: - /// \brief Add a new node map writer command for the writer. + /// \brief Add a new edge map writer command for the writer. /// - /// Add a new node map writer command for the writer. + /// Add a new edge map writer command for the writer. template - EdgeSetWriter& writeMap(std::string name, const Map& map) { - return writeMap, Map>(name, map); } - /// \brief Add a new node map writer command for the writer. + /// \brief Add a new edge map writer command for the writer. /// - /// Add a new node map writer command for the writer. + /// Add a new edge map writer command for the writer. template - EdgeSetWriter& writeMap(std::string name, const Map& map, - const Writer& writer = Writer()) { + EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { writers.push_back( make_pair(name, new MapWriter(map, writer))); return *this; @@ -561,7 +562,203 @@ WriterBase* idMap; bool forceIdMap; - const Graph& graph; + typename SmartConstReference::Type graph; + std::string id; + + std::auto_ptr > nodeIdWriter; + }; + + /// \ingroup io_group + /// \brief SectionWriter for writing a undirected edgeset. + /// + /// The lemon format can store multiple undirected edgesets with several + /// maps. The undirected edgeset section's header line is \c \@undiredgeset + /// \c undiredgeset_id, but the \c undiredgeset_id may be empty. + /// + /// The first line of the section contains the names of the maps separated + /// with white spaces. Each next lines describes an undirected edge in the + /// edgeset. The line contains the two connected nodes' id and the mapped + /// values for each undirected map. + /// + /// The section can handle the directed as a syntactical sugar. Two + /// undirected edge map describes one directed edge map. This two maps + /// are the forward map and the backward map and the names of this map + /// is near the same just with a prefix \c '+' or \c '-' character + /// difference. + /// + /// If the edgeset contains an \c "id" named map then it will be regarded + /// as id map. This map should contain only unique values and when the + /// \c writeId() member will be called with an undirected edge it will + /// write it's id. Otherwise if the \c _forceIdMap constructor parameter + /// is true then the id map will be the id in the graph. + /// + /// The undirected edgeset writer needs a node id writer to identify + /// which nodes have to be connected. If a NodeSetWriter can write the + /// nodes' id, it will be able to use with this class. + /// + /// \relates LemonWriter + template + class UndirEdgeSetWriter : public CommonSectionWriterBase { + typedef CommonSectionWriterBase Parent; + public: + + typedef _Graph Graph; + typedef _Traits Traits; + typedef typename Graph::UndirEdge Item; + + /// \brief Constructor. + /// + /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter + /// and attach it into the given LemonWriter. It will write node ids by + /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true + /// then the writer will write own id map if the user does not give + /// "id" named map. + template + UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, + const NodeIdWriter& _nodeIdWriter, + const std::string& _id = std::string(), + bool _forceIdMap = true) + : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), + graph(_graph), id(_id), + nodeIdWriter(new IdWriter + (_nodeIdWriter)) {} + + /// \brief Destructor. + /// + /// Destructor for UndirEdgeSetWriter. + virtual ~UndirEdgeSetWriter() { + typename MapWriters::iterator it; + for (it = writers.begin(); it != writers.end(); ++it) { + delete it->second; + } + } + + private: + UndirEdgeSetWriter(const UndirEdgeSetWriter&); + void operator=(const UndirEdgeSetWriter&); + + public: + + /// \brief Add a new undirected edge map writer command for the writer. + /// + /// Add a new undirected map writer command for the writer. + template + UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) { + return writeUndirEdgeMap, Map>(name, map); + } + + /// \brief Add a new undirected map writer command for the writer. + /// + /// Add a new undirected map writer command for the writer. + template + UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { + writers.push_back( + make_pair(name, new MapWriter(map, writer))); + return *this; + } + + /// \brief Add a new directed edge map writer command for the writer. + /// + /// Add a new directed map writer command for the writer. + template + UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) { + writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map)); + writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map)); + return *this; + } + + /// \brief Add a new directed map writer command for the writer. + /// + /// Add a new directed map writer command for the writer. + template + UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { + writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer); + writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer); + return *this; + } + + protected: + + /// \brief The header of the section. + /// + /// It gives back the header of the section. + virtual std::string header() { + return "@undiredgeset " + id; + } + + /// \brief Writer function of the section. + /// + /// Write the content of the section. + virtual void write(std::ostream& os) { + for (int i = 0; i < (int)writers.size(); ++i) { + if (writers[i].first == "id") { + idMap = writers[i].second; + forceIdMap = false; + break; + } + } + os << "\t\t"; + if (forceIdMap) { + os << "id\t"; + } + for (int i = 0; i < (int)writers.size(); ++i) { + os << writers[i].first << '\t'; + } + os << std::endl; + for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) { + nodeIdWriter->write(os, graph.source(it)); + os << '\t'; + nodeIdWriter->write(os, graph.target(it)); + os << '\t'; + if (forceIdMap) { + os << graph.id(it) << '\t'; + } + for (int i = 0; i < (int)writers.size(); ++i) { + writers[i].second->write(os, it); + os << '\t'; + } + os << std::endl; + } + } + + public: + + /// \brief Returns true if the undirected edgeset can write the ids of + /// the edges. + /// + /// Returns true if the undirected edgeset can write the ids of the + /// undirected edges. It is possible only if an "id" named map was + /// written or the \c _forceIdMap constructor parameter was true. + bool isIdWriter() const { + return forceIdMap || idMap != 0; + } + + /// \brief Write the id of the given undirected edge. + /// + /// It writes the id of the given undirected edge. If there was written + /// an "id" named map then it will write the map value belongs to the + /// undirected edge. Otherwise if the \c forceId parameter was true it + /// will write its id in the graph. + void writeId(std::ostream& os, const Item& item) const { + if (forceIdMap) { + os << graph.id(item); + } else { + idMap->write(os, item); + } + } + + private: + + typedef std::vector*> > MapWriters; + MapWriters writers; + + WriterBase* idMap; + bool forceIdMap; + + typename SmartConstReference::Type graph; std::string id; std::auto_ptr > nodeIdWriter; @@ -617,7 +814,7 @@ /// \brief Header checking function. /// - /// It gives back true when the header line start with \c @nodes, + /// It gives back true when the header line start with \c \@nodes, /// and the header line's id and the writer's id are the same. virtual std::string header() { return "@nodes " + id; @@ -644,7 +841,7 @@ }; /// \ingroup io_group - /// \brief SectionWriter for writeing labeled edges. + /// \brief SectionWriter for writing labeled edges. /// /// The edges section's header line is \c \@edges \c edges_id, but the /// \c edges_id may be empty. @@ -681,9 +878,9 @@ public: - /// \brief Add an edge writer command for the NodeWriter. + /// \brief Add an edge writer command for the EdgeWriter. /// - /// Add an edge writer command for the NodeWriter. + /// Add an edge writer command for the EdgeWriter. void writeEdge(const std::string& name, const Item& item) { writers.push_back(make_pair(name, &item)); } @@ -692,7 +889,85 @@ /// \brief Header checking function. /// - /// It gives back true when the header line start with \c @nodes, + /// It gives back true when the header line start with \c \@edges, + /// and the header line's id and the writer's id are the same. + virtual std::string header() { + return "@edges " + id; + } + + /// \brief Writer function of the section. + /// + /// Write the content of the section. + virtual void write(std::ostream& os) { + for (int i = 0; i < (int)writers.size(); ++i) { + os << writers[i].first << ' '; + idWriter->write(os, *(writers[i].second)); + os << std::endl; + } + } + + private: + + std::string id; + + typedef std::vector > ItemWriters; + ItemWriters writers; + + std::auto_ptr > idWriter; + }; + + /// \ingroup io_group + /// \brief SectionWriter for writing labeled undirected edges. + /// + /// The undirected edges section's header line is \c \@undiredges + /// \c undiredges_id, but the \c undiredges_id may be empty. + /// + /// Each line in the section contains the label of the undirected edge and + /// then the undirected edge id. + /// + /// \relates LemonWriter + template + class UndirEdgeWriter : public CommonSectionWriterBase { + typedef CommonSectionWriterBase Parent; + typedef _Graph Graph; + typedef typename Graph::UndirEdge Item; + public: + + /// \brief Constructor. + /// + /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and + /// attach it into the given LemonWriter. The given \c _IdWriter + /// will write the undirected edges' id what can be an undirected + /// edgeset writer. + template + UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, + const std::string& _id = std::string()) + : Parent(_writer), id(_id), + idWriter(new IdWriter + (_idWriter)) {} + + /// \brief Destructor. + /// + /// Destructor for UndirEdgeWriter. + virtual ~UndirEdgeWriter() {} + private: + UndirEdgeWriter(const UndirEdgeWriter&); + void operator=(const UndirEdgeWriter&); + + public: + + /// \brief Add an undirected edge writer command for the UndirEdgeWriter. + /// + /// Add an edge writer command for the UndirEdgeWriter. + void writeUndirEdge(const std::string& name, const Item& item) { + writers.push_back(make_pair(name, &item)); + } + + protected: + + /// \brief Header checking function. + /// + /// It gives back true when the header line start with \c \@undiredges, /// and the header line's id and the writer's id are the same. virtual std::string header() { return "@edges " + id;