Some bug fix.
Added: Concept check for maps and IdReader/Writer classes
Some runtime check
1.1 --- a/lemon/graph_reader.h Mon Jun 13 16:10:36 2005 +0000
1.2 +++ b/lemon/graph_reader.h Mon Jun 13 17:13:56 2005 +0000
1.3 @@ -261,6 +261,7 @@
1.4 /// Add a new labeled edge reader for the reader.
1.5 GraphReader& readEdge(std::string name, Edge& edge) {
1.6 edge_reader.readEdge(name, edge);
1.7 + return *this;
1.8 }
1.9
1.10 /// \brief Add a new attribute reader command.
2.1 --- a/lemon/lemon_reader.h Mon Jun 13 16:10:36 2005 +0000
2.2 +++ b/lemon/lemon_reader.h Mon Jun 13 17:13:56 2005 +0000
2.3 @@ -36,10 +36,33 @@
2.4 #include <lemon/utility.h>
2.5 #include <lemon/bits/item_reader.h>
2.6
2.7 +#include <lemon/concept_check.h>
2.8 +#include <lemon/concept/maps.h>
2.9
2.10 namespace lemon {
2.11
2.12 namespace _reader_bits {
2.13 +
2.14 + template <typename Item>
2.15 + class ItemIdReader {
2.16 + public:
2.17 +
2.18 + bool isIdReader() { return true; }
2.19 +
2.20 + Item readId(std::istream&, Item) { return Item();}
2.21 +
2.22 + template <class _ItemIdReader>
2.23 + struct Constraints {
2.24 + void constraints() {
2.25 + bool b = reader.isIdReader();
2.26 + ignore_unused_variable_warning(b);
2.27 + Item item = reader.readId(is, Item());
2.28 + }
2.29 + _ItemIdReader& reader;
2.30 + std::istream& is;
2.31 + };
2.32 +
2.33 + };
2.34
2.35 template <typename T>
2.36 bool operator<(T, T) {
2.37 @@ -531,6 +554,7 @@
2.38 public:
2.39 typedef _Item Item;
2.40 virtual Item read(std::istream& is) const = 0;
2.41 + virtual bool isIdReader() const = 0;
2.42 };
2.43
2.44 template <typename _Item, typename _BoxedIdReader>
2.45 @@ -547,6 +571,10 @@
2.46 virtual Item read(std::istream& is) const {
2.47 return boxedIdReader.readId(is, Item());
2.48 }
2.49 +
2.50 + virtual bool isIdReader() const {
2.51 + return boxedIdReader.isIdReader();
2.52 + }
2.53 };
2.54
2.55 class ValueReaderBase {
2.56 @@ -817,9 +845,10 @@
2.57 const NodeIdReader& _nodeIdReader,
2.58 const std::string& _id = std::string(),
2.59 const DefaultSkipper& _skipper = DefaultSkipper())
2.60 - : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
2.61 - nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {}
2.62 -
2.63 + : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
2.64 + checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
2.65 + nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
2.66 + }
2.67 /// \brief Destructor.
2.68 ///
2.69 /// Destructor for EdgeSetReader.
2.70 @@ -921,6 +950,9 @@
2.71 ///
2.72 /// It reads the content of the section.
2.73 virtual void read(std::istream& is) {
2.74 + if (!nodeIdReader->isIdReader()) {
2.75 + throw DataFormatError("Cannot find nodeset or ID map");
2.76 + }
2.77 std::vector<ReaderBase<Edge>* > index;
2.78 std::string line;
2.79
2.80 @@ -1033,9 +1065,10 @@
2.81 const NodeIdReader& _nodeIdReader,
2.82 const std::string& _id = std::string(),
2.83 const DefaultSkipper& _skipper = DefaultSkipper())
2.84 - : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
2.85 - nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {}
2.86 -
2.87 + : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
2.88 + checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
2.89 + nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
2.90 + }
2.91 /// \brief Destructor.
2.92 ///
2.93 /// Destructor for UndirEdgeSetReader.
2.94 @@ -1197,6 +1230,9 @@
2.95 ///
2.96 /// It reads the content of the section.
2.97 virtual void read(std::istream& is) {
2.98 + if (!nodeIdReader->isIdReader()) {
2.99 + throw DataFormatError("Cannot find nodeset or ID map");
2.100 + }
2.101 std::vector<ReaderBase<UndirEdge>* > index;
2.102 std::string line;
2.103
2.104 @@ -1302,8 +1338,10 @@
2.105 template <typename _IdReader>
2.106 NodeReader(LemonReader& _reader, const _IdReader& _idReader,
2.107 const std::string& _id = std::string())
2.108 - : Parent(_reader), id(_id),
2.109 - idReader(new IdReader<typename Graph::Node, _IdReader>(_idReader)) {}
2.110 + : Parent(_reader), id(_id) {
2.111 + checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>();
2.112 + idReader.reset(new IdReader<Node, _IdReader>(_idReader));
2.113 + }
2.114
2.115 /// \brief Destructor.
2.116 ///
2.117 @@ -1347,6 +1385,9 @@
2.118 ///
2.119 /// It reads the content of the section.
2.120 virtual void read(std::istream& is) {
2.121 + if (!idReader->isIdReader()) {
2.122 + throw DataFormatError("Cannot find nodeset or ID map");
2.123 + }
2.124 std::string line;
2.125 while (getline(is, line)) {
2.126 std::istringstream ls(line);
2.127 @@ -1394,8 +1435,10 @@
2.128 template <typename _IdReader>
2.129 EdgeReader(LemonReader& _reader, const _IdReader& _idReader,
2.130 const std::string& _id = std::string())
2.131 - : Parent(_reader), id(_id),
2.132 - idReader(new IdReader<typename Graph::Edge, _IdReader>(_idReader)) {}
2.133 + : Parent(_reader), id(_id) {
2.134 + checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
2.135 + idReader.reset(new IdReader<Edge, _IdReader>(_idReader));
2.136 + }
2.137
2.138 /// \brief Destructor.
2.139 ///
2.140 @@ -1438,6 +1481,9 @@
2.141 ///
2.142 /// It reads the content of the section.
2.143 virtual void read(std::istream& is) {
2.144 + if (!idReader->isIdReader()) {
2.145 + throw DataFormatError("Cannot find edgeset or ID map");
2.146 + }
2.147 std::string line;
2.148 while (getline(is, line)) {
2.149 std::istringstream ls(line);
2.150 @@ -1487,10 +1533,12 @@
2.151 template <typename _IdReader>
2.152 UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader,
2.153 const std::string& _id = std::string())
2.154 - : Parent(_reader), id(_id),
2.155 - undirEdgeIdReader(new IdReader<UndirEdge, _IdReader>(_idReader)),
2.156 - edgeIdReader(new IdReader<Edge, _IdReader>(_idReader))
2.157 - {}
2.158 + : Parent(_reader), id(_id) {
2.159 + checkConcept<_reader_bits::ItemIdReader<UndirEdge>, _IdReader>();
2.160 + checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
2.161 + undirEdgeIdReader.reset(new IdReader<UndirEdge, _IdReader>(_idReader));
2.162 + egdeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
2.163 + }
2.164
2.165 /// \brief Destructor.
2.166 ///
2.167 @@ -1545,6 +1593,12 @@
2.168 ///
2.169 /// It reads the content of the section.
2.170 virtual void read(std::istream& is) {
2.171 + if (!edgeIdReader->isIdReader()) {
2.172 + throw DataFormatError("Cannot find undirected edgeset or ID map");
2.173 + }
2.174 + if (!undirEdgeIdReader->isIdReader()) {
2.175 + throw DataFormatError("Cannot find undirected edgeset or ID map");
2.176 + }
2.177 std::string line;
2.178 while (getline(is, line)) {
2.179 std::istringstream ls(line);
3.1 --- a/lemon/lemon_writer.h Mon Jun 13 16:10:36 2005 +0000
3.2 +++ b/lemon/lemon_writer.h Mon Jun 13 17:13:56 2005 +0000
3.3 @@ -36,9 +36,38 @@
3.4 #include <lemon/utility.h>
3.5 #include <lemon/maps.h>
3.6
3.7 +#include <lemon/concept_check.h>
3.8 +#include <lemon/concept/maps.h>
3.9 +
3.10
3.11 namespace lemon {
3.12
3.13 + namespace _writer_bits {
3.14 +
3.15 + template <typename Item>
3.16 + class ItemIdWriter {
3.17 + public:
3.18 +
3.19 + bool isIdWriter() { return true; }
3.20 +
3.21 + void writeId(std::ostream&, const Item&) {}
3.22 +
3.23 + template <class _ItemIdWriter>
3.24 + struct Constraints {
3.25 + void constraints() {
3.26 + const Item item;
3.27 + bool b = writer.isIdWriter();
3.28 + ignore_unused_variable_warning(b);
3.29 + writer.writeId(os, item);
3.30 + }
3.31 + _ItemIdWriter& writer;
3.32 + std::ostream& os;
3.33 + };
3.34 +
3.35 + };
3.36 +
3.37 + }
3.38 +
3.39 /// \ingroup io_group
3.40 /// \brief Lemon Format writer class.
3.41 ///
3.42 @@ -229,6 +258,7 @@
3.43 public:
3.44 typedef _Item Item;
3.45 virtual void write(std::ostream&, const Item&) const = 0;
3.46 + virtual bool isIdWriter() const = 0;
3.47 };
3.48
3.49 template <typename _Item, typename _BoxedIdWriter>
3.50 @@ -245,6 +275,10 @@
3.51 virtual void write(std::ostream& os, const Item& item) const {
3.52 idWriter.writeId(os, item);
3.53 }
3.54 +
3.55 + virtual bool isIdWriter() const {
3.56 + return idWriter.isIdWriter();
3.57 + }
3.58 };
3.59 };
3.60
3.61 @@ -318,6 +352,7 @@
3.62 template <typename Writer, typename Map>
3.63 NodeSetWriter& writeNodeMap(std::string name, const Map& map,
3.64 const Writer& writer = Writer()) {
3.65 + checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>();
3.66 writers.push_back(
3.67 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
3.68 return *this;
3.69 @@ -446,8 +481,10 @@
3.70 const std::string& _id = std::string(),
3.71 bool _forceIdMap = true)
3.72 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
3.73 - graph(_graph), id(_id),
3.74 - nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
3.75 + graph(_graph), id(_id) {
3.76 + checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
3.77 + nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
3.78 + }
3.79
3.80 /// \brief Destructor.
3.81 ///
3.82 @@ -480,6 +517,7 @@
3.83 template <typename Writer, typename Map>
3.84 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
3.85 const Writer& writer = Writer()) {
3.86 + checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
3.87 writers.push_back(
3.88 make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
3.89 return *this;
3.90 @@ -498,6 +536,9 @@
3.91 ///
3.92 /// Write the content of the section.
3.93 virtual void write(std::ostream& os) {
3.94 + if (!nodeIdWriter->isIdWriter()) {
3.95 + throw DataFormatError("Cannot find nodeset or ID map");
3.96 + }
3.97 for (int i = 0; i < (int)writers.size(); ++i) {
3.98 if (writers[i].first == "id") {
3.99 idMap = writers[i].second;
3.100 @@ -621,8 +662,10 @@
3.101 const std::string& _id = std::string(),
3.102 bool _forceIdMap = true)
3.103 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
3.104 - graph(_graph), id(_id),
3.105 - nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
3.106 + graph(_graph), id(_id) {
3.107 + checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
3.108 + nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
3.109 + }
3.110
3.111 /// \brief Destructor.
3.112 ///
3.113 @@ -655,6 +698,7 @@
3.114 template <typename Writer, typename Map>
3.115 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map,
3.116 const Writer& writer = Writer()) {
3.117 + checkConcept<concept::WriteMap<UndirEdge, typename Map::Value>, Map>();
3.118 writers.push_back(
3.119 make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
3.120 return *this;
3.121 @@ -665,6 +709,7 @@
3.122 /// Add a new directed map writer command for the writer.
3.123 template <typename Map>
3.124 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
3.125 + checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
3.126 writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
3.127 writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
3.128 return *this;
3.129 @@ -676,8 +721,9 @@
3.130 template <typename Writer, typename Map>
3.131 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
3.132 const Writer& writer = Writer()) {
3.133 + checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
3.134 writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
3.135 - writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
3.136 + writeUndirEdge("-" + name, composeMap(backwardMap(graph), map), writer);
3.137 return *this;
3.138 }
3.139
3.140 @@ -694,6 +740,9 @@
3.141 ///
3.142 /// Write the content of the section.
3.143 virtual void write(std::ostream& os) {
3.144 + if (!nodeIdWriter->isIdWriter()) {
3.145 + throw DataFormatError("Cannot find nodeset or ID map");
3.146 + }
3.147 for (int i = 0; i < (int)writers.size(); ++i) {
3.148 if (writers[i].first == "id") {
3.149 idMap = writers[i].second;
3.150 @@ -811,8 +860,11 @@
3.151 template <typename _IdWriter>
3.152 NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
3.153 const std::string& _id = std::string())
3.154 - : Parent(_writer), id(_id),
3.155 - idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {}
3.156 + : Parent(_writer), id(_id) {
3.157 + checkConcept<_writer_bits::ItemIdWriter<Node>, _IdWriter>();
3.158 + idWriter.reset(new IdWriter<Node, _IdWriter>(_idWriter));
3.159 + }
3.160 +
3.161
3.162 /// \brief Destructor.
3.163 ///
3.164 @@ -846,6 +898,9 @@
3.165 ///
3.166 /// Write the content of the section.
3.167 virtual void write(std::ostream& os) {
3.168 + if (!idWriter->isIdWriter()) {
3.169 + throw DataFormatError("Cannot find nodeset or ID map");
3.170 + }
3.171 for (int i = 0; i < (int)writers.size(); ++i) {
3.172 os << writers[i].first << ' ';
3.173 idWriter->write(os, *(writers[i].second));
3.174 @@ -887,8 +942,10 @@
3.175 template <typename _IdWriter>
3.176 EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
3.177 const std::string& _id = std::string())
3.178 - : Parent(_writer), id(_id),
3.179 - idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {}
3.180 + : Parent(_writer), id(_id) {
3.181 + checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
3.182 + idWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
3.183 + }
3.184
3.185 /// \brief Destructor.
3.186 ///
3.187 @@ -921,6 +978,9 @@
3.188 ///
3.189 /// Write the content of the section.
3.190 virtual void write(std::ostream& os) {
3.191 + if (!idWriter->isIdWriter()) {
3.192 + throw DataFormatError("Cannot find edgeset or ID map");
3.193 + }
3.194 for (int i = 0; i < (int)writers.size(); ++i) {
3.195 os << writers[i].first << ' ';
3.196 idWriter->write(os, *(writers[i].second));
3.197 @@ -966,9 +1026,12 @@
3.198 template <typename _IdWriter>
3.199 UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
3.200 const std::string& _id = std::string())
3.201 - : Parent(_writer), id(_id),
3.202 - undirEdgeIdWriter(new IdWriter<UndirEdge, _IdWriter>(_idWriter)),
3.203 - edgeIdWriter(new IdWriter<Edge, _IdWriter>(_idWriter)) {}
3.204 + : Parent(_writer), id(_id) {
3.205 + checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
3.206 + checkConcept<_writer_bits::ItemIdWriter<UndirEdge>, _IdWriter>();
3.207 + undirEdgeIdWriter.reset(new IdWriter<UndirEdge, _IdWriter>(_idWriter));
3.208 + edgeIdWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
3.209 + }
3.210
3.211 /// \brief Destructor.
3.212 ///
3.213 @@ -1008,6 +1071,12 @@
3.214 ///
3.215 /// Write the content of the section.
3.216 virtual void write(std::ostream& os) {
3.217 + if (!edgeIdWriter->isIdWriter()) {
3.218 + throw DataFormatError("Cannot find undirected edgeset or ID map");
3.219 + }
3.220 + if (!undirEdgeIdWriter->isIdWriter()) {
3.221 + throw DataFormatError("Cannot find undirected edgeset or ID map");
3.222 + }
3.223 for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
3.224 os << undirEdgeWriters[i].first << ' ';
3.225 undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));