1.1 --- a/lemon/lemon_reader.h Tue Aug 28 13:58:54 2007 +0000
1.2 +++ b/lemon/lemon_reader.h Tue Aug 28 14:00:42 2007 +0000
1.3 @@ -58,7 +58,7 @@
1.4 return p < q;
1.5 }
1.6 };
1.7 -
1.8 +
1.9 template <typename Item>
1.10 class ItemLabelReader {
1.11 public:
1.12 @@ -255,7 +255,7 @@
1.13 return it->second;
1.14 } else {
1.15 ErrorMessage msg;
1.16 - msg << "Invalid label error: " << value;
1.17 + msg << "Invalid label error";
1.18 throw DataFormatError(msg.message());
1.19 }
1.20 }
1.21 @@ -289,7 +289,7 @@
1.22
1.23 virtual Item read(std::istream& is) const {
1.24 Value value;
1.25 - reader.read(is, value);
1.26 + reader.read(is, value);
1.27 typename Inverse::const_iterator it = inverse.find(value);
1.28 if (it != inverse.end()) {
1.29 return it->second;
1.30 @@ -382,6 +382,7 @@
1.31 virtual ~LabelReaderBase() {}
1.32 virtual Item read(std::istream& is) const = 0;
1.33 virtual bool isLabelReader() const = 0;
1.34 + virtual LabelReaderBase<_Item>* clone() const = 0;
1.35 };
1.36
1.37 template <typename _Item, typename _BoxedLabelReader>
1.38 @@ -390,19 +391,23 @@
1.39 typedef _Item Item;
1.40 typedef _BoxedLabelReader BoxedLabelReader;
1.41
1.42 - const BoxedLabelReader& boxedLabelReader;
1.43 -
1.44 - LabelReader(const BoxedLabelReader& _boxedLabelReader)
1.45 - : boxedLabelReader(_boxedLabelReader) {}
1.46 + const BoxedLabelReader& labelReader;
1.47 +
1.48 + LabelReader(const BoxedLabelReader& _labelReader)
1.49 + : labelReader(_labelReader) {}
1.50
1.51 virtual Item read(std::istream& is) const {
1.52 Item item;
1.53 - boxedLabelReader.readLabel(is, item);
1.54 + labelReader.readLabel(is, item);
1.55 return item;
1.56 }
1.57
1.58 virtual bool isLabelReader() const {
1.59 - return boxedLabelReader.isLabelReader();
1.60 + return labelReader.isLabelReader();
1.61 + }
1.62 +
1.63 + LabelReader<Item, BoxedLabelReader>* clone() const {
1.64 + return new LabelReader<Item, BoxedLabelReader>(labelReader);
1.65 }
1.66 };
1.67
1.68 @@ -723,7 +728,6 @@
1.69 it->second = true;
1.70 char buf[2048];
1.71 FilterStreamBuf buffer(*is, line_num);
1.72 -
1.73 try {
1.74 buffer.pubsetbuf(buf, sizeof(buf));
1.75 std::istream ss(&buffer);
1.76 @@ -1511,8 +1515,8 @@
1.77 ///
1.78 /// It reads an id from the stream and gives back which undirected edge
1.79 /// belongs to it. It is possible only if there was read an "label" named map.
1.80 - void readLabel(std::istream& is, UEdge& uEdge) const {
1.81 - uEdge = inverter->read(is);
1.82 + void readLabel(std::istream& is, UEdge& uedge) const {
1.83 + uedge = inverter->read(is);
1.84 }
1.85
1.86 /// \brief Gives back the directed edge by its label.
1.87 @@ -1524,11 +1528,11 @@
1.88 void readLabel(std::istream& is, Edge& edge) const {
1.89 char c;
1.90 is >> c;
1.91 - UEdge uEdge = inverter->read(is);
1.92 + UEdge uedge = inverter->read(is);
1.93 if (c == '+') {
1.94 - edge = graph.direct(uEdge, true);
1.95 + edge = graph.direct(uedge, true);
1.96 } else if (c == '-') {
1.97 - edge = graph.direct(uEdge, false);
1.98 + edge = graph.direct(uedge, false);
1.99 } else {
1.100 throw DataFormatError("Wrong id format for edge "
1.101 "in undirected edgeset");
1.102 @@ -1807,10 +1811,10 @@
1.103 : Parent(_reader), name(_name) {
1.104 checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
1.105 checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
1.106 - uEdgeLabelReader.reset(new _reader_bits::
1.107 - LabelReader<UEdge, _LabelReader>(_labelReader));
1.108 + uedgeLabelReader.reset(new _reader_bits::
1.109 + LabelReader<UEdge, _LabelReader>(_labelReader));
1.110 edgeLabelReader.reset(new _reader_bits::
1.111 - LabelReader<Edge, _LabelReader>(_labelReader));
1.112 + LabelReader<Edge, _LabelReader>(_labelReader));
1.113 }
1.114
1.115 /// \brief Destructor.
1.116 @@ -1827,12 +1831,12 @@
1.117 ///
1.118 /// Add an undirected edge reader command for the UEdgeReader.
1.119 void readUEdge(std::string label, UEdge& item) {
1.120 - if (uEdgeReaders.find(label) != uEdgeReaders.end()) {
1.121 + if (uedgeReaders.find(label) != uedgeReaders.end()) {
1.122 ErrorMessage msg;
1.123 msg << "Multiple read rule for undirected edge: " << label;
1.124 throw IoParameterError(msg.message());
1.125 }
1.126 - uEdgeReaders.insert(make_pair(label, _reader_bits::
1.127 + uedgeReaders.insert(make_pair(label, _reader_bits::
1.128 ItemStore<UEdge>(item)));
1.129 }
1.130
1.131 @@ -1870,7 +1874,7 @@
1.132 if (!edgeLabelReader->isLabelReader()) {
1.133 throw DataFormatError("Cannot find undirected edgeset or label map");
1.134 }
1.135 - if (!uEdgeLabelReader->isLabelReader()) {
1.136 + if (!uedgeLabelReader->isLabelReader()) {
1.137 throw DataFormatError("Cannot find undirected edgeset or label map");
1.138 }
1.139 std::string line;
1.140 @@ -1879,9 +1883,9 @@
1.141 std::string id;
1.142 ls >> id;
1.143 {
1.144 - typename UEdgeReaders::iterator it = uEdgeReaders.find(id);
1.145 - if (it != uEdgeReaders.end()) {
1.146 - it->second.read(uEdgeLabelReader->read(ls));
1.147 + typename UEdgeReaders::iterator it = uedgeReaders.find(id);
1.148 + if (it != uedgeReaders.end()) {
1.149 + it->second.read(uedgeLabelReader->read(ls));
1.150 it->second.touch();
1.151 continue;
1.152 }
1.153 @@ -1902,8 +1906,8 @@
1.154 throw IoParameterError(msg.message());
1.155 }
1.156 }
1.157 - for (typename UEdgeReaders::iterator it = uEdgeReaders.begin();
1.158 - it != uEdgeReaders.end(); ++it) {
1.159 + for (typename UEdgeReaders::iterator it = uedgeReaders.begin();
1.160 + it != uedgeReaders.end(); ++it) {
1.161 if (!it->second.touched()) {
1.162 ErrorMessage msg;
1.163 msg << "UEdge not found in file: " << it->first;
1.164 @@ -1913,7 +1917,7 @@
1.165 }
1.166
1.167 virtual void missing() {
1.168 - if (edgeReaders.empty() && uEdgeReaders.empty()) return;
1.169 + if (edgeReaders.empty() && uedgeReaders.empty()) return;
1.170 ErrorMessage msg;
1.171 msg << "UEdges section not found in file: @uedges " << name;
1.172 throw IoParameterError(msg.message());
1.173 @@ -1925,8 +1929,8 @@
1.174
1.175 typedef std::map<std::string,
1.176 _reader_bits::ItemStore<UEdge> > UEdgeReaders;
1.177 - UEdgeReaders uEdgeReaders;
1.178 - std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uEdgeLabelReader;
1.179 + UEdgeReaders uedgeReaders;
1.180 + std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uedgeLabelReader;
1.181
1.182 typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
1.183 EdgeReaders edgeReaders;
1.184 @@ -2054,6 +2058,671 @@
1.185 };
1.186
1.187 /// \ingroup section_io
1.188 + /// \brief SectionReader for reading extra node maps.
1.189 + ///
1.190 + /// The lemon format can store maps in the nodeset sections. This
1.191 + /// class let you make distinict section to store maps. The main
1.192 + /// purpose of this class is a logical separation of some maps. The
1.193 + /// other useful application could be to store paths in node maps.
1.194 + ///
1.195 + /// The first line of the section contains the names of the maps
1.196 + /// separated with white spaces. Each next line describes an item
1.197 + /// in the itemset, and contains in the first column the label of
1.198 + /// the item and then the mapped values for each map.
1.199 + ///
1.200 + /// \relates LemonReader
1.201 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
1.202 + class NodeMapReader : public LemonReader::SectionReader {
1.203 + typedef LemonReader::SectionReader Parent;
1.204 + public:
1.205 +
1.206 + typedef _Graph Graph;
1.207 + typedef typename Graph::Node Node;
1.208 + typedef _Traits Traits;
1.209 + typedef typename Traits::Skipper DefaultSkipper;
1.210 +
1.211 + /// \brief Constructor.
1.212 + ///
1.213 + /// Constructor for NodeMapReader. It creates the NodeMapReader and
1.214 + /// attach it into the given LemonReader. The reader will read
1.215 + /// the section when the \c section_name and the \c _name are the same.
1.216 + template <typename _LabelReader>
1.217 + NodeMapReader(LemonReader& _reader,
1.218 + const Graph& _graph,
1.219 + const _LabelReader& _labelReader,
1.220 + const std::string& _name = std::string(),
1.221 + const DefaultSkipper& _skipper = DefaultSkipper())
1.222 + : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
1.223 + labelReader.reset(new _reader_bits::
1.224 + LabelReader<Node, _LabelReader>(_labelReader));
1.225 + }
1.226 +
1.227 +
1.228 + /// \brief Destructor.
1.229 + ///
1.230 + /// Destructor for NodeMapReader.
1.231 + virtual ~NodeMapReader() {
1.232 + for (typename MapReaders::iterator it = readers.begin();
1.233 + it != readers.end(); ++it) {
1.234 + delete it->second;
1.235 + }
1.236 + }
1.237 +
1.238 + private:
1.239 + NodeMapReader(const NodeMapReader&);
1.240 + void operator=(const NodeMapReader&);
1.241 +
1.242 + public:
1.243 +
1.244 + /// \brief Add a new node map reader command for the reader.
1.245 + ///
1.246 + /// Add a new node map reader command for the reader.
1.247 + template <typename Map>
1.248 + NodeMapReader& readNodeMap(std::string label, Map& map) {
1.249 + return _readMap<
1.250 + typename Traits::template Reader<typename Map::Value>, Map,
1.251 + typename _reader_bits::Arg<Map>::Type>(label, map);
1.252 + }
1.253 +
1.254 + template <typename Map>
1.255 + NodeMapReader& readNodeMap(std::string label, const Map& map) {
1.256 + return _readMap<
1.257 + typename Traits::template Reader<typename Map::Value>, Map,
1.258 + typename _reader_bits::Arg<Map>::Type>(label, map);
1.259 + }
1.260 +
1.261 + /// \brief Add a new node map reader command for the reader.
1.262 + ///
1.263 + /// Add a new node map reader command for the reader.
1.264 + template <typename ItemReader, typename Map>
1.265 + NodeMapReader& readNodeMap(std::string label, Map& map,
1.266 + const ItemReader& ir = ItemReader()) {
1.267 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
1.268 + (label, map, ir);
1.269 + }
1.270 +
1.271 + template <typename ItemReader, typename Map>
1.272 + NodeMapReader& readNodeMap(std::string label, const Map& map,
1.273 + const ItemReader& ir = ItemReader()) {
1.274 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
1.275 + (label, map, ir);
1.276 + }
1.277 +
1.278 + private:
1.279 +
1.280 + template <typename ItemReader, typename Map, typename MapParameter>
1.281 + NodeMapReader& _readMap(std::string label, MapParameter map,
1.282 + const ItemReader& ir = ItemReader()) {
1.283 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.284 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
1.285 + if (readers.find(label) != readers.end()) {
1.286 + ErrorMessage msg;
1.287 + msg << "Multiple read rule for map: " << label;
1.288 + throw IoParameterError(msg.message());
1.289 + }
1.290 + readers.insert(
1.291 + make_pair(label, new _reader_bits::
1.292 + MapReader<Node, Map, ItemReader>(map, ir)));
1.293 + return *this;
1.294 + }
1.295 +
1.296 + public:
1.297 +
1.298 + /// \brief Add a new node map skipper command for the reader.
1.299 + ///
1.300 + /// Add a new node map skipper command for the reader.
1.301 + template <typename ItemReader>
1.302 + NodeMapReader& skipNodeMap(std::string label,
1.303 + const ItemReader& ir = ItemReader()) {
1.304 + if (readers.find(label) != readers.end()) {
1.305 + ErrorMessage msg;
1.306 + msg << "Multiple read rule for map: " << label;
1.307 + throw IoParameterError(msg.message());
1.308 + }
1.309 + readers.insert(make_pair(label, new _reader_bits::
1.310 + SkipReader<Node, ItemReader>(ir)));
1.311 + return *this;
1.312 + }
1.313 +
1.314 + protected:
1.315 +
1.316 + /// \brief Gives back true when the SectionReader can process
1.317 + /// the section with the given header line.
1.318 + ///
1.319 + /// It gives back true when the header line starts with \c \@mapset,
1.320 + /// and the header line's name and the mapset's name are the same.
1.321 + virtual bool header(const std::string& line) {
1.322 + std::istringstream ls(line);
1.323 + std::string command;
1.324 + std::string id;
1.325 + ls >> command >> id;
1.326 + return command == "@nodemaps" && name == id;
1.327 + }
1.328 +
1.329 + /// \brief Reader function of the section.
1.330 + ///
1.331 + /// It reads the content of the section.
1.332 + virtual void read(std::istream& is) {
1.333 + std::vector<_reader_bits::MapReaderBase<Node>* > index;
1.334 + std::string line;
1.335 +
1.336 + {
1.337 + getline(is, line);
1.338 + std::istringstream ls(line);
1.339 + std::string id;
1.340 + while (ls >> id) {
1.341 + typename MapReaders::iterator it = readers.find(id);
1.342 + if (it != readers.end()) {
1.343 + it->second->touch();
1.344 + index.push_back(it->second);
1.345 + } else {
1.346 + index.push_back(&skipper);
1.347 + }
1.348 + }
1.349 + }
1.350 + for (typename MapReaders::iterator it = readers.begin();
1.351 + it != readers.end(); ++it) {
1.352 + if (!it->second->touched()) {
1.353 + ErrorMessage msg;
1.354 + msg << "Map not found in file: " << it->first;
1.355 + throw IoParameterError(msg.message());
1.356 + }
1.357 + }
1.358 + while (getline(is, line)) {
1.359 + std::istringstream ls(line);
1.360 + Node node = labelReader->read(ls);
1.361 + for (int i = 0; i < int(index.size()); ++i) {
1.362 + index[i]->read(ls, node);
1.363 + }
1.364 + }
1.365 + }
1.366 +
1.367 + virtual void missing() {
1.368 + if (readers.empty()) return;
1.369 + ErrorMessage msg;
1.370 + msg << "NodeMap section not found in file: @nodemaps " << name;
1.371 + throw IoParameterError(msg.message());
1.372 + }
1.373 +
1.374 + private:
1.375 +
1.376 + typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
1.377 + MapReaders readers;
1.378 +
1.379 + const Graph& graph;
1.380 + std::string name;
1.381 + _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
1.382 + std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader;
1.383 +
1.384 + };
1.385 +
1.386 + /// \ingroup section_io
1.387 + /// \brief SectionReader for reading extra edge maps.
1.388 + ///
1.389 + /// The lemon format can store maps in the edgeset sections. This
1.390 + /// class let you make distinict section to store maps. The main
1.391 + /// purpose of this class is a logical separation of some maps. The
1.392 + /// other useful application could be to store paths in edge maps.
1.393 + ///
1.394 + /// The first line of the section contains the names of the maps
1.395 + /// separated with white spaces. Each next line describes an item
1.396 + /// in the itemset, and contains in the first column the label of
1.397 + /// the item and then the mapped values for each map.
1.398 + ///
1.399 + /// \relates LemonReader
1.400 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
1.401 + class EdgeMapReader : public LemonReader::SectionReader {
1.402 + typedef LemonReader::SectionReader Parent;
1.403 + public:
1.404 +
1.405 + typedef _Graph Graph;
1.406 + typedef typename Graph::Edge Edge;
1.407 + typedef _Traits Traits;
1.408 + typedef typename Traits::Skipper DefaultSkipper;
1.409 +
1.410 + /// \brief Constructor.
1.411 + ///
1.412 + /// Constructor for EdgeMapReader. It creates the EdgeMapReader and
1.413 + /// attach it into the given LemonReader. The reader will read
1.414 + /// the section when the \c section_name and the \c _name are the same.
1.415 + template <typename _LabelReader>
1.416 + EdgeMapReader(LemonReader& _reader,
1.417 + const Graph& _graph,
1.418 + const _LabelReader& _labelReader,
1.419 + const std::string& _name = std::string(),
1.420 + const DefaultSkipper& _skipper = DefaultSkipper())
1.421 + : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
1.422 + labelReader.reset(new _reader_bits::
1.423 + LabelReader<Edge, _LabelReader>(_labelReader));
1.424 + }
1.425 +
1.426 +
1.427 + /// \brief Destructor.
1.428 + ///
1.429 + /// Destructor for EdgeMapReader.
1.430 + virtual ~EdgeMapReader() {
1.431 + for (typename MapReaders::iterator it = readers.begin();
1.432 + it != readers.end(); ++it) {
1.433 + delete it->second;
1.434 + }
1.435 + }
1.436 +
1.437 + private:
1.438 + EdgeMapReader(const EdgeMapReader&);
1.439 + void operator=(const EdgeMapReader&);
1.440 +
1.441 + public:
1.442 +
1.443 + /// \brief Add a new edge map reader command for the reader.
1.444 + ///
1.445 + /// Add a new edge map reader command for the reader.
1.446 + template <typename Map>
1.447 + EdgeMapReader& readEdgeMap(std::string label, Map& map) {
1.448 + return _readMap<
1.449 + typename Traits::template Reader<typename Map::Value>, Map,
1.450 + typename _reader_bits::Arg<Map>::Type>(label, map);
1.451 + }
1.452 +
1.453 + template <typename Map>
1.454 + EdgeMapReader& readEdgeMap(std::string label, const Map& map) {
1.455 + return _readMap<
1.456 + typename Traits::template Reader<typename Map::Value>, Map,
1.457 + typename _reader_bits::Arg<Map>::Type>(label, map);
1.458 + }
1.459 +
1.460 + /// \brief Add a new edge map reader command for the reader.
1.461 + ///
1.462 + /// Add a new edge map reader command for the reader.
1.463 + template <typename ItemReader, typename Map>
1.464 + EdgeMapReader& readEdgeMap(std::string label, Map& map,
1.465 + const ItemReader& ir = ItemReader()) {
1.466 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
1.467 + (label, map, ir);
1.468 + }
1.469 +
1.470 + template <typename ItemReader, typename Map>
1.471 + EdgeMapReader& readEdgeMap(std::string label, const Map& map,
1.472 + const ItemReader& ir = ItemReader()) {
1.473 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
1.474 + (label, map, ir);
1.475 + }
1.476 +
1.477 + private:
1.478 +
1.479 + template <typename ItemReader, typename Map, typename MapParameter>
1.480 + EdgeMapReader& _readMap(std::string label, MapParameter map,
1.481 + const ItemReader& ir = ItemReader()) {
1.482 + checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1.483 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
1.484 + if (readers.find(label) != readers.end()) {
1.485 + ErrorMessage msg;
1.486 + msg << "Multiple read rule for map: " << label;
1.487 + throw IoParameterError(msg.message());
1.488 + }
1.489 + readers.insert(
1.490 + make_pair(label, new _reader_bits::
1.491 + MapReader<Edge, Map, ItemReader>(map, ir)));
1.492 + return *this;
1.493 + }
1.494 +
1.495 + public:
1.496 +
1.497 + /// \brief Add a new edge map skipper command for the reader.
1.498 + ///
1.499 + /// Add a new edge map skipper command for the reader.
1.500 + template <typename ItemReader>
1.501 + EdgeMapReader& skipEdgeMap(std::string label,
1.502 + const ItemReader& ir = ItemReader()) {
1.503 + if (readers.find(label) != readers.end()) {
1.504 + ErrorMessage msg;
1.505 + msg << "Multiple read rule for map: " << label;
1.506 + throw IoParameterError(msg.message());
1.507 + }
1.508 + readers.insert(make_pair(label, new _reader_bits::
1.509 + SkipReader<Edge, ItemReader>(ir)));
1.510 + return *this;
1.511 + }
1.512 +
1.513 + protected:
1.514 +
1.515 + /// \brief Gives back true when the SectionReader can process
1.516 + /// the section with the given header line.
1.517 + ///
1.518 + /// It gives back true when the header line starts with \c \@mapset,
1.519 + /// and the header line's name and the mapset's name are the same.
1.520 + virtual bool header(const std::string& line) {
1.521 + std::istringstream ls(line);
1.522 + std::string command;
1.523 + std::string id;
1.524 + ls >> command >> id;
1.525 + return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
1.526 + }
1.527 +
1.528 + /// \brief Reader function of the section.
1.529 + ///
1.530 + /// It reads the content of the section.
1.531 + virtual void read(std::istream& is) {
1.532 + std::vector<_reader_bits::MapReaderBase<Edge>* > index;
1.533 + std::string line;
1.534 +
1.535 + {
1.536 + getline(is, line);
1.537 + std::istringstream ls(line);
1.538 + std::string id;
1.539 + while (ls >> id) {
1.540 + typename MapReaders::iterator it = readers.find(id);
1.541 + if (it != readers.end()) {
1.542 + it->second->touch();
1.543 + index.push_back(it->second);
1.544 + } else {
1.545 + index.push_back(&skipper);
1.546 + }
1.547 + }
1.548 + }
1.549 + for (typename MapReaders::iterator it = readers.begin();
1.550 + it != readers.end(); ++it) {
1.551 + if (!it->second->touched()) {
1.552 + ErrorMessage msg;
1.553 + msg << "Map not found in file: " << it->first;
1.554 + throw IoParameterError(msg.message());
1.555 + }
1.556 + }
1.557 + while (getline(is, line)) {
1.558 + std::istringstream ls(line);
1.559 + Edge edge = labelReader->read(ls);
1.560 + for (int i = 0; i < int(index.size()); ++i) {
1.561 + index[i]->read(ls, edge);
1.562 + }
1.563 + }
1.564 + }
1.565 +
1.566 + virtual void missing() {
1.567 + if (readers.empty()) return;
1.568 + ErrorMessage msg;
1.569 + msg << "EdgeMap section not found in file: @edgemaps " << name;
1.570 + throw IoParameterError(msg.message());
1.571 + }
1.572 +
1.573 + private:
1.574 +
1.575 + typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
1.576 + MapReaders readers;
1.577 +
1.578 + const Graph& graph;
1.579 + std::string name;
1.580 + _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
1.581 + std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader;
1.582 +
1.583 + };
1.584 +
1.585 + /// \ingroup section_io
1.586 + /// \brief SectionReader for reading extra undirected edge maps.
1.587 + ///
1.588 + /// The lemon format can store maps in the uedgeset sections. This
1.589 + /// class let you make distinict section to store maps. The main
1.590 + /// purpose of this class is a logical separation of some maps. The
1.591 + /// other useful application could be to store paths in undirected
1.592 + /// edge maps.
1.593 + ///
1.594 + /// The first line of the section contains the names of the maps
1.595 + /// separated with white spaces. Each next line describes an item
1.596 + /// in the itemset, and contains in the first column the label of
1.597 + /// the item and then the mapped values for each map.
1.598 + ///
1.599 + /// \relates LemonReader
1.600 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
1.601 + class UEdgeMapReader : public LemonReader::SectionReader {
1.602 + typedef LemonReader::SectionReader Parent;
1.603 + public:
1.604 +
1.605 + typedef _Graph Graph;
1.606 + typedef typename Graph::Edge Edge;
1.607 + typedef typename Graph::UEdge UEdge;
1.608 + typedef _Traits Traits;
1.609 + typedef typename Traits::Skipper DefaultSkipper;
1.610 +
1.611 + /// \brief Constructor.
1.612 + ///
1.613 + /// Constructor for UEdgeMapReader. It creates the UEdgeMapReader and
1.614 + /// attach it into the given LemonReader. The reader will read
1.615 + /// the section when the \c section_name and the \c _name are the same.
1.616 + template <typename _LabelReader>
1.617 + UEdgeMapReader(LemonReader& _reader, const Graph& _graph,
1.618 + const _LabelReader& _labelReader,
1.619 + const std::string& _name = std::string(),
1.620 + const DefaultSkipper& _skipper = DefaultSkipper())
1.621 + : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
1.622 + labelReader.reset(new _reader_bits::
1.623 + LabelReader<UEdge, _LabelReader>(_labelReader));
1.624 + }
1.625 +
1.626 +
1.627 + /// \brief Destructor.
1.628 + ///
1.629 + /// Destructor for UEdgeMapReader.
1.630 + virtual ~UEdgeMapReader() {
1.631 + for (typename MapReaders::iterator it = readers.begin();
1.632 + it != readers.end(); ++it) {
1.633 + delete it->second;
1.634 + }
1.635 + }
1.636 +
1.637 + private:
1.638 + UEdgeMapReader(const UEdgeMapReader&);
1.639 + void operator=(const UEdgeMapReader&);
1.640 +
1.641 + public:
1.642 +
1.643 + /// \brief Add a new undirected edge map reader command for the
1.644 + /// reader.
1.645 + ///
1.646 + /// Add a new undirected edge map reader command for the reader.
1.647 + template <typename Map>
1.648 + UEdgeMapReader& readUEdgeMap(std::string label, Map& map) {
1.649 + return _readMap<
1.650 + typename Traits::template Reader<typename Map::Value>, Map,
1.651 + typename _reader_bits::Arg<Map>::Type>(label, map);
1.652 + }
1.653 +
1.654 + template <typename Map>
1.655 + UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) {
1.656 + return _readMap<
1.657 + typename Traits::template Reader<typename Map::Value>, Map,
1.658 + typename _reader_bits::Arg<Map>::Type>(label, map);
1.659 + }
1.660 +
1.661 + /// \brief Add a new undirected edge map reader command for the
1.662 + /// reader.
1.663 + ///
1.664 + /// Add a new undirected edge map reader command for the reader.
1.665 + template <typename ItemReader, typename Map>
1.666 + UEdgeMapReader& readUEdgeMap(std::string label, Map& map,
1.667 + const ItemReader& ir = ItemReader()) {
1.668 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
1.669 + (label, map, ir);
1.670 + }
1.671 +
1.672 + template <typename ItemReader, typename Map>
1.673 + UEdgeMapReader& readUEdgeMap(std::string label, const Map& map,
1.674 + const ItemReader& ir = ItemReader()) {
1.675 + return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
1.676 + (label, map, ir);
1.677 + }
1.678 +
1.679 + private:
1.680 +
1.681 + template <typename ItemReader, typename Map, typename MapParameter>
1.682 + UEdgeMapReader& _readMap(std::string label, MapParameter map,
1.683 + const ItemReader& ir = ItemReader()) {
1.684 + checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1.685 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
1.686 + if (readers.find(label) != readers.end()) {
1.687 + ErrorMessage msg;
1.688 + msg << "Multiple read rule for map: " << label;
1.689 + throw IoParameterError(msg.message());
1.690 + }
1.691 + readers.insert(
1.692 + make_pair(label, new _reader_bits::
1.693 + MapReader<UEdge, Map, ItemReader>(map, ir)));
1.694 + return *this;
1.695 + }
1.696 +
1.697 + public:
1.698 +
1.699 + /// \brief Add a new undirected edge map skipper command for the
1.700 + /// reader.
1.701 + ///
1.702 + /// Add a new undirected edge map skipper command for the reader.
1.703 + template <typename ItemReader>
1.704 + UEdgeMapReader& skipUEdgeMap(std::string label,
1.705 + const ItemReader& ir = ItemReader()) {
1.706 + if (readers.find(label) != readers.end()) {
1.707 + ErrorMessage msg;
1.708 + msg << "Multiple read rule for map: " << label;
1.709 + throw IoParameterError(msg.message());
1.710 + }
1.711 + readers.insert(make_pair(label, new _reader_bits::
1.712 + SkipReader<Edge, ItemReader>(ir)));
1.713 + return *this;
1.714 + }
1.715 +
1.716 + /// \brief Add a new directed edge map reader command for the reader.
1.717 + ///
1.718 + /// Add a new directed edge map reader command for the reader.
1.719 + template <typename Map>
1.720 + UEdgeMapReader& readEdgeMap(std::string label, Map& map) {
1.721 + return _readDirMap<
1.722 + typename Traits::template Reader<typename Map::Value>, Map,
1.723 + typename _reader_bits::Arg<Map>::Type>(label, map);
1.724 + }
1.725 +
1.726 + template <typename Map>
1.727 + UEdgeMapReader& readEdgeMap(std::string label, const Map& map) {
1.728 + return _readDirMap<
1.729 + typename Traits::template Reader<typename Map::Value>, Map,
1.730 + typename _reader_bits::Arg<Map>::Type>(label, map);
1.731 + }
1.732 +
1.733 + /// \brief Add a new directed edge map reader command for the reader.
1.734 + ///
1.735 + /// Add a new directed edge map reader command for the reader.
1.736 + template <typename ItemReader, typename Map>
1.737 + UEdgeMapReader& readEdgeMap(std::string label, Map& map,
1.738 + const ItemReader& ir = ItemReader()) {
1.739 + return _readDirMap<ItemReader, Map,
1.740 + typename _reader_bits::Arg<Map>::Type>(label, map, ir);
1.741 + }
1.742 +
1.743 + template <typename ItemReader, typename Map>
1.744 + UEdgeMapReader& readEdgeMap(std::string label, const Map& map,
1.745 + const ItemReader& ir = ItemReader()) {
1.746 + return _readDirMap<ItemReader, Map,
1.747 + typename _reader_bits::Arg<Map>::Type>(label, map, ir);
1.748 + }
1.749 +
1.750 + private:
1.751 +
1.752 + template <typename ItemReader, typename Map, typename MapParameter>
1.753 + UEdgeMapReader& _readDirMap(std::string label, MapParameter map,
1.754 + const ItemReader& ir = ItemReader()) {
1.755 + checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
1.756 + checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1.757 + readUEdgeMap("+" + label,
1.758 + _reader_bits::forwardComposeMap(graph, map), ir);
1.759 + readUEdgeMap("-" + label,
1.760 + _reader_bits::backwardComposeMap(graph, map), ir);
1.761 + return *this;
1.762 + }
1.763 +
1.764 + public:
1.765 +
1.766 + /// \brief Add a new directed edge map skipper command for the reader.
1.767 + ///
1.768 + /// Add a new directed edge map skipper command for the reader.
1.769 + template <typename ItemReader>
1.770 + UEdgeMapReader& skipEdgeMap(std::string label,
1.771 + const ItemReader& ir = ItemReader()) {
1.772 + skipUEdgeMap("+" + label, ir);
1.773 + skipUEdgeMap("-" + label, ir);
1.774 + return *this;
1.775 + }
1.776 +
1.777 + protected:
1.778 +
1.779 + /// \brief Gives back true when the SectionReader can process
1.780 + /// the section with the given header line.
1.781 + ///
1.782 + /// It gives back true when the header line starts with \c \@mapset,
1.783 + /// and the header line's name and the mapset's name are the same.
1.784 + virtual bool header(const std::string& line) {
1.785 + std::istringstream ls(line);
1.786 + std::string command;
1.787 + std::string id;
1.788 + ls >> command >> id;
1.789 + return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
1.790 + }
1.791 +
1.792 + /// \brief Reader function of the section.
1.793 + ///
1.794 + /// It reads the content of the section.
1.795 + virtual void read(std::istream& is) {
1.796 + std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
1.797 + std::string line;
1.798 +
1.799 + {
1.800 + getline(is, line);
1.801 + std::istringstream ls(line);
1.802 + std::string id;
1.803 + while (ls >> id) {
1.804 + typename MapReaders::iterator it = readers.find(id);
1.805 + if (it != readers.end()) {
1.806 + it->second->touch();
1.807 + index.push_back(it->second);
1.808 + } else {
1.809 + index.push_back(&skipper);
1.810 + }
1.811 + }
1.812 + }
1.813 + for (typename MapReaders::iterator it = readers.begin();
1.814 + it != readers.end(); ++it) {
1.815 + if (!it->second->touched()) {
1.816 + ErrorMessage msg;
1.817 + msg << "Map not found in file: " << it->first;
1.818 + throw IoParameterError(msg.message());
1.819 + }
1.820 + }
1.821 + while (getline(is, line)) {
1.822 + std::istringstream ls(line);
1.823 + UEdge uedge = labelReader->read(ls);
1.824 + for (int i = 0; i < int(index.size()); ++i) {
1.825 + index[i]->read(ls, uedge);
1.826 + }
1.827 + }
1.828 + }
1.829 +
1.830 + virtual void missing() {
1.831 + if (readers.empty()) return;
1.832 + ErrorMessage msg;
1.833 + msg << "UEdgeMap section not found in file: @uedgemaps " << name;
1.834 + throw IoParameterError(msg.message());
1.835 + }
1.836 +
1.837 + private:
1.838 +
1.839 + const Graph& graph;
1.840 + std::string name;
1.841 +
1.842 + typedef std::map<std::string,
1.843 + _reader_bits::MapReaderBase<UEdge>*> MapReaders;
1.844 +
1.845 + MapReaders readers;
1.846 + _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
1.847 +
1.848 + std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader;
1.849 +
1.850 + };
1.851 +
1.852 + /// \ingroup section_io
1.853 /// \brief SectionReader for retrieve what is in the file.
1.854 ///
1.855 /// SectionReader for retrieve what is in the file. If you want