[Lemon-commits] deba: r3306 - in lemon/trunk/lemon: . bits
Lemon SVN
svn at lemon.cs.elte.hu
Tue Aug 28 16:00:43 CEST 2007
Author: deba
Date: Tue Aug 28 16:00:42 2007
New Revision: 3306
Modified:
lemon/trunk/lemon/bits/path_dump.h
lemon/trunk/lemon/graph_reader.h
lemon/trunk/lemon/graph_writer.h
lemon/trunk/lemon/lemon_reader.h
lemon/trunk/lemon/lemon_writer.h
lemon/trunk/lemon/path_utils.h
Log:
PathNodeIt
PathWriter/Reader structures
Distinict MapSet readers and writers
Modified: lemon/trunk/lemon/bits/path_dump.h
==============================================================================
--- lemon/trunk/lemon/bits/path_dump.h (original)
+++ lemon/trunk/lemon/bits/path_dump.h Tue Aug 28 16:00:42 2007
@@ -54,7 +54,9 @@
RevEdgeIt() {}
RevEdgeIt(Invalid) : path(0), current(INVALID) {}
RevEdgeIt(const PredMapPath& _path)
- : path(&_path), current(_path.target) {}
+ : path(&_path), current(_path.target) {
+ if (path->predMap[current] == INVALID) current = INVALID;
+ }
operator const typename Graph::Edge() const {
return path->predMap[current];
@@ -126,7 +128,10 @@
RevEdgeIt() {}
RevEdgeIt(Invalid) : path(0), current(INVALID) {}
RevEdgeIt(const PredMatrixMapPath& _path)
- : path(&_path), current(_path.target) {}
+ : path(&_path), current(_path.target) {
+ if (path->predMatrixMap(path->source, current) == INVALID)
+ current = INVALID;
+ }
operator const typename Graph::Edge() const {
return path->predMatrixMap(path->source, current);
Modified: lemon/trunk/lemon/graph_reader.h
==============================================================================
--- lemon/trunk/lemon/graph_reader.h (original)
+++ lemon/trunk/lemon/graph_reader.h Tue Aug 28 16:00:42 2007
@@ -324,7 +324,7 @@
/// It reads an label from the stream and gives back which edge belongs to
/// it. It is possible only if there was read a "label" named edge map.
void readLabel(std::istream& is, Edge& edge) const {
- return edgeset_reader.readLabel(is, edge);
+ edgeset_reader.readLabel(is, edge);
}
private:
@@ -443,10 +443,10 @@
const DefaultSkipper& _skipper = DefaultSkipper())
: reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
nodeset_reader(*reader, _graph, std::string(), skipper),
- u_edgeset_reader(*reader, _graph, nodeset_reader,
+ uedgeset_reader(*reader, _graph, nodeset_reader,
std::string(), skipper),
node_reader(*reader, nodeset_reader, std::string()),
- u_edge_reader(*reader, u_edgeset_reader, std::string()),
+ uedge_reader(*reader, uedgeset_reader, std::string()),
attribute_reader(*reader, std::string()) {}
/// \brief Construct a new UGraphReader.
@@ -458,10 +458,10 @@
: reader(new LemonReader(_filename)), own_reader(true),
skipper(_skipper),
nodeset_reader(*reader, _graph, std::string(), skipper),
- u_edgeset_reader(*reader, _graph, nodeset_reader,
+ uedgeset_reader(*reader, _graph, nodeset_reader,
std::string(), skipper),
node_reader(*reader, nodeset_reader, std::string()),
- u_edge_reader(*reader, u_edgeset_reader, std::string()),
+ uedge_reader(*reader, uedgeset_reader, std::string()),
attribute_reader(*reader, std::string()) {}
/// \brief Construct a new UGraphReader.
@@ -472,10 +472,10 @@
const DefaultSkipper& _skipper = DefaultSkipper())
: reader(_reader), own_reader(false), skipper(_skipper),
nodeset_reader(*reader, _graph, std::string(), skipper),
- u_edgeset_reader(*reader, _graph, nodeset_reader,
+ uedgeset_reader(*reader, _graph, nodeset_reader,
std::string(), skipper),
node_reader(*reader, nodeset_reader, std::string()),
- u_edge_reader(*reader, u_edgeset_reader, std::string()),
+ uedge_reader(*reader, uedgeset_reader, std::string()),
attribute_reader(*reader, std::string()) {}
/// \brief Destruct the graph reader.
@@ -533,13 +533,13 @@
/// Give a new undirected edge map reading command to the reader.
template <typename Map>
UGraphReader& readUEdgeMap(std::string name, Map& map) {
- u_edgeset_reader.readUEdgeMap(name, map);
+ uedgeset_reader.readUEdgeMap(name, map);
return *this;
}
template <typename Map>
UGraphReader& readUEdgeMap(std::string name, const Map& map) {
- u_edgeset_reader.readUEdgeMap(name, map);
+ uedgeset_reader.readUEdgeMap(name, map);
return *this;
}
@@ -550,14 +550,14 @@
template <typename ItemReader, typename Map>
UGraphReader& readUEdgeMap(std::string name, Map& map,
const ItemReader& ir = ItemReader()) {
- u_edgeset_reader.readUEdgeMap(name, map, ir);
+ uedgeset_reader.readUEdgeMap(name, map, ir);
return *this;
}
template <typename ItemReader, typename Map>
UGraphReader& readUEdgeMap(std::string name, const Map& map,
const ItemReader& ir = ItemReader()) {
- u_edgeset_reader.readUEdgeMap(name, map, ir);
+ uedgeset_reader.readUEdgeMap(name, map, ir);
return *this;
}
@@ -567,7 +567,7 @@
template <typename ItemReader>
UGraphReader& skipUEdgeMap(std::string name,
const ItemReader& ir = ItemReader()) {
- u_edgeset_reader.skipUMap(name, ir);
+ uedgeset_reader.skipUMap(name, ir);
return *this;
}
@@ -577,13 +577,13 @@
/// Give a new edge map reading command to the reader.
template <typename Map>
UGraphReader& readEdgeMap(std::string name, Map& map) {
- u_edgeset_reader.readEdgeMap(name, map);
+ uedgeset_reader.readEdgeMap(name, map);
return *this;
}
template <typename Map>
UGraphReader& readEdgeMap(std::string name, const Map& map) {
- u_edgeset_reader.readEdgeMap(name, map);
+ uedgeset_reader.readEdgeMap(name, map);
return *this;
}
@@ -594,14 +594,14 @@
template <typename ItemReader, typename Map>
UGraphReader& readEdgeMap(std::string name, Map& map,
const ItemReader& ir = ItemReader()) {
- u_edgeset_reader.readEdgeMap(name, map, ir);
+ uedgeset_reader.readEdgeMap(name, map, ir);
return *this;
}
template <typename ItemReader, typename Map>
UGraphReader& readEdgeMap(std::string name, const Map& map,
const ItemReader& ir = ItemReader()) {
- u_edgeset_reader.readEdgeMap(name, map, ir);
+ uedgeset_reader.readEdgeMap(name, map, ir);
return *this;
}
@@ -611,7 +611,7 @@
template <typename ItemReader>
UGraphReader& skipEdgeMap(std::string name,
const ItemReader& ir = ItemReader()) {
- u_edgeset_reader.skipEdgeMap(name, ir);
+ uedgeset_reader.skipEdgeMap(name, ir);
return *this;
}
@@ -627,7 +627,7 @@
///
/// Give a new labeled edge reading command to the reader.
UGraphReader& readEdge(std::string name, Edge& edge) {
- u_edge_reader.readEdge(name, edge);
+ uedge_reader.readEdge(name, edge);
}
/// \brief Give a new labeled undirected edge reading command to the
@@ -635,7 +635,7 @@
///
/// Give a new labeled undirected edge reading command to the reader.
UGraphReader& readUEdge(std::string name, UEdge& edge) {
- u_edge_reader.readUEdge(name, edge);
+ uedge_reader.readUEdge(name, edge);
}
/// \brief Give a new attribute reading command.
@@ -677,10 +677,10 @@
/// \brief Returns true if the reader can give back the items by its label.
///
- /// \brief Returns true if the reader can give back the items by its label.
+ /// Returns true if the reader can give back the items by its label.
bool isLabelReader() const {
return nodeset_reader.isLabelReader() &&
- u_edgeset_reader.isLabelReader();
+ uedgeset_reader.isLabelReader();
}
/// \brief Gives back the node by its label.
@@ -696,7 +696,7 @@
/// It reads an label from the stream and gives back which edge belongs to
/// it. It is possible only if there was read a "label" named edge map.
void readLabel(std::istream& is, Edge& edge) const {
- return u_edgeset_reader.readLabel(is, edge);
+ return uedgeset_reader.readLabel(is, edge);
}
/// \brief Gives back the undirected edge by its label.
@@ -705,7 +705,7 @@
/// belongs to it. It is possible only if there was read a "label" named
/// edge map.
void readLabel(std::istream& is, UEdge& uedge) const {
- return u_edgeset_reader.readLabel(is, uedge);
+ return uedgeset_reader.readLabel(is, uedge);
}
@@ -717,10 +717,10 @@
DefaultSkipper skipper;
NodeSetReader<Graph, ReaderTraits> nodeset_reader;
- UEdgeSetReader<Graph, ReaderTraits> u_edgeset_reader;
+ UEdgeSetReader<Graph, ReaderTraits> uedgeset_reader;
NodeReader<Graph> node_reader;
- UEdgeReader<Graph> u_edge_reader;
+ UEdgeReader<Graph> uedge_reader;
AttributeReader<ReaderTraits> attribute_reader;
};
Modified: lemon/trunk/lemon/graph_writer.h
==============================================================================
--- lemon/trunk/lemon/graph_writer.h (original)
+++ lemon/trunk/lemon/graph_writer.h Tue Aug 28 16:00:42 2007
@@ -251,9 +251,17 @@
writer->run();
}
+ /// \brief Returns true if the writer can give back the labels by the items.
+ ///
+ /// Returns true if the writer can give back the the labels by the items.
+ bool isLabelWriter() const {
+ return nodeset_writer.isLabelWriter() &&
+ edgeset_writer.isLabelWriter();
+ }
+
/// \brief Write the label of the given node.
///
- /// It writes the label of the given node. If there was written an "label"
+ /// It writes the label of the given node. If there was written a "label"
/// named node map then it will write the map value belonging to the node.
void writeLabel(std::ostream& os, const Node& item) const {
nodeset_writer.writeLabel(os, item);
@@ -261,12 +269,32 @@
/// \brief Write the label of the given edge.
///
- /// It writes the label of the given edge. If there was written an "label"
+ /// It writes the label of the given edge. If there was written a "label"
/// named edge map then it will write the map value belonging to the edge.
void writeLabel(std::ostream& os, const Edge& item) const {
edgeset_writer.writeLabel(os, item);
}
+ /// \brief Sorts the given node vector by label.
+ ///
+ /// Sorts the given node vector by label. If there was written an
+ /// "label" named map then the vector will be sorted by the values
+ /// of this map. Otherwise if the \c forceLabel parameter was true
+ /// it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<Node>& nodes) const {
+ nodeset_writer.sortByLabel(nodes);
+ }
+
+ /// \brief Sorts the given edge vector by label.
+ ///
+ /// Sorts the given edge vector by label. If there was written an
+ /// "label" named map then the vector will be sorted by the values
+ /// of this map. Otherwise if the \c forceLabel parameter was true
+ /// it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<Edge>& edges) const {
+ edgeset_writer.sortByLabel(edges);
+ }
+
private:
LemonWriter* writer;
@@ -370,9 +398,9 @@
UGraphWriter(std::ostream& _os, const Graph& _graph)
: writer(new LemonWriter(_os)), own_writer(true),
nodeset_writer(*writer, _graph, std::string()),
- u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
+ uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
node_writer(*writer, nodeset_writer, std::string()),
- u_edge_writer(*writer, u_edgeset_writer, std::string()),
+ uedge_writer(*writer, uedgeset_writer, std::string()),
attribute_writer(*writer, std::string()) {}
/// \brief Construct a new UGraphWriter.
@@ -382,21 +410,21 @@
UGraphWriter(const std::string& _filename, const Graph& _graph)
: writer(new LemonWriter(_filename)), own_writer(true),
nodeset_writer(*writer, _graph, std::string()),
- u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
+ uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
node_writer(*writer, nodeset_writer, std::string()),
- u_edge_writer(*writer, u_edgeset_writer, std::string()),
+ uedge_writer(*writer, uedgeset_writer, std::string()),
attribute_writer(*writer, std::string()) {}
/// \brief Construct a new UGraphWriter.
///
/// Construct a new UGraphWriter. It writes the given graph
- /// to given LemonReader.
+ /// to given LemonWriter.
UGraphWriter(LemonWriter& _writer, const Graph& _graph)
: writer(_writer), own_writer(false),
nodeset_writer(*writer, _graph, std::string()),
- u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
+ uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
node_writer(*writer, nodeset_writer, std::string()),
- u_edge_writer(*writer, u_edgeset_writer, std::string()),
+ uedge_writer(*writer, uedgeset_writer, std::string()),
attribute_writer(*writer, std::string()) {}
/// \brief Destruct the graph writer.
@@ -434,7 +462,7 @@
/// the writer.
template <typename Map>
UGraphWriter& writeEdgeMap(std::string label, const Map& map) {
- u_edgeset_writer.writeEdgeMap(label, map);
+ uedgeset_writer.writeEdgeMap(label, map);
return *this;
}
@@ -445,7 +473,7 @@
template <typename ItemWriter, typename Map>
UGraphWriter& writeEdgeMap(std::string label, const Map& map,
const ItemWriter& iw = ItemWriter()) {
- u_edgeset_writer.writeEdgeMap(label, map, iw);
+ uedgeset_writer.writeEdgeMap(label, map, iw);
return *this;
}
@@ -455,7 +483,7 @@
/// command</i> to the writer.
template <typename Map>
UGraphWriter& writeUEdgeMap(std::string label, const Map& map) {
- u_edgeset_writer.writeUEdgeMap(label, map);
+ uedgeset_writer.writeUEdgeMap(label, map);
return *this;
}
@@ -466,7 +494,7 @@
template <typename ItemWriter, typename Map>
UGraphWriter& writeUEdgeMap(std::string label, const Map& map,
const ItemWriter& iw = ItemWriter()) {
- u_edgeset_writer.writeUEdgeMap(label, map, iw);
+ uedgeset_writer.writeUEdgeMap(label, map, iw);
return *this;
}
@@ -484,7 +512,7 @@
/// This function issues a new <i> labeled edge writing
/// command</i> to the writer.
UGraphWriter& writeEdge(std::string label, const Edge& edge) {
- u_edge_writer.writeEdge(label, edge);
+ uedge_writer.writeEdge(label, edge);
}
/// \brief Issue a new labeled undirected edge writing command to
@@ -493,7 +521,7 @@
/// Issue a new <i>labeled undirected edge writing command</i> to
/// the writer.
UGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
- u_edge_writer.writeUEdge(label, edge);
+ uedge_writer.writeUEdge(label, edge);
}
/// \brief Issue a new attribute writing command.
@@ -534,9 +562,17 @@
writer->run();
}
+ /// \brief Returns true if the writer can give back the labels by the items.
+ ///
+ /// Returns true if the writer can give back the the labels by the items.
+ bool isLabelWriter() const {
+ return nodeset_writer.isLabelWriter() &&
+ uedgeset_writer.isLabelWriter();
+ }
+
/// \brief Write the label of the given node.
///
- /// It writes the label of the given node. If there was written an "label"
+ /// It writes the label of the given node. If there was written a "label"
/// named node map then it will write the map value belonging to the node.
void writeLabel(std::ostream& os, const Node& item) const {
nodeset_writer.writeLabel(os, item);
@@ -544,21 +580,50 @@
/// \brief Write the label of the given edge.
///
- /// It writes the label of the given edge. If there was written an "label"
+ /// It writes the label of the given edge. If there was written a "label"
/// named edge map then it will write the map value belonging to the edge.
void writeLabel(std::ostream& os, const Edge& item) const {
- u_edgeset_writer.writeLabel(os, item);
+ uedgeset_writer.writeLabel(os, item);
}
/// \brief Write the label of the given undirected edge.
///
/// It writes the label of the given undirected edge. If there was
- /// written an "label" named edge map then it will write the map
+ /// written a "label" named edge map then it will write the map
/// value belonging to the edge.
void writeLabel(std::ostream& os, const UEdge& item) const {
- u_edgeset_writer.writeLabel(os, item);
+ uedgeset_writer.writeLabel(os, item);
}
+ /// \brief Sorts the given node vector by label.
+ ///
+ /// Sorts the given node vector by label. If there was written an
+ /// "label" named map then the vector will be sorted by the values
+ /// of this map. Otherwise if the \c forceLabel parameter was true
+ /// it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<Node>& nodes) const {
+ nodeset_writer.sortByLabel(nodes);
+ }
+
+ /// \brief Sorts the given edge vector by label.
+ ///
+ /// Sorts the given edge vector by label. If there was written an
+ /// "label" named map then the vector will be sorted by the values
+ /// of this map. Otherwise if the \c forceLabel parameter was true
+ /// it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<Edge>& edges) const {
+ uedgeset_writer.sortByLabel(edges);
+ }
+
+ /// \brief Sorts the given undirected edge vector by label.
+ ///
+ /// Sorts the given undirected edge vector by label. If there was
+ /// written an "label" named map then the vector will be sorted by
+ /// the values of this map. Otherwise if the \c forceLabel
+ /// parameter was true it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<UEdge>& uedges) const {
+ uedgeset_writer.sortByLabel(uedges);
+ }
private:
@@ -566,10 +631,10 @@
bool own_writer;
NodeSetWriter<Graph, WriterTraits> nodeset_writer;
- UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
+ UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
NodeWriter<Graph> node_writer;
- UEdgeWriter<Graph> u_edge_writer;
+ UEdgeWriter<Graph> uedge_writer;
AttributeWriter<WriterTraits> attribute_writer;
};
Modified: lemon/trunk/lemon/lemon_reader.h
==============================================================================
--- lemon/trunk/lemon/lemon_reader.h (original)
+++ lemon/trunk/lemon/lemon_reader.h Tue Aug 28 16:00:42 2007
@@ -58,7 +58,7 @@
return p < q;
}
};
-
+
template <typename Item>
class ItemLabelReader {
public:
@@ -255,7 +255,7 @@
return it->second;
} else {
ErrorMessage msg;
- msg << "Invalid label error: " << value;
+ msg << "Invalid label error";
throw DataFormatError(msg.message());
}
}
@@ -289,7 +289,7 @@
virtual Item read(std::istream& is) const {
Value value;
- reader.read(is, value);
+ reader.read(is, value);
typename Inverse::const_iterator it = inverse.find(value);
if (it != inverse.end()) {
return it->second;
@@ -382,6 +382,7 @@
virtual ~LabelReaderBase() {}
virtual Item read(std::istream& is) const = 0;
virtual bool isLabelReader() const = 0;
+ virtual LabelReaderBase<_Item>* clone() const = 0;
};
template <typename _Item, typename _BoxedLabelReader>
@@ -390,19 +391,23 @@
typedef _Item Item;
typedef _BoxedLabelReader BoxedLabelReader;
- const BoxedLabelReader& boxedLabelReader;
+ const BoxedLabelReader& labelReader;
- LabelReader(const BoxedLabelReader& _boxedLabelReader)
- : boxedLabelReader(_boxedLabelReader) {}
+ LabelReader(const BoxedLabelReader& _labelReader)
+ : labelReader(_labelReader) {}
virtual Item read(std::istream& is) const {
Item item;
- boxedLabelReader.readLabel(is, item);
+ labelReader.readLabel(is, item);
return item;
}
virtual bool isLabelReader() const {
- return boxedLabelReader.isLabelReader();
+ return labelReader.isLabelReader();
+ }
+
+ LabelReader<Item, BoxedLabelReader>* clone() const {
+ return new LabelReader<Item, BoxedLabelReader>(labelReader);
}
};
@@ -723,7 +728,6 @@
it->second = true;
char buf[2048];
FilterStreamBuf buffer(*is, line_num);
-
try {
buffer.pubsetbuf(buf, sizeof(buf));
std::istream ss(&buffer);
@@ -1511,8 +1515,8 @@
///
/// It reads an id from the stream and gives back which undirected edge
/// belongs to it. It is possible only if there was read an "label" named map.
- void readLabel(std::istream& is, UEdge& uEdge) const {
- uEdge = inverter->read(is);
+ void readLabel(std::istream& is, UEdge& uedge) const {
+ uedge = inverter->read(is);
}
/// \brief Gives back the directed edge by its label.
@@ -1524,11 +1528,11 @@
void readLabel(std::istream& is, Edge& edge) const {
char c;
is >> c;
- UEdge uEdge = inverter->read(is);
+ UEdge uedge = inverter->read(is);
if (c == '+') {
- edge = graph.direct(uEdge, true);
+ edge = graph.direct(uedge, true);
} else if (c == '-') {
- edge = graph.direct(uEdge, false);
+ edge = graph.direct(uedge, false);
} else {
throw DataFormatError("Wrong id format for edge "
"in undirected edgeset");
@@ -1807,10 +1811,10 @@
: Parent(_reader), name(_name) {
checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
- uEdgeLabelReader.reset(new _reader_bits::
- LabelReader<UEdge, _LabelReader>(_labelReader));
+ uedgeLabelReader.reset(new _reader_bits::
+ LabelReader<UEdge, _LabelReader>(_labelReader));
edgeLabelReader.reset(new _reader_bits::
- LabelReader<Edge, _LabelReader>(_labelReader));
+ LabelReader<Edge, _LabelReader>(_labelReader));
}
/// \brief Destructor.
@@ -1827,12 +1831,12 @@
///
/// Add an undirected edge reader command for the UEdgeReader.
void readUEdge(std::string label, UEdge& item) {
- if (uEdgeReaders.find(label) != uEdgeReaders.end()) {
+ if (uedgeReaders.find(label) != uedgeReaders.end()) {
ErrorMessage msg;
msg << "Multiple read rule for undirected edge: " << label;
throw IoParameterError(msg.message());
}
- uEdgeReaders.insert(make_pair(label, _reader_bits::
+ uedgeReaders.insert(make_pair(label, _reader_bits::
ItemStore<UEdge>(item)));
}
@@ -1870,7 +1874,7 @@
if (!edgeLabelReader->isLabelReader()) {
throw DataFormatError("Cannot find undirected edgeset or label map");
}
- if (!uEdgeLabelReader->isLabelReader()) {
+ if (!uedgeLabelReader->isLabelReader()) {
throw DataFormatError("Cannot find undirected edgeset or label map");
}
std::string line;
@@ -1879,9 +1883,9 @@
std::string id;
ls >> id;
{
- typename UEdgeReaders::iterator it = uEdgeReaders.find(id);
- if (it != uEdgeReaders.end()) {
- it->second.read(uEdgeLabelReader->read(ls));
+ typename UEdgeReaders::iterator it = uedgeReaders.find(id);
+ if (it != uedgeReaders.end()) {
+ it->second.read(uedgeLabelReader->read(ls));
it->second.touch();
continue;
}
@@ -1902,8 +1906,8 @@
throw IoParameterError(msg.message());
}
}
- for (typename UEdgeReaders::iterator it = uEdgeReaders.begin();
- it != uEdgeReaders.end(); ++it) {
+ for (typename UEdgeReaders::iterator it = uedgeReaders.begin();
+ it != uedgeReaders.end(); ++it) {
if (!it->second.touched()) {
ErrorMessage msg;
msg << "UEdge not found in file: " << it->first;
@@ -1913,7 +1917,7 @@
}
virtual void missing() {
- if (edgeReaders.empty() && uEdgeReaders.empty()) return;
+ if (edgeReaders.empty() && uedgeReaders.empty()) return;
ErrorMessage msg;
msg << "UEdges section not found in file: @uedges " << name;
throw IoParameterError(msg.message());
@@ -1925,8 +1929,8 @@
typedef std::map<std::string,
_reader_bits::ItemStore<UEdge> > UEdgeReaders;
- UEdgeReaders uEdgeReaders;
- std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uEdgeLabelReader;
+ UEdgeReaders uedgeReaders;
+ std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uedgeLabelReader;
typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
EdgeReaders edgeReaders;
@@ -2054,6 +2058,671 @@
};
/// \ingroup section_io
+ /// \brief SectionReader for reading extra node maps.
+ ///
+ /// The lemon format can store maps in the nodeset sections. This
+ /// class let you make distinict section to store maps. The main
+ /// purpose of this class is a logical separation of some maps. The
+ /// other useful application could be to store paths in node maps.
+ ///
+ /// The first line of the section contains the names of the maps
+ /// separated with white spaces. Each next line describes an item
+ /// in the itemset, and contains in the first column the label of
+ /// the item and then the mapped values for each map.
+ ///
+ /// \relates LemonReader
+ template <typename _Graph, typename _Traits = DefaultReaderTraits>
+ class NodeMapReader : public LemonReader::SectionReader {
+ typedef LemonReader::SectionReader Parent;
+ public:
+
+ typedef _Graph Graph;
+ typedef typename Graph::Node Node;
+ typedef _Traits Traits;
+ typedef typename Traits::Skipper DefaultSkipper;
+
+ /// \brief Constructor.
+ ///
+ /// Constructor for NodeMapReader. It creates the NodeMapReader and
+ /// attach it into the given LemonReader. The reader will read
+ /// the section when the \c section_name and the \c _name are the same.
+ template <typename _LabelReader>
+ NodeMapReader(LemonReader& _reader,
+ const Graph& _graph,
+ const _LabelReader& _labelReader,
+ const std::string& _name = std::string(),
+ const DefaultSkipper& _skipper = DefaultSkipper())
+ : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
+ labelReader.reset(new _reader_bits::
+ LabelReader<Node, _LabelReader>(_labelReader));
+ }
+
+
+ /// \brief Destructor.
+ ///
+ /// Destructor for NodeMapReader.
+ virtual ~NodeMapReader() {
+ for (typename MapReaders::iterator it = readers.begin();
+ it != readers.end(); ++it) {
+ delete it->second;
+ }
+ }
+
+ private:
+ NodeMapReader(const NodeMapReader&);
+ void operator=(const NodeMapReader&);
+
+ public:
+
+ /// \brief Add a new node map reader command for the reader.
+ ///
+ /// Add a new node map reader command for the reader.
+ template <typename Map>
+ NodeMapReader& readNodeMap(std::string label, Map& map) {
+ return _readMap<
+ typename Traits::template Reader<typename Map::Value>, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map);
+ }
+
+ template <typename Map>
+ NodeMapReader& readNodeMap(std::string label, const Map& map) {
+ return _readMap<
+ typename Traits::template Reader<typename Map::Value>, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map);
+ }
+
+ /// \brief Add a new node map reader command for the reader.
+ ///
+ /// Add a new node map reader command for the reader.
+ template <typename ItemReader, typename Map>
+ NodeMapReader& readNodeMap(std::string label, Map& map,
+ const ItemReader& ir = ItemReader()) {
+ return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
+ (label, map, ir);
+ }
+
+ template <typename ItemReader, typename Map>
+ NodeMapReader& readNodeMap(std::string label, const Map& map,
+ const ItemReader& ir = ItemReader()) {
+ return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
+ (label, map, ir);
+ }
+
+ private:
+
+ template <typename ItemReader, typename Map, typename MapParameter>
+ NodeMapReader& _readMap(std::string label, MapParameter map,
+ const ItemReader& ir = ItemReader()) {
+ checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+ checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
+ if (readers.find(label) != readers.end()) {
+ ErrorMessage msg;
+ msg << "Multiple read rule for map: " << label;
+ throw IoParameterError(msg.message());
+ }
+ readers.insert(
+ make_pair(label, new _reader_bits::
+ MapReader<Node, Map, ItemReader>(map, ir)));
+ return *this;
+ }
+
+ public:
+
+ /// \brief Add a new node map skipper command for the reader.
+ ///
+ /// Add a new node map skipper command for the reader.
+ template <typename ItemReader>
+ NodeMapReader& skipNodeMap(std::string label,
+ const ItemReader& ir = ItemReader()) {
+ if (readers.find(label) != readers.end()) {
+ ErrorMessage msg;
+ msg << "Multiple read rule for map: " << label;
+ throw IoParameterError(msg.message());
+ }
+ readers.insert(make_pair(label, new _reader_bits::
+ SkipReader<Node, ItemReader>(ir)));
+ return *this;
+ }
+
+ protected:
+
+ /// \brief Gives back true when the SectionReader can process
+ /// the section with the given header line.
+ ///
+ /// It gives back true when the header line starts with \c \@mapset,
+ /// and the header line's name and the mapset's name are the same.
+ virtual bool header(const std::string& line) {
+ std::istringstream ls(line);
+ std::string command;
+ std::string id;
+ ls >> command >> id;
+ return command == "@nodemaps" && name == id;
+ }
+
+ /// \brief Reader function of the section.
+ ///
+ /// It reads the content of the section.
+ virtual void read(std::istream& is) {
+ std::vector<_reader_bits::MapReaderBase<Node>* > index;
+ std::string line;
+
+ {
+ getline(is, line);
+ std::istringstream ls(line);
+ std::string id;
+ while (ls >> id) {
+ typename MapReaders::iterator it = readers.find(id);
+ if (it != readers.end()) {
+ it->second->touch();
+ index.push_back(it->second);
+ } else {
+ index.push_back(&skipper);
+ }
+ }
+ }
+ for (typename MapReaders::iterator it = readers.begin();
+ it != readers.end(); ++it) {
+ if (!it->second->touched()) {
+ ErrorMessage msg;
+ msg << "Map not found in file: " << it->first;
+ throw IoParameterError(msg.message());
+ }
+ }
+ while (getline(is, line)) {
+ std::istringstream ls(line);
+ Node node = labelReader->read(ls);
+ for (int i = 0; i < int(index.size()); ++i) {
+ index[i]->read(ls, node);
+ }
+ }
+ }
+
+ virtual void missing() {
+ if (readers.empty()) return;
+ ErrorMessage msg;
+ msg << "NodeMap section not found in file: @nodemaps " << name;
+ throw IoParameterError(msg.message());
+ }
+
+ private:
+
+ typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
+ MapReaders readers;
+
+ const Graph& graph;
+ std::string name;
+ _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
+ std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader;
+
+ };
+
+ /// \ingroup section_io
+ /// \brief SectionReader for reading extra edge maps.
+ ///
+ /// The lemon format can store maps in the edgeset sections. This
+ /// class let you make distinict section to store maps. The main
+ /// purpose of this class is a logical separation of some maps. The
+ /// other useful application could be to store paths in edge maps.
+ ///
+ /// The first line of the section contains the names of the maps
+ /// separated with white spaces. Each next line describes an item
+ /// in the itemset, and contains in the first column the label of
+ /// the item and then the mapped values for each map.
+ ///
+ /// \relates LemonReader
+ template <typename _Graph, typename _Traits = DefaultReaderTraits>
+ class EdgeMapReader : public LemonReader::SectionReader {
+ typedef LemonReader::SectionReader Parent;
+ public:
+
+ typedef _Graph Graph;
+ typedef typename Graph::Edge Edge;
+ typedef _Traits Traits;
+ typedef typename Traits::Skipper DefaultSkipper;
+
+ /// \brief Constructor.
+ ///
+ /// Constructor for EdgeMapReader. It creates the EdgeMapReader and
+ /// attach it into the given LemonReader. The reader will read
+ /// the section when the \c section_name and the \c _name are the same.
+ template <typename _LabelReader>
+ EdgeMapReader(LemonReader& _reader,
+ const Graph& _graph,
+ const _LabelReader& _labelReader,
+ const std::string& _name = std::string(),
+ const DefaultSkipper& _skipper = DefaultSkipper())
+ : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
+ labelReader.reset(new _reader_bits::
+ LabelReader<Edge, _LabelReader>(_labelReader));
+ }
+
+
+ /// \brief Destructor.
+ ///
+ /// Destructor for EdgeMapReader.
+ virtual ~EdgeMapReader() {
+ for (typename MapReaders::iterator it = readers.begin();
+ it != readers.end(); ++it) {
+ delete it->second;
+ }
+ }
+
+ private:
+ EdgeMapReader(const EdgeMapReader&);
+ void operator=(const EdgeMapReader&);
+
+ public:
+
+ /// \brief Add a new edge map reader command for the reader.
+ ///
+ /// Add a new edge map reader command for the reader.
+ template <typename Map>
+ EdgeMapReader& readEdgeMap(std::string label, Map& map) {
+ return _readMap<
+ typename Traits::template Reader<typename Map::Value>, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map);
+ }
+
+ template <typename Map>
+ EdgeMapReader& readEdgeMap(std::string label, const Map& map) {
+ return _readMap<
+ typename Traits::template Reader<typename Map::Value>, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map);
+ }
+
+ /// \brief Add a new edge map reader command for the reader.
+ ///
+ /// Add a new edge map reader command for the reader.
+ template <typename ItemReader, typename Map>
+ EdgeMapReader& readEdgeMap(std::string label, Map& map,
+ const ItemReader& ir = ItemReader()) {
+ return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
+ (label, map, ir);
+ }
+
+ template <typename ItemReader, typename Map>
+ EdgeMapReader& readEdgeMap(std::string label, const Map& map,
+ const ItemReader& ir = ItemReader()) {
+ return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
+ (label, map, ir);
+ }
+
+ private:
+
+ template <typename ItemReader, typename Map, typename MapParameter>
+ EdgeMapReader& _readMap(std::string label, MapParameter map,
+ const ItemReader& ir = ItemReader()) {
+ checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+ checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
+ if (readers.find(label) != readers.end()) {
+ ErrorMessage msg;
+ msg << "Multiple read rule for map: " << label;
+ throw IoParameterError(msg.message());
+ }
+ readers.insert(
+ make_pair(label, new _reader_bits::
+ MapReader<Edge, Map, ItemReader>(map, ir)));
+ return *this;
+ }
+
+ public:
+
+ /// \brief Add a new edge map skipper command for the reader.
+ ///
+ /// Add a new edge map skipper command for the reader.
+ template <typename ItemReader>
+ EdgeMapReader& skipEdgeMap(std::string label,
+ const ItemReader& ir = ItemReader()) {
+ if (readers.find(label) != readers.end()) {
+ ErrorMessage msg;
+ msg << "Multiple read rule for map: " << label;
+ throw IoParameterError(msg.message());
+ }
+ readers.insert(make_pair(label, new _reader_bits::
+ SkipReader<Edge, ItemReader>(ir)));
+ return *this;
+ }
+
+ protected:
+
+ /// \brief Gives back true when the SectionReader can process
+ /// the section with the given header line.
+ ///
+ /// It gives back true when the header line starts with \c \@mapset,
+ /// and the header line's name and the mapset's name are the same.
+ virtual bool header(const std::string& line) {
+ std::istringstream ls(line);
+ std::string command;
+ std::string id;
+ ls >> command >> id;
+ return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
+ }
+
+ /// \brief Reader function of the section.
+ ///
+ /// It reads the content of the section.
+ virtual void read(std::istream& is) {
+ std::vector<_reader_bits::MapReaderBase<Edge>* > index;
+ std::string line;
+
+ {
+ getline(is, line);
+ std::istringstream ls(line);
+ std::string id;
+ while (ls >> id) {
+ typename MapReaders::iterator it = readers.find(id);
+ if (it != readers.end()) {
+ it->second->touch();
+ index.push_back(it->second);
+ } else {
+ index.push_back(&skipper);
+ }
+ }
+ }
+ for (typename MapReaders::iterator it = readers.begin();
+ it != readers.end(); ++it) {
+ if (!it->second->touched()) {
+ ErrorMessage msg;
+ msg << "Map not found in file: " << it->first;
+ throw IoParameterError(msg.message());
+ }
+ }
+ while (getline(is, line)) {
+ std::istringstream ls(line);
+ Edge edge = labelReader->read(ls);
+ for (int i = 0; i < int(index.size()); ++i) {
+ index[i]->read(ls, edge);
+ }
+ }
+ }
+
+ virtual void missing() {
+ if (readers.empty()) return;
+ ErrorMessage msg;
+ msg << "EdgeMap section not found in file: @edgemaps " << name;
+ throw IoParameterError(msg.message());
+ }
+
+ private:
+
+ typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
+ MapReaders readers;
+
+ const Graph& graph;
+ std::string name;
+ _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
+ std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader;
+
+ };
+
+ /// \ingroup section_io
+ /// \brief SectionReader for reading extra undirected edge maps.
+ ///
+ /// The lemon format can store maps in the uedgeset sections. This
+ /// class let you make distinict section to store maps. The main
+ /// purpose of this class is a logical separation of some maps. The
+ /// other useful application could be to store paths in undirected
+ /// edge maps.
+ ///
+ /// The first line of the section contains the names of the maps
+ /// separated with white spaces. Each next line describes an item
+ /// in the itemset, and contains in the first column the label of
+ /// the item and then the mapped values for each map.
+ ///
+ /// \relates LemonReader
+ template <typename _Graph, typename _Traits = DefaultReaderTraits>
+ class UEdgeMapReader : public LemonReader::SectionReader {
+ typedef LemonReader::SectionReader Parent;
+ public:
+
+ typedef _Graph Graph;
+ typedef typename Graph::Edge Edge;
+ typedef typename Graph::UEdge UEdge;
+ typedef _Traits Traits;
+ typedef typename Traits::Skipper DefaultSkipper;
+
+ /// \brief Constructor.
+ ///
+ /// Constructor for UEdgeMapReader. It creates the UEdgeMapReader and
+ /// attach it into the given LemonReader. The reader will read
+ /// the section when the \c section_name and the \c _name are the same.
+ template <typename _LabelReader>
+ UEdgeMapReader(LemonReader& _reader, const Graph& _graph,
+ const _LabelReader& _labelReader,
+ const std::string& _name = std::string(),
+ const DefaultSkipper& _skipper = DefaultSkipper())
+ : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
+ labelReader.reset(new _reader_bits::
+ LabelReader<UEdge, _LabelReader>(_labelReader));
+ }
+
+
+ /// \brief Destructor.
+ ///
+ /// Destructor for UEdgeMapReader.
+ virtual ~UEdgeMapReader() {
+ for (typename MapReaders::iterator it = readers.begin();
+ it != readers.end(); ++it) {
+ delete it->second;
+ }
+ }
+
+ private:
+ UEdgeMapReader(const UEdgeMapReader&);
+ void operator=(const UEdgeMapReader&);
+
+ public:
+
+ /// \brief Add a new undirected edge map reader command for the
+ /// reader.
+ ///
+ /// Add a new undirected edge map reader command for the reader.
+ template <typename Map>
+ UEdgeMapReader& readUEdgeMap(std::string label, Map& map) {
+ return _readMap<
+ typename Traits::template Reader<typename Map::Value>, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map);
+ }
+
+ template <typename Map>
+ UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) {
+ return _readMap<
+ typename Traits::template Reader<typename Map::Value>, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map);
+ }
+
+ /// \brief Add a new undirected edge map reader command for the
+ /// reader.
+ ///
+ /// Add a new undirected edge map reader command for the reader.
+ template <typename ItemReader, typename Map>
+ UEdgeMapReader& readUEdgeMap(std::string label, Map& map,
+ const ItemReader& ir = ItemReader()) {
+ return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
+ (label, map, ir);
+ }
+
+ template <typename ItemReader, typename Map>
+ UEdgeMapReader& readUEdgeMap(std::string label, const Map& map,
+ const ItemReader& ir = ItemReader()) {
+ return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
+ (label, map, ir);
+ }
+
+ private:
+
+ template <typename ItemReader, typename Map, typename MapParameter>
+ UEdgeMapReader& _readMap(std::string label, MapParameter map,
+ const ItemReader& ir = ItemReader()) {
+ checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+ checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
+ if (readers.find(label) != readers.end()) {
+ ErrorMessage msg;
+ msg << "Multiple read rule for map: " << label;
+ throw IoParameterError(msg.message());
+ }
+ readers.insert(
+ make_pair(label, new _reader_bits::
+ MapReader<UEdge, Map, ItemReader>(map, ir)));
+ return *this;
+ }
+
+ public:
+
+ /// \brief Add a new undirected edge map skipper command for the
+ /// reader.
+ ///
+ /// Add a new undirected edge map skipper command for the reader.
+ template <typename ItemReader>
+ UEdgeMapReader& skipUEdgeMap(std::string label,
+ const ItemReader& ir = ItemReader()) {
+ if (readers.find(label) != readers.end()) {
+ ErrorMessage msg;
+ msg << "Multiple read rule for map: " << label;
+ throw IoParameterError(msg.message());
+ }
+ readers.insert(make_pair(label, new _reader_bits::
+ SkipReader<Edge, ItemReader>(ir)));
+ return *this;
+ }
+
+ /// \brief Add a new directed edge map reader command for the reader.
+ ///
+ /// Add a new directed edge map reader command for the reader.
+ template <typename Map>
+ UEdgeMapReader& readEdgeMap(std::string label, Map& map) {
+ return _readDirMap<
+ typename Traits::template Reader<typename Map::Value>, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map);
+ }
+
+ template <typename Map>
+ UEdgeMapReader& readEdgeMap(std::string label, const Map& map) {
+ return _readDirMap<
+ typename Traits::template Reader<typename Map::Value>, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map);
+ }
+
+ /// \brief Add a new directed edge map reader command for the reader.
+ ///
+ /// Add a new directed edge map reader command for the reader.
+ template <typename ItemReader, typename Map>
+ UEdgeMapReader& readEdgeMap(std::string label, Map& map,
+ const ItemReader& ir = ItemReader()) {
+ return _readDirMap<ItemReader, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map, ir);
+ }
+
+ template <typename ItemReader, typename Map>
+ UEdgeMapReader& readEdgeMap(std::string label, const Map& map,
+ const ItemReader& ir = ItemReader()) {
+ return _readDirMap<ItemReader, Map,
+ typename _reader_bits::Arg<Map>::Type>(label, map, ir);
+ }
+
+ private:
+
+ template <typename ItemReader, typename Map, typename MapParameter>
+ UEdgeMapReader& _readDirMap(std::string label, MapParameter map,
+ const ItemReader& ir = ItemReader()) {
+ checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
+ checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+ readUEdgeMap("+" + label,
+ _reader_bits::forwardComposeMap(graph, map), ir);
+ readUEdgeMap("-" + label,
+ _reader_bits::backwardComposeMap(graph, map), ir);
+ return *this;
+ }
+
+ public:
+
+ /// \brief Add a new directed edge map skipper command for the reader.
+ ///
+ /// Add a new directed edge map skipper command for the reader.
+ template <typename ItemReader>
+ UEdgeMapReader& skipEdgeMap(std::string label,
+ const ItemReader& ir = ItemReader()) {
+ skipUEdgeMap("+" + label, ir);
+ skipUEdgeMap("-" + label, ir);
+ return *this;
+ }
+
+ protected:
+
+ /// \brief Gives back true when the SectionReader can process
+ /// the section with the given header line.
+ ///
+ /// It gives back true when the header line starts with \c \@mapset,
+ /// and the header line's name and the mapset's name are the same.
+ virtual bool header(const std::string& line) {
+ std::istringstream ls(line);
+ std::string command;
+ std::string id;
+ ls >> command >> id;
+ return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
+ }
+
+ /// \brief Reader function of the section.
+ ///
+ /// It reads the content of the section.
+ virtual void read(std::istream& is) {
+ std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
+ std::string line;
+
+ {
+ getline(is, line);
+ std::istringstream ls(line);
+ std::string id;
+ while (ls >> id) {
+ typename MapReaders::iterator it = readers.find(id);
+ if (it != readers.end()) {
+ it->second->touch();
+ index.push_back(it->second);
+ } else {
+ index.push_back(&skipper);
+ }
+ }
+ }
+ for (typename MapReaders::iterator it = readers.begin();
+ it != readers.end(); ++it) {
+ if (!it->second->touched()) {
+ ErrorMessage msg;
+ msg << "Map not found in file: " << it->first;
+ throw IoParameterError(msg.message());
+ }
+ }
+ while (getline(is, line)) {
+ std::istringstream ls(line);
+ UEdge uedge = labelReader->read(ls);
+ for (int i = 0; i < int(index.size()); ++i) {
+ index[i]->read(ls, uedge);
+ }
+ }
+ }
+
+ virtual void missing() {
+ if (readers.empty()) return;
+ ErrorMessage msg;
+ msg << "UEdgeMap section not found in file: @uedgemaps " << name;
+ throw IoParameterError(msg.message());
+ }
+
+ private:
+
+ const Graph& graph;
+ std::string name;
+
+ typedef std::map<std::string,
+ _reader_bits::MapReaderBase<UEdge>*> MapReaders;
+
+ MapReaders readers;
+ _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
+
+ std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader;
+
+ };
+
+ /// \ingroup section_io
/// \brief SectionReader for retrieve what is in the file.
///
/// SectionReader for retrieve what is in the file. If you want
Modified: lemon/trunk/lemon/lemon_writer.h
==============================================================================
--- lemon/trunk/lemon/lemon_writer.h (original)
+++ lemon/trunk/lemon/lemon_writer.h Tue Aug 28 16:00:42 2007
@@ -71,6 +71,22 @@
Less<typename Map::Value> less;
};
+ template <typename UGraph, typename Map>
+ struct UEdgeComposeLess {
+ UEdgeComposeLess(const UGraph& _ugraph, const Map& _map)
+ : ugraph(_ugraph), map(_map), less() {}
+
+ bool operator()(const typename UGraph::Edge& p,
+ const typename UGraph::Edge& q) const {
+ return p != q ? less(map[p], map[q]) :
+ (!ugraph.direction(p) && ugraph.direction(q));
+ }
+
+ const UGraph& ugraph;
+ const Map& map;
+ Less<typename Map::Value> less;
+ };
+
template <typename Item>
class ItemLabelWriter {
public:
@@ -123,8 +139,8 @@
ForwardComposeMap(const Graph& _graph, const Map& _map)
: graph(_graph), map(_map) {}
- Value operator[](const Key& key) {
- return map[graph.direct(key, false)];
+ Value operator[](const Key& key) const {
+ return map[graph.direct(key, true)];
}
private:
@@ -147,7 +163,7 @@
BackwardComposeMap(const Graph& _graph, const Map& _map)
: graph(_graph), map(_map) {}
- Value operator[](const Key& key) {
+ Value operator[](const Key& key) const {
return map[graph.direct(key, false)];
}
@@ -199,7 +215,7 @@
virtual ~MapWriterBase() {}
virtual void write(std::ostream& os, const Item& item) const = 0;
- virtual void sortByMap(std::vector<Item>&) const = 0;
+ virtual void sort(std::vector<Item>&) const = 0;
};
@@ -224,7 +240,59 @@
writer.write(os, value);
}
- virtual void sortByMap(std::vector<Item>& items) const {
+ virtual void sort(std::vector<Item>& items) const {
+ ComposeLess<Map> less(map);
+ std::sort(items.begin(), items.end(), less);
+ }
+
+ };
+
+ template <typename _UGraph>
+ class UEdgeMapWriterBase {
+ public:
+ typedef typename _UGraph::Edge Edge;
+ typedef typename _UGraph::UEdge UEdge;
+
+ typedef UEdge Item;
+
+ virtual ~UEdgeMapWriterBase() {}
+
+ virtual void write(std::ostream& os, const Item& item) const = 0;
+ virtual void sort(const _UGraph&, std::vector<Edge>&) const = 0;
+ virtual void sort(std::vector<UEdge>&) const = 0;
+ };
+
+
+ template <typename _UGraph, typename _Map, typename _Writer>
+ class UEdgeMapWriter : public UEdgeMapWriterBase<_UGraph> {
+ public:
+ typedef _Map Map;
+ typedef _Writer Writer;
+ typedef typename Writer::Value Value;
+
+ typedef typename _UGraph::Edge Edge;
+ typedef typename _UGraph::UEdge UEdge;
+ typedef UEdge Item;
+
+ typename _writer_bits::Ref<Map>::Type map;
+ Writer writer;
+
+ UEdgeMapWriter(const Map& _map, const Writer& _writer)
+ : map(_map), writer(_writer) {}
+
+ virtual ~UEdgeMapWriter() {}
+
+ virtual void write(std::ostream& os, const Item& item) const {
+ Value value = map[item];
+ writer.write(os, value);
+ }
+
+ virtual void sort(const _UGraph& ugraph, std::vector<Edge>& items) const {
+ UEdgeComposeLess<_UGraph, Map> less(ugraph, map);
+ std::sort(items.begin(), items.end(), less);
+ }
+
+ virtual void sort(std::vector<UEdge>& items) const {
ComposeLess<Map> less(map);
std::sort(items.begin(), items.end(), less);
}
@@ -262,7 +330,9 @@
typedef _Item Item;
virtual ~LabelWriterBase() {}
virtual void write(std::ostream&, const Item&) const = 0;
+ virtual void sort(std::vector<Item>&) const = 0;
virtual bool isLabelWriter() const = 0;
+ virtual LabelWriterBase* clone() const = 0;
};
template <typename _Item, typename _BoxedLabelWriter>
@@ -279,10 +349,17 @@
virtual void write(std::ostream& os, const Item& item) const {
labelWriter.writeLabel(os, item);
}
+ virtual void sort(std::vector<Item>& items) const {
+ labelWriter.sortByLabel(items);
+ }
virtual bool isLabelWriter() const {
return labelWriter.isLabelWriter();
}
+
+ virtual LabelWriter* clone() const {
+ return new LabelWriter(labelWriter);
+ }
};
}
@@ -425,7 +502,7 @@
/// \c writeLabel() member will be called with a node it will write it's
/// label. Otherwise if the \c _forceLabelMap constructor parameter is true
/// then the label map will be the id in the graph. In addition if the
- /// the \c _sortByLabel is true then the writer will write the edges
+ /// the \c _forceSort is true then the writer will write the edges
/// sorted by the labels.
///
/// \relates LemonWriter
@@ -444,13 +521,13 @@
/// attach it into the given LemonWriter. If the \c _forceLabelMap
/// parameter is true then the writer will write own label map when
/// the user does not give "label" named map. In addition if the
- /// the \c _sortByLabel is true then the writer will write the edges
+ /// the \c _forceSort is true then the writer will write the edges
/// sorted by the labels.
NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
const std::string& _name = std::string(),
- bool _forceLabelMap = true, bool _sortByLabel = true)
+ bool _forceLabelMap = true, bool _forceSort = true)
: Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
- sortByLabel(_sortByLabel), graph(_graph), name(_name) {}
+ forceSort(_forceSort), graph(_graph), name(_name) {}
/// \brief Destructor.
///
@@ -515,9 +592,9 @@
for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
items.push_back(it);
}
- if (sortByLabel) {
+ if (forceSort) {
if (labelMap) {
- labelMap->sortByMap(items);
+ labelMap->sort(items);
} else {
typedef IdMap<Graph, Node> Map;
Map map(graph);
@@ -550,7 +627,7 @@
/// \brief Returns true if the nodeset can write the labels of the nodes.
///
/// Returns true if the nodeset can write the labels of the nodes.
- /// It is possible only if an "label" named map was written or the
+ /// It is possible only if a "label" named map was written or the
/// \c _forceLabelMap constructor parameter was true.
bool isLabelWriter() const {
return labelMap != 0 || forceLabelMap;
@@ -558,7 +635,7 @@
/// \brief Write the label of the given node.
///
- /// It writes the label of the given node. If there was written an "label"
+ /// It writes the label of the given node. If there was written a "label"
/// named map then it will write the map value belongs to the node.
/// Otherwise if the \c forceLabel parameter was true it will write
/// its label in the graph.
@@ -570,6 +647,23 @@
}
}
+ /// \brief Sorts the given node vector by label.
+ ///
+ /// Sorts the given node vector by label. If there was written an
+ /// "label" named map then the vector will be sorted by the values
+ /// of this map. Otherwise if the \c forceLabel parameter was true
+ /// it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<Node>& nodes) const {
+ if (labelMap) {
+ labelMap->sort(nodes);
+ } else {
+ typedef IdMap<Graph, Node> Map;
+ Map map(graph);
+ _writer_bits::ComposeLess<Map> less(map);
+ std::sort(nodes.begin(), nodes.end(), less);
+ }
+ }
+
private:
typedef std::vector<std::pair<std::string, _writer_bits::
@@ -578,7 +672,7 @@
_writer_bits::MapWriterBase<Node>* labelMap;
bool forceLabelMap;
- bool sortByLabel;
+ bool forceSort;
const Graph& graph;
std::string name;
@@ -602,7 +696,7 @@
/// \c writeLabel() member will be called with an edge it will write it's
/// label. Otherwise if the \c _forceLabelMap constructor parameter is true
/// then the label map will be the id in the graph. In addition if the
- /// the \c _sortByLabel is true then the writer will write the edges
+ /// the \c _forceSort is true then the writer will write the edges
/// sorted by the labels.
///
/// The edgeset writer needs a node label writer to identify which nodes
@@ -627,15 +721,15 @@
/// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
/// parameter is true then the writer will write own label map if
/// the user does not give "label" named map. In addition if the
- /// the \c _sortByLabel is true then the writer will write the
+ /// the \c _forceSort is true then the writer will write the
/// edges sorted by the labels.
template <typename NodeLabelWriter>
EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
const NodeLabelWriter& _nodeLabelWriter,
const std::string& _name = std::string(),
- bool _forceLabelMap = true, bool _sortByLabel = true)
+ bool _forceLabelMap = true, bool _forceSort = true)
: Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
- sortByLabel(_sortByLabel), graph(_graph), name(_name) {
+ forceSort(_forceSort), graph(_graph), name(_name) {
checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
nodeLabelWriter.reset(new _writer_bits::
LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
@@ -707,9 +801,9 @@
for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
items.push_back(it);
}
- if (sortByLabel) {
+ if (forceSort) {
if (labelMap) {
- labelMap->sortByMap(items);
+ labelMap->sort(items);
} else {
typedef IdMap<Graph, Edge> Map;
Map map(graph);
@@ -747,7 +841,7 @@
/// \brief Returns true if the edgeset can write the labels of the edges.
///
/// Returns true if the edgeset can write the labels of the edges.
- /// It is possible only if an "label" named map was written or the
+ /// It is possible only if a "label" named map was written or the
/// \c _forceLabelMap constructor parameter was true.
bool isLabelWriter() const {
return forceLabelMap || labelMap != 0;
@@ -755,7 +849,7 @@
/// \brief Write the label of the given edge.
///
- /// It writes the label of the given edge. If there was written an "label"
+ /// It writes the label of the given edge. If there was written a "label"
/// named map then it will write the map value belongs to the edge.
/// Otherwise if the \c forceLabel parameter was true it will write
/// its label in the graph.
@@ -767,6 +861,23 @@
}
}
+ /// \brief Sorts the given edge vector by label.
+ ///
+ /// Sorts the given edge vector by label. If there was written an
+ /// "label" named map then the vector will be sorted by the values
+ /// of this map. Otherwise if the \c forceLabel parameter was true
+ /// it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<Edge>& edges) const {
+ if (labelMap) {
+ labelMap->sort(edges);
+ } else {
+ typedef IdMap<Graph, Edge> Map;
+ Map map(graph);
+ _writer_bits::ComposeLess<Map> less(map);
+ std::sort(edges.begin(), edges.end(), less);
+ }
+ }
+
private:
typedef std::vector<std::pair<std::string, _writer_bits::
@@ -775,7 +886,7 @@
_writer_bits::MapWriterBase<Edge>* labelMap;
bool forceLabelMap;
- bool sortByLabel;
+ bool forceSort;
const Graph& graph;
std::string name;
@@ -807,7 +918,7 @@
/// an undirected edge it will write it's label. Otherwise if the \c
/// _forceLabelMap constructor parameter is true then the label map
/// will be the id in the graph. In addition if the the \c
- /// _sortByLabel is true then the writer will write the edges sorted
+ /// _forceSort is true then the writer will write the edges sorted
/// by the labels.
///
/// The undirected edgeset writer needs a node label writer to identify
@@ -833,18 +944,18 @@
/// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
/// parameter is true then the writer will write own label map if
/// the user does not give "label" named map. In addition if the
- /// the \c _sortByLabel is true then the writer will write the
+ /// the \c _forceSort is true then the writer will write the
/// edges sorted by the labels.
template <typename NodeLabelWriter>
UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
const NodeLabelWriter& _nodeLabelWriter,
const std::string& _name = std::string(),
- bool _forceLabelMap = true, bool _sortByLabel = true)
+ bool _forceLabelMap = true, bool _forceSort = true)
: Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
- sortByLabel(_sortByLabel), graph(_graph), name(_name) {
+ forceSort(_forceSort), graph(_graph), name(_name) {
checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
nodeLabelWriter.reset(new _writer_bits::
- LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
+ LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
}
/// \brief Destructor.
@@ -882,7 +993,7 @@
checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
writers.push_back(
make_pair(label, new _writer_bits::
- MapWriter<UEdge, Map, ItemWriter>(map, iw)));
+ UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
return *this;
}
@@ -903,9 +1014,9 @@
const ItemWriter& iw = ItemWriter()) {
checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
- writeUEdgeMap("+" + name,
+ writeUEdgeMap("+" + label,
_writer_bits::forwardComposeMap(graph, map), iw);
- writeUEdgeMap("-" + name,
+ writeUEdgeMap("-" + label,
_writer_bits::backwardComposeMap(graph, map), iw);
return *this;
}
@@ -937,9 +1048,9 @@
for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
items.push_back(it);
}
- if (sortByLabel) {
+ if (forceSort) {
if (labelMap) {
- labelMap->sortByMap(items);
+ labelMap->sort(items);
} else {
typedef IdMap<Graph, UEdge> Map;
Map map(graph);
@@ -978,7 +1089,7 @@
/// the edges.
///
/// Returns true if the undirected edgeset can write the labels of the
- /// undirected edges. It is possible only if an "label" named map was
+ /// undirected edges. It is possible only if a "label" named map was
/// written or the \c _forceLabelMap constructor parameter was true.
bool isLabelWriter() const {
return forceLabelMap || labelMap != 0;
@@ -987,7 +1098,7 @@
/// \brief Write the label of the given undirected edge.
///
/// It writes the label of the given undirected edge. If there was written
- /// an "label" named map then it will write the map value belongs to the
+ /// a "label" named map then it will write the map value belongs to the
/// undirected edge. Otherwise if the \c forceLabel parameter was true it
/// will write its id in the graph.
void writeLabel(std::ostream& os, const UEdge& item) const {
@@ -1001,32 +1112,66 @@
/// \brief Write the label of the given edge.
///
/// It writes the label of the given edge. If there was written
- /// an "label" named map then it will write the map value belongs to the
+ /// a "label" named map then it will write the map value belongs to the
/// edge. Otherwise if the \c forceLabel parameter was true it
/// will write its id in the graph. If the edge is forward map
/// then its prefix character is \c '+' elsewhere \c '-'.
void writeLabel(std::ostream& os, const Edge& item) const {
if (graph.direction(item)) {
- os << "+ ";
+ os << "+";
} else {
- os << "- ";
+ os << "-";
}
if (forceLabelMap) {
- os << graph.id(item);
+ os << graph.id(static_cast<const UEdge&>(item));
} else {
labelMap->write(os, item);
}
}
+ /// \brief Sorts the given undirected edge vector by label.
+ ///
+ /// Sorts the given undirected edge vector by label. If there was
+ /// written a "label" named map then the vector will be sorted by
+ /// the values of this map. Otherwise if the \c forceLabel
+ /// parameter was true it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<UEdge>& uedges) const {
+ if (labelMap) {
+ labelMap->sort(uedges);
+ } else {
+ typedef IdMap<Graph, UEdge> Map;
+ Map map(graph);
+ _writer_bits::ComposeLess<Map> less(map);
+ std::sort(uedges.begin(), uedges.end(), less);
+ }
+ }
+
+ /// \brief Sorts the given edge vector by label.
+ ///
+ /// Sorts the given edge vector by label. If there was written a
+ /// "label" named map then the vector will be sorted by the values
+ /// of this map. Otherwise if the \c forceLabel parameter was true
+ /// it will be sorted by its id in the graph.
+ void sortByLabel(std::vector<Edge>& edges) const {
+ if (labelMap) {
+ labelMap->sort(graph, edges);
+ } else {
+ typedef IdMap<Graph, Edge> Map;
+ Map map(graph);
+ _writer_bits::ComposeLess<Map> less(map);
+ std::sort(edges.begin(), edges.end(), less);
+ }
+ }
+
private:
typedef std::vector<std::pair<std::string, _writer_bits::
- MapWriterBase<UEdge>*> > MapWriters;
+ UEdgeMapWriterBase<Graph>*> > MapWriters;
MapWriters writers;
- _writer_bits::MapWriterBase<UEdge>* labelMap;
+ _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
bool forceLabelMap;
- bool sortByLabel;
+ bool forceSort;
const Graph& graph;
std::string name;
@@ -1206,6 +1351,7 @@
std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
};
+
/// \ingroup section_io
/// \brief SectionWriter for writing named undirected edges.
///
@@ -1321,6 +1467,429 @@
};
/// \ingroup section_io
+ /// \brief SectionWriter for writing extra node maps.
+ ///
+ /// The lemon format can store maps in the nodeset. This class let
+ /// you make distinict section to store maps. The main purpose of
+ /// this class is a logical separation of some maps. The other
+ /// useful application could be to store paths in node maps.
+ ///
+ /// The first line of the section contains the names of the maps
+ /// separated with white spaces. Each next line describes an item
+ /// in the itemset, and contains in the first column the label of
+ /// the item and then the mapped values for each map.
+ ///
+ /// \relates LemonWriter
+ template <typename _Graph, typename _Traits = DefaultWriterTraits>
+ class NodeMapWriter : public LemonWriter::SectionWriter {
+ typedef LemonWriter::SectionWriter Parent;
+ public:
+
+ typedef _Graph Graph;
+ typedef _Traits Traits;
+ typedef typename Graph::Node Node;
+
+ /// \brief Constructor.
+ ///
+ /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
+ /// attach it into the given LemonWriter. If the the
+ /// \c _forceSort is true then the writer will write the edges
+ /// sorted by the labels.
+ template <typename _LabelWriter>
+ NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
+ const _LabelWriter& _labelWriter,
+ const std::string& _name = std::string(),
+ bool _forceSort = true)
+ : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
+ checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
+ labelWriter.reset(new _writer_bits::LabelWriter<Node,
+ _LabelWriter>(_labelWriter));
+ }
+
+ /// \brief Destructor.
+ ///
+ /// Destructor for NodeMapWriter.
+ virtual ~NodeMapWriter() {
+ typename MapWriters::iterator it;
+ for (it = writers.begin(); it != writers.end(); ++it) {
+ delete it->second;
+ }
+ }
+
+ private:
+ NodeMapWriter(const NodeMapWriter&);
+ void operator=(const NodeMapWriter&);
+
+ public:
+
+ /// \brief Add a new node map writer command for the writer.
+ ///
+ /// Add a new node map writer command for the writer.
+ template <typename Map>
+ NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
+ return writeNodeMap<typename Traits::
+ template Writer<typename Map::Value>, Map>(label, map);
+ }
+
+ /// \brief Add a new node map writer command for the writer.
+ ///
+ /// Add a new node map writer command for the writer.
+ template <typename ItemWriter, typename Map>
+ NodeMapWriter& writeNodeMap(std::string label, const Map& map,
+ const ItemWriter& iw = ItemWriter()) {
+ checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+ checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
+ writers.push_back(
+ make_pair(label, new _writer_bits::
+ MapWriter<Node, Map, ItemWriter>(map, iw)));
+ return *this;
+ }
+
+ protected:
+
+ /// \brief The header of the section.
+ ///
+ /// It gives back the header of the section.
+ virtual std::string header() {
+ return "@nodemaps " + name;
+ }
+
+ /// \brief Writer function of the section.
+ ///
+ /// Write the content of the section.
+ virtual void write(std::ostream& os) {
+ std::vector<Node> nodes;
+ for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
+ nodes.push_back(it);
+ }
+ if (forceSort) {
+ labelWriter->sort(nodes);
+ }
+ os << '\t';
+ for (int i = 0; i < int(writers.size()); ++i) {
+ os << writers[i].first << '\t';
+ }
+ os << std::endl;
+ for (typename std::vector<Node>::iterator it = nodes.begin();
+ it != nodes.end(); ++it) {
+
+ labelWriter->write(os, *it); os << '\t';
+ for (int i = 0; i < int(writers.size()); ++i) {
+ writers[i].second->write(os, *it);
+ os << '\t';
+ }
+ os << std::endl;
+ }
+ }
+
+
+ private:
+
+ typedef std::vector<std::pair<std::string, _writer_bits::
+ MapWriterBase<Node>*> > MapWriters;
+ MapWriters writers;
+
+ _writer_bits::MapWriterBase<Node>* labelMap;
+
+ const Graph& graph;
+ std::string name;
+ bool forceSort;
+
+ std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
+ };
+
+ /// \ingroup section_io
+ /// \brief SectionWriter for writing extra edge maps.
+ ///
+ /// The lemon format can store maps in the edgeset. This class let
+ /// you make distinict section to store maps. The main purpose of
+ /// this class is a logical separation of some maps. The other
+ /// useful application could be to store paths in edge maps.
+ ///
+ /// The first line of the section contains the names of the maps
+ /// separated with white spaces. Each next line describes an item
+ /// in the itemset, and contains in the first column the label of
+ /// the item and then the mapped values for each map.
+ ///
+ /// \relates LemonWriter
+ template <typename _Graph, typename _Traits = DefaultWriterTraits>
+ class EdgeMapWriter : public LemonWriter::SectionWriter {
+ typedef LemonWriter::SectionWriter Parent;
+ public:
+
+ typedef _Graph Graph;
+ typedef _Traits Traits;
+ typedef typename Graph::Edge Edge;
+
+ /// \brief Constructor.
+ ///
+ /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
+ /// attach it into the given LemonWriter. If the the
+ /// \c _forceSort is true then the writer will write the edges
+ /// sorted by the labels.
+ template <typename _LabelWriter>
+ EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
+ const _LabelWriter& _labelWriter,
+ const std::string& _name = std::string(),
+ bool _forceSort = true)
+ : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
+ checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
+ labelWriter.reset(new _writer_bits::LabelWriter<Edge,
+ _LabelWriter>(_labelWriter));
+ }
+
+ /// \brief Destructor.
+ ///
+ /// Destructor for EdgeMapWriter.
+ virtual ~EdgeMapWriter() {
+ typename MapWriters::iterator it;
+ for (it = writers.begin(); it != writers.end(); ++it) {
+ delete it->second;
+ }
+ }
+
+ private:
+ EdgeMapWriter(const EdgeMapWriter&);
+ void operator=(const EdgeMapWriter&);
+
+ public:
+
+ /// \brief Add a new edge map writer command for the writer.
+ ///
+ /// Add a new edge map writer command for the writer.
+ template <typename Map>
+ EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
+ return writeEdgeMap<typename Traits::
+ template Writer<typename Map::Value>, Map>(label, map);
+ }
+
+ /// \brief Add a new edge map writer command for the writer.
+ ///
+ /// Add a new edge map writer command for the writer.
+ template <typename ItemWriter, typename Map>
+ EdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
+ const ItemWriter& iw = ItemWriter()) {
+ checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+ checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
+ writers.push_back(
+ make_pair(label, new _writer_bits::
+ MapWriter<Edge, Map, ItemWriter>(map, iw)));
+ return *this;
+ }
+
+ protected:
+
+ /// \brief The header of the section.
+ ///
+ /// It gives back the header of the section.
+ virtual std::string header() {
+ return "@edgemaps " + name;
+ }
+
+ /// \brief Writer function of the section.
+ ///
+ /// Write the content of the section.
+ virtual void write(std::ostream& os) {
+ std::vector<Edge> edges;
+ for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
+ edges.push_back(it);
+ }
+ if (forceSort) {
+ labelWriter->sort(edges);
+ }
+ os << '\t';
+ for (int i = 0; i < int(writers.size()); ++i) {
+ os << writers[i].first << '\t';
+ }
+ os << std::endl;
+ for (typename std::vector<Edge>::iterator it = edges.begin();
+ it != edges.end(); ++it) {
+
+ labelWriter->write(os, *it); os << '\t';
+ for (int i = 0; i < int(writers.size()); ++i) {
+ writers[i].second->write(os, *it);
+ os << '\t';
+ }
+ os << std::endl;
+ }
+ }
+
+
+ private:
+
+ typedef std::vector<std::pair<std::string, _writer_bits::
+ MapWriterBase<Edge>*> > MapWriters;
+ MapWriters writers;
+
+ _writer_bits::MapWriterBase<Edge>* labelMap;
+
+ const Graph& graph;
+ std::string name;
+ bool forceSort;
+
+ std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
+ };
+
+ /// \ingroup section_io
+ /// \brief SectionWriter for writing extra undirected edge maps.
+ ///
+ /// The lemon format can store maps in the uedgeset. This class let
+ /// you make distinict section to store maps. The main purpose of
+ /// this class is a logical separation of some maps. The other
+ /// useful application could be to store paths in undirected edge
+ /// maps.
+ ///
+ /// The first line of the section contains the names of the maps
+ /// separated with white spaces. Each next line describes an item
+ /// in the itemset, and contains in the first column the label of
+ /// the item and then the mapped values for each map.
+ ///
+ /// \relates LemonWriter
+ template <typename _Graph, typename _Traits = DefaultWriterTraits>
+ class UEdgeMapWriter : public LemonWriter::SectionWriter {
+ typedef LemonWriter::SectionWriter Parent;
+ public:
+
+ typedef _Graph Graph;
+ typedef _Traits Traits;
+ typedef typename Graph::UEdge UEdge;
+ typedef typename Graph::Edge Edge;
+
+ /// \brief Constructor.
+ ///
+ /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
+ /// attach it into the given LemonWriter. If the the
+ /// \c _forceSort is true then the writer will write the uedges
+ /// sorted by the labels.
+ template <typename _LabelWriter>
+ UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
+ const _LabelWriter& _labelWriter,
+ const std::string& _name = std::string(),
+ bool _forceSort = true)
+ : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
+ checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
+ labelWriter.reset(new _writer_bits::LabelWriter<UEdge,
+ _LabelWriter>(_labelWriter));
+ }
+
+ /// \brief Destructor.
+ ///
+ /// Destructor for UEdgeMapWriter.
+ virtual ~UEdgeMapWriter() {
+ typename MapWriters::iterator it;
+ for (it = writers.begin(); it != writers.end(); ++it) {
+ delete it->second;
+ }
+ }
+
+ private:
+ UEdgeMapWriter(const UEdgeMapWriter&);
+ void operator=(const UEdgeMapWriter&);
+
+ public:
+
+ /// \brief Add a new undirected edge map writer command for the writer.
+ ///
+ /// Add a new undirected edge map writer command for the writer.
+ template <typename Map>
+ UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
+ return writeUEdgeMap<typename Traits::
+ template Writer<typename Map::Value>, Map>(label, map);
+ }
+
+ /// \brief Add a new undirected edge map writer command for the writer.
+ ///
+ /// Add a new undirected edge map writer command for the writer.
+ template <typename ItemWriter, typename Map>
+ UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map,
+ const ItemWriter& iw = ItemWriter()) {
+ checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
+ checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
+ writers.push_back(
+ make_pair(label, new _writer_bits::
+ MapWriter<UEdge, Map, ItemWriter>(map, iw)));
+ 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 <typename Map>
+ UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
+ return writeEdgeMap<typename Traits::
+ template Writer<typename Map::Value>, Map>(label, map);
+ }
+
+ /// \brief Add a new directed map writer command for the writer.
+ ///
+ /// Add a new directed map writer command for the writer.
+ template <typename ItemWriter, typename Map>
+ UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
+ const ItemWriter& iw = ItemWriter()) {
+ checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+ checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
+ writeUEdgeMap("+" + label,
+ _writer_bits::forwardComposeMap(graph, map), iw);
+ writeUEdgeMap("-" + label,
+ _writer_bits::backwardComposeMap(graph, map), iw);
+ return *this;
+ }
+
+ protected:
+
+ /// \brief The header of the section.
+ ///
+ /// It gives back the header of the section.
+ virtual std::string header() {
+ return "@uedgemaps " + name;
+ }
+
+ /// \brief Writer function of the section.
+ ///
+ /// Write the content of the section.
+ virtual void write(std::ostream& os) {
+ std::vector<UEdge> uedges;
+ for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
+ uedges.push_back(it);
+ }
+ if (forceSort) {
+ labelWriter->sort(uedges);
+ }
+ os << '\t';
+ for (int i = 0; i < int(writers.size()); ++i) {
+ os << writers[i].first << '\t';
+ }
+ os << std::endl;
+ for (typename std::vector<UEdge>::iterator it = uedges.begin();
+ it != uedges.end(); ++it) {
+
+ labelWriter->write(os, *it); os << '\t';
+ for (int i = 0; i < int(writers.size()); ++i) {
+ writers[i].second->write(os, *it);
+ os << '\t';
+ }
+ os << std::endl;
+ }
+ }
+
+
+ private:
+
+ typedef std::vector<std::pair<std::string, _writer_bits::
+ MapWriterBase<UEdge>*> > MapWriters;
+ MapWriters writers;
+
+ _writer_bits::MapWriterBase<UEdge>* labelMap;
+
+ const Graph& graph;
+ std::string name;
+ bool forceSort;
+
+ std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
+ };
+
+
+ /// \ingroup section_io
/// \brief SectionWriter for attributes.
///
/// The lemon format can store multiple attribute set. Each set has
Modified: lemon/trunk/lemon/path_utils.h
==============================================================================
--- lemon/trunk/lemon/path_utils.h (original)
+++ lemon/trunk/lemon/path_utils.h Tue Aug 28 16:00:42 2007
@@ -25,6 +25,8 @@
#define LEMON_PATH_UTILS_H
#include <lemon/concepts/path.h>
+#include <lemon/lemon_reader.h>
+#include <lemon/lemon_writer.h>
namespace lemon {
@@ -132,6 +134,261 @@
typename Graph::Node pathTarget(const Graph& graph, const Path& path) {
return graph.target(path.back());
}
+
+ /// \brief Class which helps to iterate the nodes of a path
+ ///
+ /// In a sense, the path can be treated as a list of edges. The
+ /// lemon path type stores just this list. As a consequence it
+ /// cannot enumerate the nodes in the path and the zero length paths
+ /// cannot store the node.
+ ///
+ /// This class implements the node iterator of a path structure. To
+ /// provide this feature, the underlying graph should be given to
+ /// the constructor of the iterator.
+ template <typename Path>
+ class PathNodeIt {
+ private:
+ const typename Path::Graph *_graph;
+ typename Path::EdgeIt _it;
+ typename Path::Graph::Node _nd;
+
+ public:
+
+ typedef typename Path::Graph Graph;
+ typedef typename Graph::Node Node;
+
+ /// Default constructor
+ PathNodeIt() {}
+ /// Invalid constructor
+ PathNodeIt(Invalid)
+ : _graph(0), _it(INVALID), _nd(INVALID) {}
+ /// Constructor
+ PathNodeIt(const Graph& graph, const Path& path)
+ : _graph(&graph), _it(path) {
+ _nd = (_it != INVALID ? _graph->source(_it) : INVALID);
+ }
+ /// Constructor
+ PathNodeIt(const Graph& graph, const Path& path, const Node& src)
+ : _graph(&graph), _it(path), _nd(src) {}
+
+ ///Conversion to Graph::Node
+ operator Node() const {
+ return _nd;
+ }
+
+ /// Next node
+ PathNodeIt& operator++() {
+ if (_it == INVALID) _nd = INVALID;
+ else {
+ _nd = _graph->target(_it);
+ ++_it;
+ }
+ return *this;
+ }
+
+ /// Comparison operator
+ bool operator==(const PathNodeIt& n) const {
+ return _it == n._it && _nd == n._nd;
+ }
+ /// Comparison operator
+ bool operator!=(const PathNodeIt& n) const {
+ return _it != n._it || _nd != n._nd;
+ }
+ /// Comparison operator
+ bool operator<(const PathNodeIt& n) const {
+ return (_it < n._it && _nd != INVALID);
+ }
+
+ };
+
+ /// \brief Item writer for paths
+ ///
+ /// This class can write paths into files. You can store paths in
+ /// distinict mapset or in attributes section.
+ ///
+ ///\code
+ /// GraphWriter<SmartGraph> gw(std::cout, g);
+ /// NodeMapWriter<SmartGraph> nmw(gw, g, gw);
+ ///
+ /// SmartGraph::NodeMap<Path<SmartGraph> > pnm(g);
+ /// for (SmartGraph::NodeIt n(g); n != INVALID; ++n) {
+ /// pnm[n] = bfs.path(n);
+ /// }
+ /// nmw.writeNodeMap("pnm", pnm, PathWriter<Path<SmartGraph> >(gw));
+ ///
+ /// gw.run();
+ ///\endcode
+ ///
+ /// \warning Do not use this class to write node or edge map values
+ /// into usual nodesets or edgesets. You will not be able to read
+ /// back your paths. Rather use NodeMapWriter, EdgeSetWriter or
+ /// UEdgeSetWriter to dump paths from maps to lemon file.
+ template <typename Path>
+ class PathWriter {
+ private:
+
+ typedef typename Path::Edge Edge;
+ std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
+
+ public:
+
+ typedef Path Value;
+
+ PathWriter(const PathWriter& pw) {
+ edgeLabelWriter.reset(pw.edgeLabelWriter->clone());
+ }
+
+ /// \brief Constructor
+ ///
+ /// The paramter shold be an edge label writer which could
+ /// be a GraphWriter or an EdgeSetWriter.
+ template <typename EdgeLabelWriter>
+ explicit PathWriter(const EdgeLabelWriter& _edgeLabelWriter) {
+ edgeLabelWriter.reset(new _writer_bits::
+ LabelWriter<Edge, EdgeLabelWriter>(_edgeLabelWriter));
+ }
+
+ /// \brief Writer function
+ ///
+ /// Writes the path to the current stream. The representation
+ /// is the edge labels beetween parentheses.
+ void write(std::ostream& os, const Value& value) const {
+ if (!edgeLabelWriter->isLabelWriter()) {
+ throw DataFormatError("Cannot find edgeset or label map");
+ }
+ os << '(' << ' ';
+ for (typename Path::EdgeIt e(value); e != INVALID; ++e) {
+ edgeLabelWriter->write(os, e);
+ os << ' ';
+ }
+ os << ')';
+ }
+
+ };
+
+ namespace _path_bits {
+
+ template <typename _Graph>
+ class PathProxy {
+ public:
+ typedef False RevPathTag;
+
+ typedef _Graph Graph;
+ typedef typename Graph::Edge Edge;
+
+ PathProxy(const std::vector<Edge>& edges)
+ : _edges(edges) {}
+
+ int length() const {
+ return _edges.size();
+ }
+
+ bool empty() const {
+ return _edges.size() == 0;
+ }
+
+ class EdgeIt {
+ public:
+ EdgeIt() {}
+ EdgeIt(const PathProxy& path)
+ : _path(&path), _index(0) {}
+
+ operator const Edge() const {
+ return _path->_edges[_index];
+ }
+
+ EdgeIt& operator++() {
+ ++_index;
+ return *this;
+ }
+
+ bool operator==(Invalid) const {
+ return int(_path->_edges.size()) == _index;
+ }
+ bool operator!=(Invalid) const {
+ return int(_path->_edges.size()) != _index;
+ }
+
+ private:
+ const PathProxy* _path;
+ int _index;
+ };
+
+ private:
+ const std::vector<Edge>& _edges;
+
+ };
+
+ }
+
+ /// \brief Item reader for paths
+ ///
+ /// This class can read paths from files. You can store paths in
+ /// distinict mapset or in attributes section.
+ ///
+ ///\code
+ /// GraphReader<SmartGraph> gr(std::cout, g);
+ /// NodeMapReader<SmartGraph> nmr(gr, g, gr);
+ ///
+ /// SmartGraph::NodeMap<Path<SmartGraph> > pnm(g);
+ /// nmr.readNodeMap("pnm", pnm, PathReader<Path<SmartGraph> >(gr));
+ ///
+ /// gr.run();
+ ///\endcode
+ ///
+ /// \warning Do not use this class to read node or edge map values
+ /// from nodesets or edgesets. The edges are not surely constructed
+ /// when the edge list should be read. Rather use NodeMapReader,
+ /// EdgeSetReader or UEdgeSetReader to read distinict map sets from file.
+ template <typename Path>
+ class PathReader {
+ private:
+
+ typedef typename Path::Edge Edge;
+ std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
+
+ public:
+
+ typedef Path Value;
+
+ PathReader(const PathReader& pw) {
+ edgeLabelReader.reset(pw.edgeLabelReader->clone());
+ }
+
+ /// \brief Constructor
+ ///
+ /// The paramter shold be an edge label reader which could
+ /// be a GraphReader or an EdgeSetReader.
+ template <typename EdgeLabelReader>
+ explicit PathReader(const EdgeLabelReader& _edgeLabelReader) {
+ edgeLabelReader.reset(new _reader_bits::
+ LabelReader<Edge, EdgeLabelReader>(_edgeLabelReader));
+ }
+
+
+ /// \brief Reader function
+ ///
+ /// Reads the path from the current stream. The representation
+ /// is the edge labels beetween parentheses.
+ void read(std::istream& is, Value& value) const {
+ if (!edgeLabelReader->isLabelReader()) {
+ throw DataFormatError("Cannot find edgeset or label map");
+ }
+ char c;
+ if (!(is >> c) || c != '(')
+ throw DataFormatError("PathReader format error");
+ std::vector<typename Path::Edge> v;
+ while (is >> c && c != ')') {
+ is.putback(c);
+ Edge edge = edgeLabelReader->read(is);
+ v.push_back(edge);
+ }
+ if (!is) throw DataFormatError("PathReader format error");
+ copyPath(value, _path_bits::PathProxy<typename Path::Edge>(v));
+ }
+
+ };
+
}
#endif
More information about the Lemon-commits
mailing list