3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
21 ///\brief Lemon Format reader.
24 #ifndef LEMON_LEMON_READER_H
25 #define LEMON_LEMON_READER_H
36 #include <lemon/error.h>
37 #include <lemon/graph_utils.h>
38 #include <lemon/bits/utility.h>
39 #include <lemon/bits/item_reader.h>
41 #include <lemon/dim2.h>
43 #include <lemon/concept_check.h>
44 #include <lemon/concepts/maps.h>
48 namespace _reader_bits {
51 bool operator<(T, T) {
52 throw DataFormatError("Label is not comparable");
57 bool operator()(const T& p, const T& q) const {
62 template <typename Item>
63 class ItemLabelReader {
66 bool isLabelReader() { return true; }
68 void readLabel(std::istream&, Item&) {}
70 template <class _ItemLabelReader>
73 bool b = reader.isLabelReader();
74 ignore_unused_variable_warning(b);
76 reader.readLabel(is, item);
78 _ItemLabelReader& reader;
84 template <typename Item>
87 void read(std::istream&, Item&) {}
89 template <class _ItemReader>
93 reader.read(is, item);
101 template <typename Map>
102 struct Ref { typedef Map& Type; };
103 template <typename Map>
104 struct Arg { typedef Map& Type; };
106 template <typename Graph, typename Map>
107 class ForwardComposeMap {
109 typedef typename Graph::UEdge Key;
110 typedef typename Map::Value Value;
112 ForwardComposeMap(const Graph& _graph, typename Arg<Map>::Type _map)
113 : graph(_graph), map(_map) {}
115 void set(const Key& key, const Value& val) {
116 map.set(graph.direct(key, true), val);
121 typename Ref<Map>::Type map;
124 template <typename Graph, typename Map>
125 ForwardComposeMap<Graph, Map>
126 forwardComposeMap(const Graph& graph, const Map& map) {
127 return ForwardComposeMap<Graph, Map>(graph, map);
130 template <typename Graph, typename Map>
131 ForwardComposeMap<Graph, Map>
132 forwardComposeMap(const Graph& graph, Map& map) {
133 return ForwardComposeMap<Graph, Map>(graph, map);
136 template <typename Graph, typename Map>
137 class BackwardComposeMap {
139 typedef typename Graph::UEdge Key;
140 typedef typename Map::Value Value;
142 BackwardComposeMap(const Graph& _graph, typename Arg<Map>::Type _map)
143 : graph(_graph), map(_map) {}
145 void set(const Key& key, const Value& val) {
146 map.set(graph.direct(key, false), val);
151 typename Ref<Map>::Type map;
155 template <typename Graph, typename Map>
156 BackwardComposeMap<Graph, Map>
157 backwardComposeMap(const Graph& graph, const Map& map) {
158 return BackwardComposeMap<Graph, Map>(graph, map);
161 template <typename Graph, typename Map>
162 BackwardComposeMap<Graph, Map>
163 backwardComposeMap(const Graph& graph, Map& map) {
164 return BackwardComposeMap<Graph, Map>(graph, map);
167 template <typename Graph, typename Map>
168 struct Ref<ForwardComposeMap<Graph, Map> > {
169 typedef ForwardComposeMap<Graph, Map> Type;
171 template <typename Graph, typename Map>
172 struct Arg<ForwardComposeMap<Graph, Map> > {
173 typedef const ForwardComposeMap<Graph, Map>& Type;
176 template <typename Graph, typename Map>
177 struct Ref<BackwardComposeMap<Graph, Map> > {
178 typedef BackwardComposeMap<Graph, Map> Type;
180 template <typename Graph, typename Map>
181 struct Arg<BackwardComposeMap<Graph, Map> > {
182 typedef const BackwardComposeMap<Graph, Map>& Type;
185 template <typename Map>
186 struct Ref<dim2::XMap<Map> > {
187 typedef dim2::XMap<Map> Type;
189 template <typename Map>
190 struct Arg<dim2::XMap<Map> > {
191 typedef const dim2::XMap<Map>& Type;
194 template <typename Map>
195 struct Ref<dim2::YMap<Map> > {
196 typedef dim2::YMap<Map> Type;
198 template <typename Map>
199 struct Arg<dim2::YMap<Map> > {
200 typedef const dim2::YMap<Map>& Type;
204 template <typename _Item>
207 template <typename _Item>
208 class MapInverterBase : public MapReaderBase<_Item> {
211 virtual void read(std::istream&, const Item&) = 0;
212 virtual Item read(std::istream&) const = 0;
214 virtual MapInverterBase<_Item>* getInverter() {
219 template <typename _Item, typename _Map, typename _Reader>
220 class MapReaderInverter : public MapInverterBase<_Item> {
223 typedef _Reader Reader;
224 typedef typename Reader::Value Value;
226 typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
228 typename _reader_bits::Ref<Map>::Type map;
232 MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map,
233 const Reader& _reader)
234 : map(_map), reader(_reader) {}
236 virtual ~MapReaderInverter() {}
238 virtual void read(std::istream& is, const Item& item) {
240 reader.read(is, value);
241 map.set(item, value);
242 typename Inverse::iterator it = inverse.find(value);
243 if (it == inverse.end()) {
244 inverse.insert(std::make_pair(value, item));
246 throw DataFormatError("Multiple label occurence");
250 virtual Item read(std::istream& is) const {
252 reader.read(is, value);
253 typename Inverse::const_iterator it = inverse.find(value);
254 if (it != inverse.end()) {
258 msg << "Invalid label error";
259 throw DataFormatError(msg.message());
264 template <typename _Item, typename _Reader>
265 class SkipReaderInverter : public MapInverterBase<_Item> {
268 typedef _Reader Reader;
269 typedef typename Reader::Value Value;
270 typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
274 SkipReaderInverter(const Reader& _reader)
277 virtual ~SkipReaderInverter() {}
279 virtual void read(std::istream& is, const Item& item) {
281 reader.read(is, value);
282 typename Inverse::iterator it = inverse.find(value);
283 if (it == inverse.end()) {
284 inverse.insert(std::make_pair(value, item));
286 throw DataFormatError("Multiple label occurence error");
290 virtual Item read(std::istream& is) const {
292 reader.read(is, value);
293 typename Inverse::const_iterator it = inverse.find(value);
294 if (it != inverse.end()) {
298 msg << "Invalid label error: " << value;
299 throw DataFormatError(msg.message());
307 template <typename _Item>
308 class MapReaderBase {
312 MapReaderBase() { _touched = false; }
314 void touch() { _touched = true; }
315 bool touched() const { return _touched; }
317 virtual ~MapReaderBase() {}
319 virtual void read(std::istream& is, const Item& item) = 0;
320 virtual MapInverterBase<_Item>* getInverter() = 0;
327 template <typename _Item, typename _Map, typename _Reader>
328 class MapReader : public MapReaderBase<_Item> {
331 typedef _Reader Reader;
332 typedef typename Reader::Value Value;
335 typename _reader_bits::Ref<Map>::Type map;
338 MapReader(typename _reader_bits::Arg<Map>::Type _map,
339 const Reader& _reader)
340 : map(_map), reader(_reader) {}
342 virtual ~MapReader() {}
344 virtual void read(std::istream& is, const Item& item) {
346 reader.read(is, value);
347 map.set(item, value);
350 virtual MapInverterBase<_Item>* getInverter() {
351 return new MapReaderInverter<Item, Map, Reader>(map, reader);
356 template <typename _Item, typename _Reader>
357 class SkipReader : public MapReaderBase<_Item> {
359 typedef _Reader Reader;
360 typedef typename Reader::Value Value;
364 SkipReader(const Reader& _reader) : reader(_reader) {}
366 virtual ~SkipReader() {}
368 virtual void read(std::istream& is, const Item&) {
370 reader.read(is, value);
373 virtual MapInverterBase<Item>* getInverter() {
374 return new SkipReaderInverter<Item, Reader>(reader);
378 template <typename _Item>
379 class LabelReaderBase {
382 virtual ~LabelReaderBase() {}
383 virtual Item read(std::istream& is) const = 0;
384 virtual bool isLabelReader() const = 0;
385 virtual LabelReaderBase<_Item>* clone() const = 0;
388 template <typename _Item, typename _BoxedLabelReader>
389 class LabelReader : public LabelReaderBase<_Item> {
392 typedef _BoxedLabelReader BoxedLabelReader;
394 const BoxedLabelReader& labelReader;
396 LabelReader(const BoxedLabelReader& _labelReader)
397 : labelReader(_labelReader) {}
399 virtual Item read(std::istream& is) const {
401 labelReader.readLabel(is, item);
405 virtual bool isLabelReader() const {
406 return labelReader.isLabelReader();
409 LabelReader<Item, BoxedLabelReader>* clone() const {
410 return new LabelReader<Item, BoxedLabelReader>(labelReader);
414 template <typename _Item>
420 ItemStore(Item& _item) : item(&_item) {
424 void touch() { _touched = true; }
425 bool touched() const { return _touched; }
427 void read(const Item& _item) {
436 class ValueReaderBase {
438 virtual void read(std::istream&) {};
439 ValueReaderBase() { _touched = false; }
441 void touch() { _touched = true; }
442 bool touched() const { return _touched; }
444 virtual ~ValueReaderBase() {}
449 template <typename _Value, typename _Reader>
450 class ValueReader : public ValueReaderBase {
452 typedef _Value Value;
453 typedef _Reader Reader;
455 ValueReader(Value& _value, const Reader& _reader)
456 : value(_value), reader(_reader) {}
458 virtual void read(std::istream& is) {
459 reader.read(is, value);
468 /// \ingroup lemon_io
469 /// \brief Lemon Format reader class.
471 /// The Lemon Format contains several sections. We do not want to
472 /// determine what sections are in a lemon file we give only a framework
473 /// to read a section oriented format.
475 /// In the Lemon Format each section starts with a line containing a
476 /// \c \@ character on the first not white space position. This line
477 /// is the header line of the section. Each of the next lines belong
478 /// to this section until a line starting with \c \@ character is
479 /// found. This line can start a new section or it can close the
480 /// file with the \c \@end line. The file format ignores the empty
481 /// and comment lines. The line is comment line if it starts with a
484 /// The framework provides an abstract LemonReader::SectionReader class
485 /// that defines the interface of a SectionReader. The SectionReader
486 /// has the \c header() member function that gets a header line string and
487 /// decides if it wants to process the next section. Several SectionReaders
488 /// can be attached to a LemonReader and the first attached that can
489 /// process the section will be used. Its \c read() member will be called
490 /// with a stream containing the section. From this stream the empty and
491 /// comment lines are filtered out.
493 /// \relates GraphReader
494 /// \relates NodeSetReader
495 /// \relates EdgeSetReader
496 /// \relates NodesReader
497 /// \relates EdgesReader
498 /// \relates AttributeReader
502 class FilterStreamBuf : public std::streambuf {
505 typedef std::streambuf Parent;
506 typedef Parent::char_type char_type;
507 FilterStreamBuf(std::istream& is, int& num)
508 : _is(is), _base(0), _eptr(0),
509 _num(num), skip_state(after_endl) {}
513 enum skip_state_type {
519 char_type small_buf[1];
529 skip_state_type skip_state;
532 char_type* base() { return _base; }
534 char_type* eptr() { return _eptr; }
536 int_type blen() { return _eptr - _base; }
538 void setb(char_type* buf, int_type len) {
543 virtual std::streambuf* setbuf(char *buf, std::streamsize len) {
544 if (base()) return 0;
545 if (buf != 0 && len >= int(sizeof(small_buf))) {
548 setb(small_buf, sizeof(small_buf));
554 bool put_char(char c) {
555 switch (skip_state) {
559 skip_state = after_endl;
571 skip_state = comment_line;
575 skip_state = no_skip;
585 skip_state = after_endl;
594 virtual int_type underflow() {
596 if (_is.read(&c, 1)) {
605 for (ptr = base(); ptr != eptr(); ++ptr) {
606 if (_is.read(&c, 1)) {
607 if (c == '\n') ++_num;
611 if (skip_state == after_endl && c == '@') {
621 setg(base(), base(), ptr);
625 virtual int_type sync() {
631 int line_num() const {
633 for (char_type* p = gptr(); p != egptr(); ++p) {
643 /// \brief Abstract base class for reading a section.
645 /// This class has an \c header() member function what get a
646 /// header line string and decides if it want to process the next
647 /// section. Several SectionReaders can be attached to an LemonReader
648 /// and the first attached what can process the section will be used.
649 /// Its \c read() member will called with a stream contains the section.
650 /// From this stream the empty lines and comments are filtered out.
651 class SectionReader {
652 friend class LemonReader;
654 /// \brief Constructor for SectionReader.
656 /// Constructor for SectionReader. It attach this reader to
657 /// the given LemonReader.
658 SectionReader(LemonReader& reader) {
659 reader.attach(*this);
662 virtual ~SectionReader() {}
664 /// \brief Gives back true when the SectionReader can process
665 /// the section with the given header line.
667 /// It gives back true when the SectionReader can process
668 /// the section with the given header line.
669 virtual bool header(const std::string& line) = 0;
671 /// \brief Reader function of the section.
673 /// It reads the content of the section.
674 virtual void read(std::istream& is) = 0;
676 /// \brief The given section missing in the file.
678 /// The given section missing in the file.
679 virtual void missing() {};
682 /// \brief Constructor for LemonReader.
684 /// Constructor for LemonReader which reads from the given stream.
685 LemonReader(std::istream& _is)
686 : is(&_is), own_is(false) {}
688 /// \brief Constructor for LemonReader.
690 /// Constructor for LemonReader which reads from the given file.
691 LemonReader(const std::string& filename)
692 : is(0), own_is(true) {
693 is = new std::ifstream(filename.c_str());
695 throw FileOpenError(filename);
699 /// \brief Desctructor for LemonReader.
701 /// Desctructor for LemonReader.
709 LemonReader(const LemonReader&);
710 void operator=(const LemonReader&);
712 void attach(SectionReader& reader) {
713 readers.push_back(std::make_pair(&reader, false));
717 /// \brief Executes the LemonReader.
719 /// It executes the LemonReader.
724 SectionReaders::iterator it;
725 while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
726 for (it = readers.begin(); it != readers.end(); ++it) {
727 if (it->first->header(line)) {
730 FilterStreamBuf buffer(*is, line_num);
732 buffer.pubsetbuf(buf, sizeof(buf));
733 std::istream ss(&buffer);
736 } catch (DataFormatError& error) {
737 error.line(buffer.line_num());
743 for (it = readers.begin(); it != readers.end(); ++it) {
746 it->first->missing();
747 } catch (DataFormatError& error) {
748 error.line(line_num);
761 typedef std::vector<std::pair<SectionReader*, bool> > SectionReaders;
762 SectionReaders readers;
766 /// \ingroup section_io
767 /// \brief SectionReader for reading a graph's nodeset.
769 /// The lemon format can store multiple graph nodesets with several
770 /// maps. The nodeset section's header line is \c \@nodeset \c
771 /// nodeset_name, but the \c nodeset_name may be empty.
773 /// The first line of the section contains the names of the maps separated
774 /// with white spaces. Each next lines describes a node in the nodeset, and
775 /// contains the mapped values for each map.
777 /// If the nodeset contains an \c "label" named map then it will be regarded
778 /// as id map. This map should contain only unique values and when the
779 /// \c readLabel() member will read a value from the given stream it will
780 /// give back that node which is mapped to this value.
782 /// \relates LemonReader
783 template <typename _Graph, typename _Traits = DefaultReaderTraits>
784 class NodeSetReader : public LemonReader::SectionReader {
785 typedef LemonReader::SectionReader Parent;
788 typedef _Graph Graph;
789 typedef _Traits Traits;
790 typedef typename Graph::Node Node;
791 typedef typename Traits::Skipper DefaultSkipper;
793 /// \brief Constructor.
795 /// Constructor for NodeSetReader. It creates the NodeSetReader and
796 /// attach it into the given LemonReader. The nodeset reader will
797 /// add the read nodes to the given Graph. The reader will read
798 /// the section when the \c section_name and the \c _name are the same.
799 NodeSetReader(LemonReader& _reader,
801 const std::string& _name = std::string(),
802 const DefaultSkipper& _skipper = DefaultSkipper())
803 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {}
806 /// \brief Destructor.
808 /// Destructor for NodeSetReader.
809 virtual ~NodeSetReader() {
810 for (typename MapReaders::iterator it = readers.begin();
811 it != readers.end(); ++it) {
817 NodeSetReader(const NodeSetReader&);
818 void operator=(const NodeSetReader&);
822 /// \brief Add a new node map reader command for the reader.
824 /// Add a new node map reader command for the reader.
825 template <typename Map>
826 NodeSetReader& readNodeMap(std::string label, Map& map) {
828 typename Traits::template Reader<typename Map::Value>, Map,
829 typename _reader_bits::Arg<Map>::Type>(label, map);
832 template <typename Map>
833 NodeSetReader& readNodeMap(std::string label, const Map& map) {
835 typename Traits::template Reader<typename Map::Value>, Map,
836 typename _reader_bits::Arg<Map>::Type>(label, map);
839 /// \brief Add a new node map reader command for the reader.
841 /// Add a new node map reader command for the reader.
842 template <typename ItemReader, typename Map>
843 NodeSetReader& readNodeMap(std::string label, Map& map,
844 const ItemReader& ir = ItemReader()) {
845 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
849 template <typename ItemReader, typename Map>
850 NodeSetReader& readNodeMap(std::string label, const Map& map,
851 const ItemReader& ir = ItemReader()) {
852 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
858 template <typename ItemReader, typename Map, typename MapParameter>
859 NodeSetReader& _readMap(std::string label, MapParameter map,
860 const ItemReader& ir = ItemReader()) {
861 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
862 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
863 if (readers.find(label) != readers.end()) {
865 msg << "Multiple read rule for node map: " << label;
866 throw IoParameterError(msg.message());
869 make_pair(label, new _reader_bits::
870 MapReader<Node, Map, ItemReader>(map, ir)));
876 /// \brief Add a new node map skipper command for the reader.
878 /// Add a new node map skipper command for the reader.
879 template <typename ItemReader>
880 NodeSetReader& skipNodeMap(std::string label,
881 const ItemReader& ir = ItemReader()) {
882 if (readers.find(label) != readers.end()) {
884 msg << "Multiple read rule for node map: " << label;
885 throw IoParameterError(msg.message());
887 readers.insert(make_pair(label, new _reader_bits::
888 SkipReader<Node, ItemReader>(ir)));
894 /// \brief Gives back true when the SectionReader can process
895 /// the section with the given header line.
897 /// It gives back true when the header line starts with \c \@nodeset,
898 /// and the header line's name and the nodeset's name are the same.
899 virtual bool header(const std::string& line) {
900 std::istringstream ls(line);
904 return command == "@nodeset" && name == id;
907 /// \brief Reader function of the section.
909 /// It reads the content of the section.
910 virtual void read(std::istream& is) {
911 std::vector<_reader_bits::MapReaderBase<Node>* > index;
916 std::istringstream ls(line);
919 typename MapReaders::iterator it = readers.find(id);
920 if (it != readers.end()) {
922 index.push_back(it->second);
924 index.push_back(&skipper);
927 inverter.reset(index.back()->getInverter());
928 index.back() = inverter.get();
932 for (typename MapReaders::iterator it = readers.begin();
933 it != readers.end(); ++it) {
934 if (!it->second->touched()) {
936 msg << "Map not found in file: " << it->first;
937 throw IoParameterError(msg.message());
940 while (getline(is, line)) {
941 Node node = graph.addNode();
942 std::istringstream ls(line);
943 for (int i = 0; i < int(index.size()); ++i) {
944 index[i]->read(ls, node);
949 virtual void missing() {
950 if (readers.empty()) return;
952 msg << "NodeSet section not found in file: @nodeset " << name;
953 throw IoParameterError(msg.message());
958 /// \brief Returns true if the nodeset can give back the node by its label.
960 /// Returns true if the nodeset can give back the node by its label.
961 /// It is possible only if an "label" named map was read.
962 bool isLabelReader() const {
963 return inverter.get() != 0;
966 /// \brief Gives back the node by its label.
968 /// It reads an id from the stream and gives back which node belongs to
969 /// it. It is possible only if there was read an "label" named map.
970 void readLabel(std::istream& is, Node& node) const {
971 node = inverter->read(is);
976 typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
981 _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
983 std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
986 /// \ingroup section_io
987 /// \brief SectionReader for reading a graph's edgeset.
989 /// The lemon format can store multiple graph edgesets with several maps.
990 /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but the
991 /// \c edgeset_name may be empty.
993 /// The first line of the section contains the names of the maps separated
994 /// with white spaces. Each next lines describes an edge in the edgeset. The
995 /// line contains the source and the target nodes' id and the mapped
996 /// values for each map.
998 /// If the edgeset contains an \c "label" named map then it will be regarded
999 /// as id map. This map should contain only unique values and when the
1000 /// \c readLabel() member will read a value from the given stream it will
1001 /// give back that edge which is mapped to this value.
1003 /// The edgeset reader needs a node id reader to identify which nodes
1004 /// have to be connected. If a NodeSetReader reads an "label" named map,
1005 /// it will be able to resolve the nodes by ids.
1007 /// \relates LemonReader
1008 template <typename _Graph, typename _Traits = DefaultReaderTraits>
1009 class EdgeSetReader : public LemonReader::SectionReader {
1010 typedef LemonReader::SectionReader Parent;
1013 typedef _Graph Graph;
1014 typedef _Traits Traits;
1015 typedef typename Graph::Node Node;
1016 typedef typename Graph::Edge Edge;
1017 typedef typename Traits::Skipper DefaultSkipper;
1019 /// \brief Constructor.
1021 /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
1022 /// attach it into the given LemonReader. The edgeset reader will
1023 /// add the read edges to the given Graph. It will use the given
1024 /// node id reader to read the source and target nodes of the edges.
1025 /// The reader will read the section only if the \c _name and the
1026 /// \c edgset_name are the same.
1027 template <typename NodeLabelReader>
1028 EdgeSetReader(LemonReader& _reader,
1030 const NodeLabelReader& _nodeLabelReader,
1031 const std::string& _name = std::string(),
1032 const DefaultSkipper& _skipper = DefaultSkipper())
1033 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
1034 checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
1035 nodeLabelReader.reset(new _reader_bits::
1036 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
1038 /// \brief Destructor.
1040 /// Destructor for EdgeSetReader.
1041 virtual ~EdgeSetReader() {
1042 for (typename MapReaders::iterator it = readers.begin();
1043 it != readers.end(); ++it) {
1049 EdgeSetReader(const EdgeSetReader&);
1050 void operator=(const EdgeSetReader&);
1054 /// \brief Add a new edge map reader command for the reader.
1056 /// Add a new edge map reader command for the reader.
1057 template <typename Map>
1058 EdgeSetReader& readEdgeMap(std::string label, Map& map) {
1060 typename Traits::template Reader<typename Map::Value>, Map,
1061 typename _reader_bits::Arg<Map>::Type>(label, map);
1064 template <typename Map>
1065 EdgeSetReader& readEdgeMap(std::string label, const Map& map) {
1067 typename Traits::template Reader<typename Map::Value>, Map,
1068 typename _reader_bits::Arg<Map>::Type>(label, map);
1071 /// \brief Add a new edge map reader command for the reader.
1073 /// Add a new edge map reader command for the reader.
1074 template <typename ItemReader, typename Map>
1075 EdgeSetReader& readEdgeMap(std::string label, Map& map,
1076 const ItemReader& ir = ItemReader()) {
1077 return _readMap<ItemReader, Map,
1078 typename _reader_bits::Arg<Map>::Type>(label, map, ir);
1081 template <typename ItemReader, typename Map>
1082 EdgeSetReader& readEdgeMap(std::string label, const Map& map,
1083 const ItemReader& ir = ItemReader()) {
1084 return _readMap<ItemReader, Map,
1085 typename _reader_bits::Arg<Map>::Type>(label, map, ir);
1090 template <typename ItemReader, typename Map, typename MapParameter>
1091 EdgeSetReader& _readMap(std::string label, MapParameter map,
1092 const ItemReader& ir = ItemReader()) {
1093 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1094 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
1095 if (readers.find(label) != readers.end()) {
1097 msg << "Multiple read rule for edge map: " << label;
1098 throw IoParameterError(msg.message());
1101 make_pair(label, new _reader_bits::
1102 MapReader<Edge, Map, ItemReader>(map, ir)));
1108 /// \brief Add a new edge map skipper command for the reader.
1110 /// Add a new edge map skipper command for the reader.
1111 template <typename ItemReader>
1112 EdgeSetReader& skipEdgeMap(std::string label,
1113 const ItemReader& ir = ItemReader()) {
1114 if (readers.find(label) != readers.end()) {
1116 msg << "Multiple read rule for edge map: " << label;
1117 throw IoParameterError(msg.message());
1119 readers.insert(make_pair(label, new _reader_bits::
1120 SkipReader<Edge, ItemReader>(ir)));
1126 /// \brief Gives back true when the SectionReader can process
1127 /// the section with the given header line.
1129 /// It gives back true when the header line starts with \c \@edgeset,
1130 /// and the header line's name and the edgeset's name are the same.
1131 /// The sections with @uedgeset head line could be read with this
1132 /// section reader too.
1133 virtual bool header(const std::string& line) {
1134 std::istringstream ls(line);
1135 std::string command;
1137 ls >> command >> id;
1138 return (command == "@edgeset" || command == "@uedgeset") && name == id;
1141 /// \brief Reader function of the section.
1143 /// It reads the content of the section.
1144 virtual void read(std::istream& is) {
1145 if (!nodeLabelReader->isLabelReader()) {
1146 throw DataFormatError("Cannot find nodeset or label map");
1148 std::vector<_reader_bits::MapReaderBase<Edge>* > index;
1153 std::istringstream ls(line);
1156 typename MapReaders::iterator it = readers.find(id);
1157 if (it != readers.end()) {
1158 index.push_back(it->second);
1159 it->second->touch();
1161 index.push_back(&skipper);
1163 if (id == "label") {
1164 inverter.reset(index.back()->getInverter());
1165 index.back() = inverter.get();
1169 for (typename MapReaders::iterator it = readers.begin();
1170 it != readers.end(); ++it) {
1171 if (!it->second->touched()) {
1173 msg << "Map not found in file: " << it->first;
1174 throw IoParameterError(msg.message());
1177 while (getline(is, line)) {
1178 std::istringstream ls(line);
1179 Node from = nodeLabelReader->read(ls);
1180 Node to = nodeLabelReader->read(ls);
1181 Edge edge = graph.addEdge(from, to);
1182 for (int i = 0; i < int(index.size()); ++i) {
1183 index[i]->read(ls, edge);
1188 virtual void missing() {
1189 if (readers.empty()) return;
1191 msg << "EdgeSet section not found in file: @edgeset " << name;
1192 throw IoParameterError(msg.message());
1197 /// \brief Returns true if the edgeset can give back the edge by its label.
1199 /// Returns true if the edgeset can give back the edge by its label.
1200 /// It is possible only if an "label" named map was read.
1201 bool isLabelReader() const {
1202 return inverter.get() != 0;
1205 /// \brief Gives back the edge by its label.
1207 /// It reads an id from the stream and gives back which edge belongs to
1208 /// it. It is possible only if there was read an "label" named map.
1209 void readLabel(std::istream& is, Edge& edge) const {
1210 edge = inverter->read(is);
1215 typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*>
1222 _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
1224 std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
1225 std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
1228 /// \ingroup section_io
1229 /// \brief SectionReader for reading a undirected graph's edgeset.
1231 /// The lemon format can store multiple undirected edgesets with several
1232 /// maps. The undirected edgeset section's header line is \c \@uedgeset
1233 /// \c uedgeset_name, but the \c uedgeset_name may be empty.
1235 /// The first line of the section contains the names of the maps separated
1236 /// with white spaces. Each next lines describes an edge in the edgeset. The
1237 /// line contains the connected nodes' id and the mapped values for each map.
1239 /// The section can handle the directed as a syntactical sugar. Two
1240 /// undirected edge map describes one directed edge map. This two maps
1241 /// are the forward map and the backward map and the names of this map
1242 /// is near the same just with a prefix \c '+' or \c '-' character
1245 /// If the edgeset contains an \c "label" named map then it will be regarded
1246 /// as id map. This map should contain only unique values and when the
1247 /// \c readLabel() member will read a value from the given stream it will
1248 /// give back that uicted edge which is mapped to this value.
1250 /// The undirected edgeset reader needs a node id reader to identify which
1251 /// nodes have to be connected. If a NodeSetReader reads an "label" named
1252 /// map, it will be able to resolve the nodes by ids.
1254 /// \relates LemonReader
1255 template <typename _Graph, typename _Traits = DefaultReaderTraits>
1256 class UEdgeSetReader : public LemonReader::SectionReader {
1257 typedef LemonReader::SectionReader Parent;
1260 typedef _Graph Graph;
1261 typedef _Traits Traits;
1262 typedef typename Graph::Node Node;
1263 typedef typename Graph::Edge Edge;
1264 typedef typename Graph::UEdge UEdge;
1265 typedef typename Traits::Skipper DefaultSkipper;
1267 /// \brief Constructor.
1269 /// Constructor for UEdgeSetReader. It creates the UEdgeSetReader
1270 /// and attach it into the given LemonReader. The undirected edgeset
1271 /// reader will add the read undirected edges to the given Graph. It
1272 /// will use the given node id reader to read the source and target
1273 /// nodes of the edges. The reader will read the section only if the
1274 /// \c _name and the \c uedgset_name are the same.
1275 template <typename NodeLabelReader>
1276 UEdgeSetReader(LemonReader& _reader,
1278 const NodeLabelReader& _nodeLabelReader,
1279 const std::string& _name = std::string(),
1280 const DefaultSkipper& _skipper = DefaultSkipper())
1281 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
1282 checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
1283 nodeLabelReader.reset(new _reader_bits::
1284 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
1286 /// \brief Destructor.
1288 /// Destructor for UEdgeSetReader.
1289 virtual ~UEdgeSetReader() {
1290 for (typename MapReaders::iterator it = readers.begin();
1291 it != readers.end(); ++it) {
1297 UEdgeSetReader(const UEdgeSetReader&);
1298 void operator=(const UEdgeSetReader&);
1302 /// \brief Add a new undirected edge map reader command for the reader.
1304 /// Add a new edge undirected map reader command for the reader.
1305 template <typename Map>
1306 UEdgeSetReader& readUEdgeMap(std::string label, Map& map) {
1308 typename Traits::template Reader<typename Map::Value>, Map,
1309 typename _reader_bits::Arg<Map>::Type>(label, map);
1312 template <typename Map>
1313 UEdgeSetReader& readUEdgeMap(std::string label, const Map& map) {
1315 typename Traits::template Reader<typename Map::Value>, Map,
1316 typename _reader_bits::Arg<Map>::Type>(label, map);
1319 /// \brief Add a new undirected edge map reader command for the reader.
1321 /// Add a new edge undirected map reader command for the reader.
1322 template <typename ItemReader, typename Map>
1323 UEdgeSetReader& readUEdgeMap(std::string label, Map& map,
1324 const ItemReader& ir = ItemReader()) {
1325 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
1329 template <typename ItemReader, typename Map>
1330 UEdgeSetReader& readUEdgeMap(std::string label, const Map& map,
1331 const ItemReader& ir = ItemReader()) {
1332 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type >
1338 template <typename ItemReader, typename Map, typename MapParameter>
1339 UEdgeSetReader& _readMap(std::string label, MapParameter map,
1340 const ItemReader& ir = ItemReader()) {
1341 checkConcept<concepts::WriteMap<UEdge, typename Map::Value>, Map>();
1342 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
1343 if (readers.find(label) != readers.end()) {
1345 msg << "Multiple read rule for edge map: " << label;
1346 throw IoParameterError(msg.message());
1349 make_pair(label, new _reader_bits::
1350 MapReader<UEdge, Map, ItemReader>(map, ir)));
1356 /// \brief Add a new undirected edge map skipper command for the reader.
1358 /// Add a new undirected edge map skipper command for the reader.
1359 template <typename ItemReader>
1360 UEdgeSetReader& skipUEdgeMap(std::string label,
1361 const ItemReader& ir = ItemReader()) {
1362 if (readers.find(label) != readers.end()) {
1364 msg << "Multiple read rule for node map: " << label;
1365 throw IoParameterError(msg.message());
1367 readers.insert(make_pair(label, new _reader_bits::
1368 SkipReader<UEdge, ItemReader>(ir)));
1372 /// \brief Add a new directed edge map reader command for the reader.
1374 /// Add a new directed edge map reader command for the reader.
1375 template <typename Map>
1376 UEdgeSetReader& readEdgeMap(std::string label, Map& map) {
1378 typename Traits::template Reader<typename Map::Value>, Map,
1379 typename _reader_bits::Arg<Map>::Type>(label, map);
1382 template <typename Map>
1383 UEdgeSetReader& readEdgeMap(std::string label, const Map& map) {
1385 typename Traits::template Reader<typename Map::Value>, Map,
1386 typename _reader_bits::Arg<Map>::Type>(label, map);
1389 /// \brief Add a new directed edge map reader command for the reader.
1391 /// Add a new directed edge map reader command for the reader.
1392 template <typename ItemReader, typename Map>
1393 UEdgeSetReader& readEdgeMap(std::string label, Map& map,
1394 const ItemReader& ir = ItemReader()) {
1395 return _readDirMap<ItemReader, Map,
1396 typename _reader_bits::Arg<Map>::Type>(label, map, ir);
1399 template <typename ItemReader, typename Map>
1400 UEdgeSetReader& readEdgeMap(std::string label, const Map& map,
1401 const ItemReader& ir = ItemReader()) {
1402 return _readDirMap<ItemReader, Map,
1403 typename _reader_bits::Arg<Map>::Type>(label, map, ir);
1408 template <typename ItemReader, typename Map, typename MapParameter>
1409 UEdgeSetReader& _readDirMap(std::string label, MapParameter map,
1410 const ItemReader& ir = ItemReader()) {
1411 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
1412 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1413 readUEdgeMap("+" + label,
1414 _reader_bits::forwardComposeMap(graph, map), ir);
1415 readUEdgeMap("-" + label,
1416 _reader_bits::backwardComposeMap(graph, map), ir);
1422 /// \brief Add a new directed edge map skipper command for the reader.
1424 /// Add a new directed edge map skipper command for the reader.
1425 template <typename ItemReader>
1426 UEdgeSetReader& skipEdgeMap(std::string label,
1427 const ItemReader& ir = ItemReader()) {
1428 skipUEdgeMap("+" + label, ir);
1429 skipUEdgeMap("-" + label, ir);
1435 /// \brief Gives back true when the SectionReader can process
1436 /// the section with the given header line.
1438 /// It gives back true when the header line starts with \c \@uedgeset,
1439 /// and the header line's name and the edgeset's name are the same.
1440 /// The sections with @edgeset head line could be read with this
1441 /// section reader too.
1442 virtual bool header(const std::string& line) {
1443 std::istringstream ls(line);
1444 std::string command;
1446 ls >> command >> id;
1447 return (command == "@edgeset" || command == "@uedgeset") && name == id;
1450 /// \brief Reader function of the section.
1452 /// It reads the content of the section.
1453 virtual void read(std::istream& is) {
1454 if (!nodeLabelReader->isLabelReader()) {
1455 throw DataFormatError("Cannot find nodeset or label map");
1457 std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
1462 std::istringstream ls(line);
1465 typename MapReaders::iterator it = readers.find(id);
1466 if (it != readers.end()) {
1467 index.push_back(it->second);
1468 it->second->touch();
1470 index.push_back(&skipper);
1472 if (id == "label") {
1473 inverter.reset(index.back()->getInverter());
1474 index.back() = inverter.get();
1477 for (typename MapReaders::iterator it = readers.begin();
1478 it != readers.end(); ++it) {
1479 if (!it->second->touched()) {
1481 msg << "Map not found in file: " << it->first;
1482 throw IoParameterError(msg.message());
1486 while (getline(is, line)) {
1487 std::istringstream ls(line);
1488 Node from = nodeLabelReader->read(ls);
1489 Node to = nodeLabelReader->read(ls);
1490 UEdge edge = graph.addEdge(from, to);
1491 for (int i = 0; i < int(index.size()); ++i) {
1492 index[i]->read(ls, edge);
1497 virtual void missing() {
1498 if (readers.empty()) return;
1500 msg << "UEdgeSet section not found in file: @uedgeset " << name;
1501 throw IoParameterError(msg.message());
1506 /// \brief Returns true if the edgeset can give back the edge by its label.
1508 /// Returns true if the edgeset can give back the undirected edge by its
1509 /// id. It is possible only if an "label" named map was read.
1510 bool isLabelReader() const {
1511 return inverter.get() != 0;
1514 /// \brief Gives back the undirected edge by its label.
1516 /// It reads an id from the stream and gives back which undirected edge
1517 /// belongs to it. It is possible only if there was read an "label" named map.
1518 void readLabel(std::istream& is, UEdge& uedge) const {
1519 uedge = inverter->read(is);
1522 /// \brief Gives back the directed edge by its label.
1524 /// It reads an id from the stream and gives back which directed edge
1525 /// belongs to it. The directed edge id is the \c '+' or \c '-' character
1526 /// and the undirected edge id. It is possible only if there was read
1527 /// an "label" named map.
1528 void readLabel(std::istream& is, Edge& edge) const {
1531 UEdge uedge = inverter->read(is);
1533 edge = graph.direct(uedge, true);
1534 } else if (c == '-') {
1535 edge = graph.direct(uedge, false);
1537 throw DataFormatError("Wrong id format for edge "
1538 "in undirected edgeset");
1544 typedef std::map<std::string,
1545 _reader_bits::MapReaderBase<UEdge>*> MapReaders;
1550 _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
1552 std::auto_ptr<_reader_bits::MapInverterBase<UEdge> > inverter;
1553 std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
1556 /// \ingroup section_io
1557 /// \brief SectionReader for reading labeled nodes.
1559 /// The nodes section's header line is \c \@nodes \c nodes_name, but the
1560 /// \c nodes_name may be empty.
1562 /// Each line in the section contains the name of the node
1563 /// and then the node id.
1565 /// \relates LemonReader
1566 template <typename _Graph>
1567 class NodeReader : public LemonReader::SectionReader {
1568 typedef LemonReader::SectionReader Parent;
1569 typedef _Graph Graph;
1570 typedef typename Graph::Node Node;
1573 /// \brief Constructor.
1575 /// Constructor for NodeReader. It creates the NodeReader and
1576 /// attach it into the given LemonReader. It will use the given
1577 /// node id reader to give back the nodes. The reader will read the
1578 /// section only if the \c _name and the \c nodes_name are the same.
1579 template <typename _LabelReader>
1580 NodeReader(LemonReader& _reader, const _LabelReader& _labelReader,
1581 const std::string& _name = std::string())
1582 : Parent(_reader), name(_name) {
1583 checkConcept<_reader_bits::ItemLabelReader<Node>, _LabelReader>();
1584 nodeLabelReader.reset(new _reader_bits::
1585 LabelReader<Node, _LabelReader>(_labelReader));
1588 /// \brief Destructor.
1590 /// Destructor for NodeReader.
1591 virtual ~NodeReader() {}
1594 NodeReader(const NodeReader&);
1595 void operator=(const NodeReader&);
1599 /// \brief Add a node reader command for the NodeReader.
1601 /// Add a node reader command for the NodeReader.
1602 void readNode(std::string label, Node& item) {
1603 if (readers.find(label) != readers.end()) {
1605 msg << "Multiple read rule for node: " << label;
1606 throw IoParameterError(msg.message());
1608 readers.insert(make_pair(label, _reader_bits::ItemStore<Node>(item)));
1613 /// \brief Gives back true when the SectionReader can process
1614 /// the section with the given header line.
1616 /// It gives back true when the header line start with \c \@nodes,
1617 /// and the header line's name and the reader's name are the same.
1618 virtual bool header(const std::string& line) {
1619 std::istringstream ls(line);
1620 std::string command;
1622 ls >> command >> id;
1623 return command == "@nodes" && name == id;
1626 /// \brief Reader function of the section.
1628 /// It reads the content of the section.
1629 virtual void read(std::istream& is) {
1630 if (!nodeLabelReader->isLabelReader()) {
1631 throw DataFormatError("Cannot find nodeset or label map");
1634 while (getline(is, line)) {
1635 std::istringstream ls(line);
1638 typename NodeReaders::iterator it = readers.find(id);
1639 if (it != readers.end()) {
1640 it->second.read(nodeLabelReader->read(ls));
1644 for (typename NodeReaders::iterator it = readers.begin();
1645 it != readers.end(); ++it) {
1646 if (!it->second.touched()) {
1648 msg << "Node not found in file: " << it->first;
1649 throw IoParameterError(msg.message());
1654 virtual void missing() {
1655 if (readers.empty()) return;
1657 msg << "Nodes section not found in file: @nodes " << name;
1658 throw IoParameterError(msg.message());
1665 typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
1666 NodeReaders readers;
1667 std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
1670 /// \ingroup section_io
1671 /// \brief SectionReader for reading labeled edges.
1673 /// The edges section's header line is \c \@edges \c edges_name, but the
1674 /// \c edges_name may be empty.
1676 /// Each line in the section contains the name of the edge
1677 /// and then the edge id.
1679 /// \relates LemonReader
1680 template <typename _Graph>
1681 class EdgeReader : public LemonReader::SectionReader {
1682 typedef LemonReader::SectionReader Parent;
1683 typedef _Graph Graph;
1684 typedef typename Graph::Edge Edge;
1687 /// \brief Constructor.
1689 /// Constructor for EdgeReader. It creates the EdgeReader and
1690 /// attach it into the given LemonReader. It will use the given
1691 /// edge id reader to give back the edges. The reader will read the
1692 /// section only if the \c _name and the \c edges_name are the same.
1693 template <typename _LabelReader>
1694 EdgeReader(LemonReader& _reader, const _LabelReader& _labelReader,
1695 const std::string& _name = std::string())
1696 : Parent(_reader), name(_name) {
1697 checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
1698 edgeLabelReader.reset(new _reader_bits::
1699 LabelReader<Edge, _LabelReader>(_labelReader));
1702 /// \brief Destructor.
1704 /// Destructor for EdgeReader.
1705 virtual ~EdgeReader() {}
1707 EdgeReader(const EdgeReader&);
1708 void operator=(const EdgeReader&);
1712 /// \brief Add an edge reader command for the EdgeReader.
1714 /// Add an edge reader command for the EdgeReader.
1715 void readEdge(std::string label, Edge& item) {
1716 if (readers.find(label) != readers.end()) {
1718 msg << "Multiple read rule for edge: " << label;
1719 throw IoParameterError(msg.message());
1721 readers.insert(make_pair(label, _reader_bits::ItemStore<Edge>(item)));
1726 /// \brief Gives back true when the SectionReader can process
1727 /// the section with the given header line.
1729 /// It gives back true when the header line start with \c \@edges,
1730 /// and the header line's name and the reader's name are the same.
1731 virtual bool header(const std::string& line) {
1732 std::istringstream ls(line);
1733 std::string command;
1735 ls >> command >> id;
1736 return command == "@edges" && name == id;
1739 /// \brief Reader function of the section.
1741 /// It reads the content of the section.
1742 virtual void read(std::istream& is) {
1743 if (!edgeLabelReader->isLabelReader()) {
1744 throw DataFormatError("Cannot find edgeset or label map");
1747 while (getline(is, line)) {
1748 std::istringstream ls(line);
1751 typename EdgeReaders::iterator it = readers.find(id);
1752 if (it != readers.end()) {
1753 it->second.read(edgeLabelReader->read(ls));
1757 for (typename EdgeReaders::iterator it = readers.begin();
1758 it != readers.end(); ++it) {
1759 if (!it->second.touched()) {
1761 msg << "Edge not found in file: " << it->first;
1762 throw IoParameterError(msg.message());
1767 virtual void missing() {
1768 if (readers.empty()) return;
1770 msg << "Edges section not found in file: @edges " << name;
1771 throw IoParameterError(msg.message());
1778 typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
1779 EdgeReaders readers;
1780 std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
1783 /// \ingroup section_io
1784 /// \brief SectionReader for reading labeled undirected edges.
1786 /// The undirected edges section's header line is \c \@uedges
1787 /// \c uedges_name, but the \c uedges_name may be empty.
1789 /// Each line in the section contains the name of the undirected edge
1790 /// and then the undirected edge id.
1792 /// \relates LemonReader
1793 template <typename _Graph>
1794 class UEdgeReader : public LemonReader::SectionReader {
1795 typedef LemonReader::SectionReader Parent;
1796 typedef _Graph Graph;
1797 typedef typename Graph::Edge Edge;
1798 typedef typename Graph::UEdge UEdge;
1801 /// \brief Constructor.
1803 /// Constructor for UEdgeReader. It creates the UEdgeReader and
1804 /// attach it into the given LemonReader. It will use the given
1805 /// undirected edge id reader to give back the edges. The reader will
1806 /// read the section only if the \c _name and the \c uedges_name are
1808 template <typename _LabelReader>
1809 UEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader,
1810 const std::string& _name = std::string())
1811 : Parent(_reader), name(_name) {
1812 checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
1813 checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
1814 uedgeLabelReader.reset(new _reader_bits::
1815 LabelReader<UEdge, _LabelReader>(_labelReader));
1816 edgeLabelReader.reset(new _reader_bits::
1817 LabelReader<Edge, _LabelReader>(_labelReader));
1820 /// \brief Destructor.
1822 /// Destructor for UEdgeReader.
1823 virtual ~UEdgeReader() {}
1825 UEdgeReader(const UEdgeReader&);
1826 void operator=(const UEdgeReader&);
1830 /// \brief Add an undirected edge reader command for the UEdgeReader.
1832 /// Add an undirected edge reader command for the UEdgeReader.
1833 void readUEdge(std::string label, UEdge& item) {
1834 if (uedgeReaders.find(label) != uedgeReaders.end()) {
1836 msg << "Multiple read rule for undirected edge: " << label;
1837 throw IoParameterError(msg.message());
1839 uedgeReaders.insert(make_pair(label, _reader_bits::
1840 ItemStore<UEdge>(item)));
1843 /// \brief Add an edge reader command for the UEdgeReader.
1845 /// Add an edge reader command for the UEdgeReader.
1846 void readEdge(std::string label, Edge& item) {
1847 if (edgeReaders.find(label) != edgeReaders.end()) {
1849 msg << "Multiple read rule for edge: " << label;
1850 throw IoParameterError(msg.message());
1852 edgeReaders.insert(make_pair(label, _reader_bits::ItemStore<Edge>(item)));
1857 /// \brief Gives back true when the SectionReader can process
1858 /// the section with the given header line.
1860 /// It gives back true when the header line start with \c \@edges,
1861 /// and the header line's name and the reader's name are the same.
1862 virtual bool header(const std::string& line) {
1863 std::istringstream ls(line);
1864 std::string command;
1866 ls >> command >> id;
1867 return command == "@uedges" && name == id;
1870 /// \brief Reader function of the section.
1872 /// It reads the content of the section.
1873 virtual void read(std::istream& is) {
1874 if (!edgeLabelReader->isLabelReader()) {
1875 throw DataFormatError("Cannot find undirected edgeset or label map");
1877 if (!uedgeLabelReader->isLabelReader()) {
1878 throw DataFormatError("Cannot find undirected edgeset or label map");
1881 while (getline(is, line)) {
1882 std::istringstream ls(line);
1886 typename UEdgeReaders::iterator it = uedgeReaders.find(id);
1887 if (it != uedgeReaders.end()) {
1888 it->second.read(uedgeLabelReader->read(ls));
1893 typename EdgeReaders::iterator it = edgeReaders.find(id);
1894 if (it != edgeReaders.end()) {
1895 it->second.read(edgeLabelReader->read(ls));
1901 for (typename EdgeReaders::iterator it = edgeReaders.begin();
1902 it != edgeReaders.end(); ++it) {
1903 if (!it->second.touched()) {
1905 msg << "Edge not found in file: " << it->first;
1906 throw IoParameterError(msg.message());
1909 for (typename UEdgeReaders::iterator it = uedgeReaders.begin();
1910 it != uedgeReaders.end(); ++it) {
1911 if (!it->second.touched()) {
1913 msg << "UEdge not found in file: " << it->first;
1914 throw IoParameterError(msg.message());
1919 virtual void missing() {
1920 if (edgeReaders.empty() && uedgeReaders.empty()) return;
1922 msg << "UEdges section not found in file: @uedges " << name;
1923 throw IoParameterError(msg.message());
1930 typedef std::map<std::string,
1931 _reader_bits::ItemStore<UEdge> > UEdgeReaders;
1932 UEdgeReaders uedgeReaders;
1933 std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uedgeLabelReader;
1935 typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
1936 EdgeReaders edgeReaders;
1937 std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
1940 /// \ingroup section_io
1941 /// \brief SectionReader for attributes.
1943 /// The lemon format can store multiple attribute set. Each set has
1944 /// the header line \c \@attributes \c attributeset_name, but the
1945 /// attributeset_name may be empty.
1947 /// The attributeset section contains several lines. Each of them starts
1948 /// with an attribute and then a the value for the id.
1950 /// \relates LemonReader
1951 template <typename _Traits = DefaultReaderTraits>
1952 class AttributeReader : public LemonReader::SectionReader {
1953 typedef LemonReader::SectionReader Parent;
1954 typedef _Traits Traits;
1956 /// \brief Constructor.
1958 /// Constructor for AttributeReader. It creates the AttributeReader and
1959 /// attach it into the given LemonReader. The reader process a section
1960 /// only if the \c section_name and the \c _name are the same.
1961 AttributeReader(LemonReader& _reader,
1962 const std::string& _name = std::string())
1963 : Parent(_reader), name(_name) {}
1965 /// \brief Destructor.
1967 /// Destructor for AttributeReader.
1968 virtual ~AttributeReader() {
1969 for (typename Readers::iterator it = readers.begin();
1970 it != readers.end(); ++it) {
1976 AttributeReader(const AttributeReader&);
1977 void operator=(AttributeReader&);
1980 /// \brief Add an attribute reader command for the reader.
1982 /// Add an attribute reader command for the reader.
1983 template <typename Value>
1984 AttributeReader& readAttribute(const std::string& label, Value& value) {
1985 return readAttribute<typename Traits::template Reader<Value> >
1989 /// \brief Add an attribute reader command for the reader.
1991 /// Add an attribute reader command for the reader.
1992 template <typename ItemReader, typename Value>
1993 AttributeReader& readAttribute(const std::string& label, Value& value,
1994 const ItemReader& ir = ItemReader()) {
1995 checkConcept<_reader_bits::ItemReader<Value>, ItemReader>();
1996 if (readers.find(label) != readers.end()) {
1998 msg << "Multiple read rule for attribute: " << label;
1999 throw IoParameterError(msg.message());
2001 readers.insert(make_pair(label, new _reader_bits::
2002 ValueReader<Value, ItemReader>(value, ir)));
2008 /// \brief Gives back true when the SectionReader can process
2009 /// the section with the given header line.
2011 /// It gives back true when the header line start with \c \@attributes,
2012 /// and the header line's id and the attributeset's id are the same.
2013 bool header(const std::string& line) {
2014 std::istringstream ls(line);
2015 std::string command;
2017 ls >> command >> id;
2018 return command == "@attributes" && name == id;
2021 /// \brief Reader function of the section.
2023 /// It reads the content of the section.
2024 void read(std::istream& is) {
2026 while (getline(is, line)) {
2027 std::istringstream ls(line);
2030 typename Readers::iterator it = readers.find(id);
2031 if (it != readers.end()) {
2032 it->second->read(ls);
2033 it->second->touch();
2036 for (typename Readers::iterator it = readers.begin();
2037 it != readers.end(); ++it) {
2038 if (!it->second->touched()) {
2040 msg << "Attribute not found in file: " << it->first;
2041 throw IoParameterError(msg.message());
2046 virtual void missing() {
2047 if (readers.empty()) return;
2049 msg << "Attribute section not found in file: @attributes " << name;
2050 throw IoParameterError(msg.message());
2056 typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
2060 /// \ingroup section_io
2061 /// \brief SectionReader for reading extra node maps.
2063 /// The lemon format can store maps in the nodeset sections. This
2064 /// class let you make distinict section to store maps. The main
2065 /// purpose of this class is a logical separation of some maps. The
2066 /// other useful application could be to store paths in node maps.
2068 /// The first line of the section contains the names of the maps
2069 /// separated with white spaces. Each next line describes an item
2070 /// in the itemset, and contains in the first column the label of
2071 /// the item and then the mapped values for each map.
2073 /// \relates LemonReader
2074 template <typename _Graph, typename _Traits = DefaultReaderTraits>
2075 class NodeMapReader : public LemonReader::SectionReader {
2076 typedef LemonReader::SectionReader Parent;
2079 typedef _Graph Graph;
2080 typedef typename Graph::Node Node;
2081 typedef _Traits Traits;
2082 typedef typename Traits::Skipper DefaultSkipper;
2084 /// \brief Constructor.
2086 /// Constructor for NodeMapReader. It creates the NodeMapReader and
2087 /// attach it into the given LemonReader. The reader will read
2088 /// the section when the \c section_name and the \c _name are the same.
2089 template <typename _LabelReader>
2090 NodeMapReader(LemonReader& _reader,
2091 const Graph& _graph,
2092 const _LabelReader& _labelReader,
2093 const std::string& _name = std::string(),
2094 const DefaultSkipper& _skipper = DefaultSkipper())
2095 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
2096 labelReader.reset(new _reader_bits::
2097 LabelReader<Node, _LabelReader>(_labelReader));
2101 /// \brief Destructor.
2103 /// Destructor for NodeMapReader.
2104 virtual ~NodeMapReader() {
2105 for (typename MapReaders::iterator it = readers.begin();
2106 it != readers.end(); ++it) {
2112 NodeMapReader(const NodeMapReader&);
2113 void operator=(const NodeMapReader&);
2117 /// \brief Add a new node map reader command for the reader.
2119 /// Add a new node map reader command for the reader.
2120 template <typename Map>
2121 NodeMapReader& readNodeMap(std::string label, Map& map) {
2123 typename Traits::template Reader<typename Map::Value>, Map,
2124 typename _reader_bits::Arg<Map>::Type>(label, map);
2127 template <typename Map>
2128 NodeMapReader& readNodeMap(std::string label, const Map& map) {
2130 typename Traits::template Reader<typename Map::Value>, Map,
2131 typename _reader_bits::Arg<Map>::Type>(label, map);
2134 /// \brief Add a new node map reader command for the reader.
2136 /// Add a new node map reader command for the reader.
2137 template <typename ItemReader, typename Map>
2138 NodeMapReader& readNodeMap(std::string label, Map& map,
2139 const ItemReader& ir = ItemReader()) {
2140 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
2144 template <typename ItemReader, typename Map>
2145 NodeMapReader& readNodeMap(std::string label, const Map& map,
2146 const ItemReader& ir = ItemReader()) {
2147 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
2153 template <typename ItemReader, typename Map, typename MapParameter>
2154 NodeMapReader& _readMap(std::string label, MapParameter map,
2155 const ItemReader& ir = ItemReader()) {
2156 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
2157 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
2158 if (readers.find(label) != readers.end()) {
2160 msg << "Multiple read rule for map: " << label;
2161 throw IoParameterError(msg.message());
2164 make_pair(label, new _reader_bits::
2165 MapReader<Node, Map, ItemReader>(map, ir)));
2171 /// \brief Add a new node map skipper command for the reader.
2173 /// Add a new node map skipper command for the reader.
2174 template <typename ItemReader>
2175 NodeMapReader& skipNodeMap(std::string label,
2176 const ItemReader& ir = ItemReader()) {
2177 if (readers.find(label) != readers.end()) {
2179 msg << "Multiple read rule for map: " << label;
2180 throw IoParameterError(msg.message());
2182 readers.insert(make_pair(label, new _reader_bits::
2183 SkipReader<Node, ItemReader>(ir)));
2189 /// \brief Gives back true when the SectionReader can process
2190 /// the section with the given header line.
2192 /// It gives back true when the header line starts with \c \@mapset,
2193 /// and the header line's name and the mapset's name are the same.
2194 virtual bool header(const std::string& line) {
2195 std::istringstream ls(line);
2196 std::string command;
2198 ls >> command >> id;
2199 return command == "@nodemaps" && name == id;
2202 /// \brief Reader function of the section.
2204 /// It reads the content of the section.
2205 virtual void read(std::istream& is) {
2206 std::vector<_reader_bits::MapReaderBase<Node>* > index;
2211 std::istringstream ls(line);
2214 typename MapReaders::iterator it = readers.find(id);
2215 if (it != readers.end()) {
2216 it->second->touch();
2217 index.push_back(it->second);
2219 index.push_back(&skipper);
2223 for (typename MapReaders::iterator it = readers.begin();
2224 it != readers.end(); ++it) {
2225 if (!it->second->touched()) {
2227 msg << "Map not found in file: " << it->first;
2228 throw IoParameterError(msg.message());
2231 while (getline(is, line)) {
2232 std::istringstream ls(line);
2233 Node node = labelReader->read(ls);
2234 for (int i = 0; i < int(index.size()); ++i) {
2235 index[i]->read(ls, node);
2240 virtual void missing() {
2241 if (readers.empty()) return;
2243 msg << "NodeMap section not found in file: @nodemaps " << name;
2244 throw IoParameterError(msg.message());
2249 typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
2254 _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
2255 std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader;
2259 /// \ingroup section_io
2260 /// \brief SectionReader for reading extra edge maps.
2262 /// The lemon format can store maps in the edgeset sections. This
2263 /// class let you make distinict section to store maps. The main
2264 /// purpose of this class is a logical separation of some maps. The
2265 /// other useful application could be to store paths in edge maps.
2267 /// The first line of the section contains the names of the maps
2268 /// separated with white spaces. Each next line describes an item
2269 /// in the itemset, and contains in the first column the label of
2270 /// the item and then the mapped values for each map.
2272 /// \relates LemonReader
2273 template <typename _Graph, typename _Traits = DefaultReaderTraits>
2274 class EdgeMapReader : public LemonReader::SectionReader {
2275 typedef LemonReader::SectionReader Parent;
2278 typedef _Graph Graph;
2279 typedef typename Graph::Edge Edge;
2280 typedef _Traits Traits;
2281 typedef typename Traits::Skipper DefaultSkipper;
2283 /// \brief Constructor.
2285 /// Constructor for EdgeMapReader. It creates the EdgeMapReader and
2286 /// attach it into the given LemonReader. The reader will read
2287 /// the section when the \c section_name and the \c _name are the same.
2288 template <typename _LabelReader>
2289 EdgeMapReader(LemonReader& _reader,
2290 const Graph& _graph,
2291 const _LabelReader& _labelReader,
2292 const std::string& _name = std::string(),
2293 const DefaultSkipper& _skipper = DefaultSkipper())
2294 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
2295 labelReader.reset(new _reader_bits::
2296 LabelReader<Edge, _LabelReader>(_labelReader));
2300 /// \brief Destructor.
2302 /// Destructor for EdgeMapReader.
2303 virtual ~EdgeMapReader() {
2304 for (typename MapReaders::iterator it = readers.begin();
2305 it != readers.end(); ++it) {
2311 EdgeMapReader(const EdgeMapReader&);
2312 void operator=(const EdgeMapReader&);
2316 /// \brief Add a new edge map reader command for the reader.
2318 /// Add a new edge map reader command for the reader.
2319 template <typename Map>
2320 EdgeMapReader& readEdgeMap(std::string label, Map& map) {
2322 typename Traits::template Reader<typename Map::Value>, Map,
2323 typename _reader_bits::Arg<Map>::Type>(label, map);
2326 template <typename Map>
2327 EdgeMapReader& readEdgeMap(std::string label, const Map& map) {
2329 typename Traits::template Reader<typename Map::Value>, Map,
2330 typename _reader_bits::Arg<Map>::Type>(label, map);
2333 /// \brief Add a new edge map reader command for the reader.
2335 /// Add a new edge map reader command for the reader.
2336 template <typename ItemReader, typename Map>
2337 EdgeMapReader& readEdgeMap(std::string label, Map& map,
2338 const ItemReader& ir = ItemReader()) {
2339 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
2343 template <typename ItemReader, typename Map>
2344 EdgeMapReader& readEdgeMap(std::string label, const Map& map,
2345 const ItemReader& ir = ItemReader()) {
2346 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
2352 template <typename ItemReader, typename Map, typename MapParameter>
2353 EdgeMapReader& _readMap(std::string label, MapParameter map,
2354 const ItemReader& ir = ItemReader()) {
2355 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
2356 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
2357 if (readers.find(label) != readers.end()) {
2359 msg << "Multiple read rule for map: " << label;
2360 throw IoParameterError(msg.message());
2363 make_pair(label, new _reader_bits::
2364 MapReader<Edge, Map, ItemReader>(map, ir)));
2370 /// \brief Add a new edge map skipper command for the reader.
2372 /// Add a new edge map skipper command for the reader.
2373 template <typename ItemReader>
2374 EdgeMapReader& skipEdgeMap(std::string label,
2375 const ItemReader& ir = ItemReader()) {
2376 if (readers.find(label) != readers.end()) {
2378 msg << "Multiple read rule for map: " << label;
2379 throw IoParameterError(msg.message());
2381 readers.insert(make_pair(label, new _reader_bits::
2382 SkipReader<Edge, ItemReader>(ir)));
2388 /// \brief Gives back true when the SectionReader can process
2389 /// the section with the given header line.
2391 /// It gives back true when the header line starts with \c \@mapset,
2392 /// and the header line's name and the mapset's name are the same.
2393 virtual bool header(const std::string& line) {
2394 std::istringstream ls(line);
2395 std::string command;
2397 ls >> command >> id;
2398 return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
2401 /// \brief Reader function of the section.
2403 /// It reads the content of the section.
2404 virtual void read(std::istream& is) {
2405 std::vector<_reader_bits::MapReaderBase<Edge>* > index;
2410 std::istringstream ls(line);
2413 typename MapReaders::iterator it = readers.find(id);
2414 if (it != readers.end()) {
2415 it->second->touch();
2416 index.push_back(it->second);
2418 index.push_back(&skipper);
2422 for (typename MapReaders::iterator it = readers.begin();
2423 it != readers.end(); ++it) {
2424 if (!it->second->touched()) {
2426 msg << "Map not found in file: " << it->first;
2427 throw IoParameterError(msg.message());
2430 while (getline(is, line)) {
2431 std::istringstream ls(line);
2432 Edge edge = labelReader->read(ls);
2433 for (int i = 0; i < int(index.size()); ++i) {
2434 index[i]->read(ls, edge);
2439 virtual void missing() {
2440 if (readers.empty()) return;
2442 msg << "EdgeMap section not found in file: @edgemaps " << name;
2443 throw IoParameterError(msg.message());
2448 typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
2453 _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
2454 std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader;
2458 /// \ingroup section_io
2459 /// \brief SectionReader for reading extra undirected edge maps.
2461 /// The lemon format can store maps in the uedgeset sections. This
2462 /// class let you make distinict section to store maps. The main
2463 /// purpose of this class is a logical separation of some maps. The
2464 /// other useful application could be to store paths in undirected
2467 /// The first line of the section contains the names of the maps
2468 /// separated with white spaces. Each next line describes an item
2469 /// in the itemset, and contains in the first column the label of
2470 /// the item and then the mapped values for each map.
2472 /// \relates LemonReader
2473 template <typename _Graph, typename _Traits = DefaultReaderTraits>
2474 class UEdgeMapReader : public LemonReader::SectionReader {
2475 typedef LemonReader::SectionReader Parent;
2478 typedef _Graph Graph;
2479 typedef typename Graph::Edge Edge;
2480 typedef typename Graph::UEdge UEdge;
2481 typedef _Traits Traits;
2482 typedef typename Traits::Skipper DefaultSkipper;
2484 /// \brief Constructor.
2486 /// Constructor for UEdgeMapReader. It creates the UEdgeMapReader and
2487 /// attach it into the given LemonReader. The reader will read
2488 /// the section when the \c section_name and the \c _name are the same.
2489 template <typename _LabelReader>
2490 UEdgeMapReader(LemonReader& _reader, const Graph& _graph,
2491 const _LabelReader& _labelReader,
2492 const std::string& _name = std::string(),
2493 const DefaultSkipper& _skipper = DefaultSkipper())
2494 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
2495 labelReader.reset(new _reader_bits::
2496 LabelReader<UEdge, _LabelReader>(_labelReader));
2500 /// \brief Destructor.
2502 /// Destructor for UEdgeMapReader.
2503 virtual ~UEdgeMapReader() {
2504 for (typename MapReaders::iterator it = readers.begin();
2505 it != readers.end(); ++it) {
2511 UEdgeMapReader(const UEdgeMapReader&);
2512 void operator=(const UEdgeMapReader&);
2516 /// \brief Add a new undirected edge map reader command for the
2519 /// Add a new undirected edge map reader command for the reader.
2520 template <typename Map>
2521 UEdgeMapReader& readUEdgeMap(std::string label, Map& map) {
2523 typename Traits::template Reader<typename Map::Value>, Map,
2524 typename _reader_bits::Arg<Map>::Type>(label, map);
2527 template <typename Map>
2528 UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) {
2530 typename Traits::template Reader<typename Map::Value>, Map,
2531 typename _reader_bits::Arg<Map>::Type>(label, map);
2534 /// \brief Add a new undirected edge map reader command for the
2537 /// Add a new undirected edge map reader command for the reader.
2538 template <typename ItemReader, typename Map>
2539 UEdgeMapReader& readUEdgeMap(std::string label, Map& map,
2540 const ItemReader& ir = ItemReader()) {
2541 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
2545 template <typename ItemReader, typename Map>
2546 UEdgeMapReader& readUEdgeMap(std::string label, const Map& map,
2547 const ItemReader& ir = ItemReader()) {
2548 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
2554 template <typename ItemReader, typename Map, typename MapParameter>
2555 UEdgeMapReader& _readMap(std::string label, MapParameter map,
2556 const ItemReader& ir = ItemReader()) {
2557 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
2558 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
2559 if (readers.find(label) != readers.end()) {
2561 msg << "Multiple read rule for map: " << label;
2562 throw IoParameterError(msg.message());
2565 make_pair(label, new _reader_bits::
2566 MapReader<UEdge, Map, ItemReader>(map, ir)));
2572 /// \brief Add a new undirected edge map skipper command for the
2575 /// Add a new undirected edge map skipper command for the reader.
2576 template <typename ItemReader>
2577 UEdgeMapReader& skipUEdgeMap(std::string label,
2578 const ItemReader& ir = ItemReader()) {
2579 if (readers.find(label) != readers.end()) {
2581 msg << "Multiple read rule for map: " << label;
2582 throw IoParameterError(msg.message());
2584 readers.insert(make_pair(label, new _reader_bits::
2585 SkipReader<Edge, ItemReader>(ir)));
2589 /// \brief Add a new directed edge map reader command for the reader.
2591 /// Add a new directed edge map reader command for the reader.
2592 template <typename Map>
2593 UEdgeMapReader& readEdgeMap(std::string label, Map& map) {
2595 typename Traits::template Reader<typename Map::Value>, Map,
2596 typename _reader_bits::Arg<Map>::Type>(label, map);
2599 template <typename Map>
2600 UEdgeMapReader& readEdgeMap(std::string label, const Map& map) {
2602 typename Traits::template Reader<typename Map::Value>, Map,
2603 typename _reader_bits::Arg<Map>::Type>(label, map);
2606 /// \brief Add a new directed edge map reader command for the reader.
2608 /// Add a new directed edge map reader command for the reader.
2609 template <typename ItemReader, typename Map>
2610 UEdgeMapReader& readEdgeMap(std::string label, Map& map,
2611 const ItemReader& ir = ItemReader()) {
2612 return _readDirMap<ItemReader, Map,
2613 typename _reader_bits::Arg<Map>::Type>(label, map, ir);
2616 template <typename ItemReader, typename Map>
2617 UEdgeMapReader& readEdgeMap(std::string label, const Map& map,
2618 const ItemReader& ir = ItemReader()) {
2619 return _readDirMap<ItemReader, Map,
2620 typename _reader_bits::Arg<Map>::Type>(label, map, ir);
2625 template <typename ItemReader, typename Map, typename MapParameter>
2626 UEdgeMapReader& _readDirMap(std::string label, MapParameter map,
2627 const ItemReader& ir = ItemReader()) {
2628 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
2629 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
2630 readUEdgeMap("+" + label,
2631 _reader_bits::forwardComposeMap(graph, map), ir);
2632 readUEdgeMap("-" + label,
2633 _reader_bits::backwardComposeMap(graph, map), ir);
2639 /// \brief Add a new directed edge map skipper command for the reader.
2641 /// Add a new directed edge map skipper command for the reader.
2642 template <typename ItemReader>
2643 UEdgeMapReader& skipEdgeMap(std::string label,
2644 const ItemReader& ir = ItemReader()) {
2645 skipUEdgeMap("+" + label, ir);
2646 skipUEdgeMap("-" + label, ir);
2652 /// \brief Gives back true when the SectionReader can process
2653 /// the section with the given header line.
2655 /// It gives back true when the header line starts with \c \@mapset,
2656 /// and the header line's name and the mapset's name are the same.
2657 virtual bool header(const std::string& line) {
2658 std::istringstream ls(line);
2659 std::string command;
2661 ls >> command >> id;
2662 return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
2665 /// \brief Reader function of the section.
2667 /// It reads the content of the section.
2668 virtual void read(std::istream& is) {
2669 std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
2674 std::istringstream ls(line);
2677 typename MapReaders::iterator it = readers.find(id);
2678 if (it != readers.end()) {
2679 it->second->touch();
2680 index.push_back(it->second);
2682 index.push_back(&skipper);
2686 for (typename MapReaders::iterator it = readers.begin();
2687 it != readers.end(); ++it) {
2688 if (!it->second->touched()) {
2690 msg << "Map not found in file: " << it->first;
2691 throw IoParameterError(msg.message());
2694 while (getline(is, line)) {
2695 std::istringstream ls(line);
2696 UEdge uedge = labelReader->read(ls);
2697 for (int i = 0; i < int(index.size()); ++i) {
2698 index[i]->read(ls, uedge);
2703 virtual void missing() {
2704 if (readers.empty()) return;
2706 msg << "UEdgeMap section not found in file: @uedgemaps " << name;
2707 throw IoParameterError(msg.message());
2715 typedef std::map<std::string,
2716 _reader_bits::MapReaderBase<UEdge>*> MapReaders;
2719 _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
2721 std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader;
2725 /// \ingroup section_io
2726 /// \brief SectionReader for retrieve what is in the file.
2728 /// SectionReader for retrieve what is in the file. If you want
2729 /// to know which sections, maps and items are in the file
2730 /// use the next code:
2732 /// LemonReader reader("input.lgf");
2733 /// ContentReader content(reader);
2736 class ContentReader : public LemonReader::SectionReader {
2737 typedef LemonReader::SectionReader Parent;
2739 /// \brief Constructor.
2742 ContentReader(LemonReader& _reader) : Parent(_reader) {}
2744 /// \brief Desctructor.
2747 virtual ~ContentReader() {}
2749 /// \brief Gives back how many nodesets are in the file.
2751 /// Gives back how many nodesets are in the file.
2752 int nodeSetNum() const {
2753 return nodesets.size();
2756 /// \brief Gives back the name of nodeset on the indiced position.
2758 /// Gives back the name of nodeset on the indiced position.
2759 std::string nodeSetName(int index) const {
2760 return nodesets[index].name;
2763 /// \brief Gives back the map names of nodeset on the indiced position.
2765 /// Gives back the map names of nodeset on the indiced position.
2766 const std::vector<std::string>& nodeSetMaps(int index) const {
2767 return nodesets[index].items;
2770 /// \brief Gives back how many edgesets are in the file.
2772 /// Gives back how many edgesets are in the file.
2773 int edgeSetNum() const {
2774 return edgesets.size();
2777 /// \brief Gives back the name of edgeset on the indiced position.
2779 /// Gives back the name of edgeset on the indiced position.
2780 std::string edgeSetName(int index) const {
2781 return edgesets[index].name;
2784 /// \brief Gives back the map names of edgeset on the indiced position.
2786 /// Gives back the map names of edgeset on the indiced position.
2787 const std::vector<std::string>& edgeSetMaps(int index) const {
2788 return edgesets[index].items;
2791 /// \brief Gives back how many undirected edgesets are in the file.
2793 /// Gives back how many undirected edgesets are in the file.
2794 int uEdgeSetNum() const {
2795 return uedgesets.size();
2798 /// \brief Gives back the name of undirected edgeset on the indiced
2801 /// Gives back the name of undirected edgeset on the indiced position.
2802 std::string uEdgeSetName(int index) const {
2803 return uedgesets[index].name;
2806 /// \brief Gives back the map names of undirected edgeset on the indiced
2809 /// Gives back the map names of undirected edgeset on the indiced position.
2810 const std::vector<std::string>& uEdgeSetMaps(int index) const {
2811 return uedgesets[index].items;
2814 /// \brief Gives back how many labeled nodes section are in the file.
2816 /// Gives back how many labeled nodes section are in the file.
2817 int nodesNum() const {
2818 return nodes.size();
2821 /// \brief Gives back the name of labeled nodes section on the indiced
2824 /// Gives back the name of labeled nodes section on the indiced position.
2825 std::string nodesName(int index) const {
2826 return nodes[index].name;
2829 /// \brief Gives back the names of the labeled nodes in the indiced
2832 /// Gives back the names of the labeled nodes in the indiced section.
2833 const std::vector<std::string>& nodesItems(int index) const {
2834 return nodes[index].items;
2837 /// \brief Gives back how many labeled edges section are in the file.
2839 /// Gives back how many labeled edges section are in the file.
2840 int edgesNum() const {
2841 return edges.size();
2844 /// \brief Gives back the name of labeled edges section on the indiced
2847 /// Gives back the name of labeled edges section on the indiced position.
2848 std::string edgesName(int index) const {
2849 return edges[index].name;
2852 /// \brief Gives back the names of the labeled edges in the indiced
2855 /// Gives back the names of the labeled edges in the indiced section.
2856 const std::vector<std::string>& edgesItems(int index) const {
2857 return edges[index].items;
2860 /// \brief Gives back how many labeled undirected edges section are
2863 /// Gives back how many labeled undirected edges section are in the file.
2864 int uEdgesNum() const {
2865 return uedges.size();
2868 /// \brief Gives back the name of labeled undirected edges section
2869 /// on the indiced position.
2871 /// Gives back the name of labeled undirected edges section on the
2872 /// indiced position.
2873 std::string uEdgesName(int index) const {
2874 return uedges[index].name;
2877 /// \brief Gives back the names of the labeled undirected edges in
2878 /// the indiced section.
2880 /// Gives back the names of the labeled undirected edges in the
2881 /// indiced section.
2882 const std::vector<std::string>& uEdgesItems(int index) const {
2883 return uedges[index].items;
2887 /// \brief Gives back how many attributes section are in the file.
2889 /// Gives back how many attributes section are in the file.
2890 int attributesNum() const {
2891 return attributes.size();
2894 /// \brief Gives back the name of attributes section on the indiced
2897 /// Gives back the name of attributes section on the indiced position.
2898 std::string attributesName(int index) const {
2899 return attributes[index].name;
2902 /// \brief Gives back the names of the attributes in the indiced section.
2904 /// Gives back the names of the attributes in the indiced section.
2905 const std::vector<std::string>& attributesItems(int index) const {
2906 return attributes[index].items;
2909 const std::vector<std::string>& otherSections() const {
2915 /// \brief Gives back true when the SectionReader can process
2916 /// the section with the given header line.
2918 /// It gives back true when the section is common section.
2919 bool header(const std::string& line) {
2920 std::istringstream ls(line);
2921 std::string command, name;
2922 ls >> command >> name;
2923 if (command == "@nodeset") {
2925 nodesets.push_back(SectionInfo(name));
2926 } else if (command == "@edgeset") {
2928 edgesets.push_back(SectionInfo(name));
2929 } else if (command == "@uedgeset") {
2931 uedgesets.push_back(SectionInfo(name));
2932 } else if (command == "@nodes") {
2934 nodes.push_back(SectionInfo(name));
2935 } else if (command == "@edges") {
2937 edges.push_back(SectionInfo(name));
2938 } else if (command == "@uedges") {
2940 uedges.push_back(SectionInfo(name));
2941 } else if (command == "@attributes") {
2943 attributes.push_back(SectionInfo(name));
2945 sections.push_back(line);
2951 /// \brief Retrieve the items from various sections.
2953 /// Retrieve the items from various sections.
2954 void read(std::istream& is) {
2955 if (current == "@nodeset") {
2956 readMapNames(is, nodesets.back().items);
2957 } else if (current == "@edgeset") {
2958 readMapNames(is, edgesets.back().items);
2959 } else if (current == "@uedgeset") {
2960 readMapNames(is, uedgesets.back().items);
2961 } else if (current == "@nodes") {
2962 readItemNames(is, nodes.back().items);
2963 } else if (current == "@edges") {
2964 readItemNames(is, edges.back().items);
2965 } else if (current == "@uedges") {
2966 readItemNames(is, uedges.back().items);
2967 } else if (current == "@attributes") {
2968 readItemNames(is, attributes.back().items);
2974 void readMapNames(std::istream& is, std::vector<std::string>& maps) {
2975 std::string line, name;
2976 std::getline(is, line);
2977 std::istringstream ls(line);
2978 while (ls >> name) {
2979 maps.push_back(name);
2981 while (getline(is, line));
2984 void readItemNames(std::istream& is, std::vector<std::string>& maps) {
2985 std::string line, name;
2986 while (std::getline(is, line)) {
2987 std::istringstream ls(line);
2989 maps.push_back(name);
2993 struct SectionInfo {
2995 std::vector<std::string> items;
2997 SectionInfo(const std::string& _name) : name(_name) {}
3000 std::vector<SectionInfo> nodesets;
3001 std::vector<SectionInfo> edgesets;
3002 std::vector<SectionInfo> uedgesets;
3004 std::vector<SectionInfo> nodes;
3005 std::vector<SectionInfo> edges;
3006 std::vector<SectionInfo> uedges;
3008 std::vector<SectionInfo> attributes;
3010 std::vector<std::string> sections;
3012 std::string current;