lemon/lemon_reader.h
changeset 1903 f3d24016dad5
parent 1875 98698b69a902
child 1909 2d806130e700
equal deleted inserted replaced
11:9f7876c449c6 12:028ac22cb3c4
    45 
    45 
    46   namespace _reader_bits {
    46   namespace _reader_bits {
    47 
    47 
    48     template <typename T>
    48     template <typename T>
    49     bool operator<(T, T) {
    49     bool operator<(T, T) {
    50       throw DataFormatError("Id is not comparable");
    50       throw DataFormatError("Label is not comparable");
    51     }
    51     }
    52 
    52 
    53     template <typename T>
    53     template <typename T>
    54     struct Less {
    54     struct Less {
    55       bool operator()(const T& p, const T& q) const {
    55       bool operator()(const T& p, const T& q) const {
    56 	return p < q;
    56 	return p < q;
    57       }
    57       }
    58     };
    58     };
    59 
    59 
    60     template <typename Item>
    60     template <typename Item>
    61     class ItemIdReader {
    61     class ItemLabelReader {
    62     public:
    62     public:
    63 
    63 
    64       bool isIdReader() { return true; }
    64       bool isLabelReader() { return true; }
    65 
    65 
    66       void readId(std::istream&, Item&) {}
    66       void readLabel(std::istream&, Item&) {}
    67       
    67       
    68       template <class _ItemIdReader>
    68       template <class _ItemLabelReader>
    69       struct Constraints {
    69       struct Constraints {
    70 	void constraints() {
    70 	void constraints() {
    71 	  bool b = reader.isIdReader();
    71 	  bool b = reader.isLabelReader();
    72 	  ignore_unused_variable_warning(b);
    72 	  ignore_unused_variable_warning(b);
    73 	  Item item;
    73 	  Item item;
    74 	  reader.readId(is, item);
    74 	  reader.readLabel(is, item);
    75 	}
    75 	}
    76 	_ItemIdReader& reader;
    76 	_ItemLabelReader& reader;
    77 	std::istream& is;
    77 	std::istream& is;
    78       };
    78       };
    79 
    79 
    80     };
    80     };
    81 
    81 
   239 	map.set(item, value);
   239 	map.set(item, value);
   240 	typename Inverse::iterator it = inverse.find(value);
   240 	typename Inverse::iterator it = inverse.find(value);
   241 	if (it == inverse.end()) {
   241 	if (it == inverse.end()) {
   242 	  inverse.insert(std::make_pair(value, item));
   242 	  inverse.insert(std::make_pair(value, item));
   243 	} else {
   243 	} else {
   244 	  throw DataFormatError("Multiple ID occurence");
   244 	  throw DataFormatError("Multiple label occurence");
   245 	}
   245 	}
   246       }
   246       }
   247 
   247 
   248       virtual Item read(std::istream& is) const {
   248       virtual Item read(std::istream& is) const {
   249 	Value value;
   249 	Value value;
   250 	reader.read(is, value);	
   250 	reader.read(is, value);	
   251 	typename Inverse::const_iterator it = inverse.find(value);
   251 	typename Inverse::const_iterator it = inverse.find(value);
   252 	if (it != inverse.end()) {
   252 	if (it != inverse.end()) {
   253 	  return it->second;
   253 	  return it->second;
   254 	} else {
   254 	} else {
   255 	  throw DataFormatError("Invalid ID error");
   255 	  throw DataFormatError("Invalid label error");
   256 	}
   256 	}
   257       }      
   257       }      
   258     };
   258     };
   259 
   259 
   260     template <typename _Item, typename _Reader>
   260     template <typename _Item, typename _Reader>
   277 	reader.read(is, value);
   277 	reader.read(is, value);
   278 	typename Inverse::iterator it = inverse.find(value);
   278 	typename Inverse::iterator it = inverse.find(value);
   279 	if (it == inverse.end()) {
   279 	if (it == inverse.end()) {
   280 	  inverse.insert(std::make_pair(value, item));
   280 	  inverse.insert(std::make_pair(value, item));
   281 	} else {
   281 	} else {
   282 	  throw DataFormatError("Multiple ID occurence error");
   282 	  throw DataFormatError("Multiple label occurence error");
   283 	}
   283 	}
   284       }
   284       }
   285 
   285 
   286       virtual Item read(std::istream& is) const {
   286       virtual Item read(std::istream& is) const {
   287 	Value value;
   287 	Value value;
   288 	reader.read(is, value);	
   288 	reader.read(is, value);	
   289 	typename Inverse::const_iterator it = inverse.find(value);
   289 	typename Inverse::const_iterator it = inverse.find(value);
   290 	if (it != inverse.end()) {
   290 	if (it != inverse.end()) {
   291 	  return it->second;
   291 	  return it->second;
   292 	} else {
   292 	} else {
   293 	  throw DataFormatError("Invalid ID error");
   293 	  throw DataFormatError("Invalid label error");
   294 	}
   294 	}
   295       }
   295       }
   296 
   296 
   297     private:
   297     private:
   298       Inverse inverse;
   298       Inverse inverse;
   368 	return new SkipReaderInverter<Item, Reader>(reader);
   368 	return new SkipReaderInverter<Item, Reader>(reader);
   369       }
   369       }
   370     };
   370     };
   371 
   371 
   372     template <typename _Item>
   372     template <typename _Item>
   373     class IdReaderBase {
   373     class LabelReaderBase {
   374     public:
   374     public:
   375       typedef _Item Item;
   375       typedef _Item Item;
   376       virtual ~IdReaderBase() {}
   376       virtual ~LabelReaderBase() {}
   377       virtual Item read(std::istream& is) const = 0;
   377       virtual Item read(std::istream& is) const = 0;
   378       virtual bool isIdReader() const = 0;
   378       virtual bool isLabelReader() const = 0;
   379     };
   379     };
   380 
   380 
   381     template <typename _Item, typename _BoxedIdReader>
   381     template <typename _Item, typename _BoxedLabelReader>
   382     class IdReader : public IdReaderBase<_Item> {
   382     class LabelReader : public LabelReaderBase<_Item> {
   383     public:
   383     public:
   384       typedef _Item Item;
   384       typedef _Item Item;
   385       typedef _BoxedIdReader BoxedIdReader;
   385       typedef _BoxedLabelReader BoxedLabelReader;
   386       
   386       
   387       const BoxedIdReader& boxedIdReader;
   387       const BoxedLabelReader& boxedLabelReader;
   388 
   388 
   389       IdReader(const BoxedIdReader& _boxedIdReader) 
   389       LabelReader(const BoxedLabelReader& _boxedLabelReader) 
   390 	: boxedIdReader(_boxedIdReader) {}
   390 	: boxedLabelReader(_boxedLabelReader) {}
   391 
   391 
   392       virtual Item read(std::istream& is) const {
   392       virtual Item read(std::istream& is) const {
   393 	Item item;
   393 	Item item;
   394 	boxedIdReader.readId(is, item);
   394 	boxedLabelReader.readLabel(is, item);
   395 	return item;
   395 	return item;
   396       }
   396       }
   397 
   397 
   398       virtual bool isIdReader() const {
   398       virtual bool isLabelReader() const {
   399 	return boxedIdReader.isIdReader();
   399 	return boxedLabelReader.isLabelReader();
   400       }
   400       }
   401     };
   401     };
   402 
   402 
   403     template <typename _Item>
   403     template <typename _Item>
   404     class ItemStore {
   404     class ItemStore {
   725 
   725 
   726   /// \ingroup io_group
   726   /// \ingroup io_group
   727   /// \brief SectionReader for reading a graph's nodeset.
   727   /// \brief SectionReader for reading a graph's nodeset.
   728   ///
   728   ///
   729   /// The lemon format can store multiple graph nodesets with several maps.
   729   /// The lemon format can store multiple graph nodesets with several maps.
   730   /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
   730   /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but the
   731   /// \c nodeset_id may be empty.
   731   /// \c nodeset_name may be empty.
   732   ///
   732   ///
   733   /// The first line of the section contains the names of the maps separated
   733   /// The first line of the section contains the names of the maps separated
   734   /// with white spaces. Each next lines describes a node in the nodeset, and
   734   /// with white spaces. Each next lines describes a node in the nodeset, and
   735   /// contains the mapped values for each map.
   735   /// contains the mapped values for each map.
   736   ///
   736   ///
   737   /// If the nodeset contains an \c "id" named map then it will be regarded
   737   /// If the nodeset contains an \c "label" named map then it will be regarded
   738   /// as id map. This map should contain only unique values and when the 
   738   /// as id map. This map should contain only unique values and when the 
   739   /// \c readId() member will read a value from the given stream it will
   739   /// \c readLabel() member will read a value from the given stream it will
   740   /// give back that node which is mapped to this value.
   740   /// give back that node which is mapped to this value.
   741   ///
   741   ///
   742   /// \relates LemonReader
   742   /// \relates LemonReader
   743   template <typename _Graph, typename _Traits = DefaultReaderTraits>
   743   template <typename _Graph, typename _Traits = DefaultReaderTraits>
   744   class NodeSetReader : public LemonReader::SectionReader {
   744   class NodeSetReader : public LemonReader::SectionReader {
   753     /// \brief Constructor.
   753     /// \brief Constructor.
   754     ///
   754     ///
   755     /// Constructor for NodeSetReader. It creates the NodeSetReader and
   755     /// Constructor for NodeSetReader. It creates the NodeSetReader and
   756     /// attach it into the given LemonReader. The nodeset reader will
   756     /// attach it into the given LemonReader. The nodeset reader will
   757     /// add the readed nodes to the given Graph. The reader will read
   757     /// add the readed nodes to the given Graph. The reader will read
   758     /// the section when the \c section_id and the \c _id are the same. 
   758     /// the section when the \c section_name and the \c _name are the same. 
   759     NodeSetReader(LemonReader& _reader, 
   759     NodeSetReader(LemonReader& _reader, 
   760 		  Graph& _graph, 
   760 		  Graph& _graph, 
   761 		  const std::string& _id = std::string(),
   761 		  const std::string& _name = std::string(),
   762 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   762 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   763       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {} 
   763       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {} 
   764 
   764 
   765 
   765 
   766     /// \brief Destructor.
   766     /// \brief Destructor.
   767     ///
   767     ///
   768     /// Destructor for NodeSetReader.
   768     /// Destructor for NodeSetReader.
   853 
   853 
   854     /// \brief Gives back true when the SectionReader can process 
   854     /// \brief Gives back true when the SectionReader can process 
   855     /// the section with the given header line.
   855     /// the section with the given header line.
   856     ///
   856     ///
   857     /// It gives back true when the header line starts with \c \@nodeset,
   857     /// It gives back true when the header line starts with \c \@nodeset,
   858     /// and the header line's id and the nodeset's id are the same.
   858     /// and the header line's name and the nodeset's name are the same.
   859     virtual bool header(const std::string& line) {
   859     virtual bool header(const std::string& line) {
   860       std::istringstream ls(line);
   860       std::istringstream ls(line);
   861       std::string command;
   861       std::string command;
   862       std::string name;
   862       std::string id;
   863       ls >> command >> name;
   863       ls >> command >> name;
   864       return command == "@nodeset" && name == id;
   864       return command == "@nodeset" && name == id;
   865     }
   865     }
   866 
   866 
   867     /// \brief Reader function of the section.
   867     /// \brief Reader function of the section.
   870     virtual void read(std::istream& is) {
   870     virtual void read(std::istream& is) {
   871       std::vector<_reader_bits::MapReaderBase<Node>* > index;
   871       std::vector<_reader_bits::MapReaderBase<Node>* > index;
   872       std::string line;
   872       std::string line;
   873 
   873 
   874       getline(is, line);
   874       getline(is, line);
   875       std::istringstream ls(line);	
   875       std::istringstream ls(line);
       
   876       std::string id;
   876       while (ls >> id) {
   877       while (ls >> id) {
   877 	typename MapReaders::iterator it = readers.find(id);
   878 	typename MapReaders::iterator it = readers.find(id);
   878 	if (it != readers.end()) {
   879 	if (it != readers.end()) {
   879 	  it->second->touch();
   880 	  it->second->touch();
   880 	  index.push_back(it->second);
   881 	  index.push_back(it->second);
   881 	} else {
   882 	} else {
   882 	  index.push_back(&skipper);
   883 	  index.push_back(&skipper);
   883 	}
   884 	}
   884 	if (id == "id" && inverter.get() == 0) {
   885 	if (id == "label" || (id =="id" && inverter.get() == 0)) {
   885 	  inverter.reset(index.back()->getInverter());
   886 	  inverter.reset(index.back()->getInverter());
   886 	  index.back() = inverter.get();
   887 	  index.back() = inverter.get();
   887 	}
   888 	}
   888       }
   889       }
   889       for (typename MapReaders::iterator it = readers.begin();
   890       for (typename MapReaders::iterator it = readers.begin();
   903       }
   904       }
   904     }
   905     }
   905 
   906 
   906   public:
   907   public:
   907 
   908 
   908     /// \brief Returns true if the nodeset can give back the node by its id.
   909     /// \brief Returns true if the nodeset can give back the node by its label.
   909     ///
   910     ///
   910     /// Returns true if the nodeset can give back the node by its id.
   911     /// Returns true if the nodeset can give back the node by its label.
   911     /// It is possible only if an "id" named map was read.
   912     /// It is possible only if an "label" named map was read.
   912     bool isIdReader() const {
   913     bool isLabelReader() const {
   913       return inverter.get() != 0;
   914       return inverter.get() != 0;
   914     }
   915     }
   915 
   916 
   916     /// \brief Gives back the node by its id.
   917     /// \brief Gives back the node by its label.
   917     ///
   918     ///
   918     /// It reads an id from the stream and gives back which node belongs to
   919     /// It reads an id from the stream and gives back which node belongs to
   919     /// it. It is possible only if there was read an "id" named map.
   920     /// it. It is possible only if there was read an "label" named map.
   920     void readId(std::istream& is, Node& node) const {
   921     void readLabel(std::istream& is, Node& node) const {
   921       node = inverter->read(is);
   922       node = inverter->read(is);
   922     } 
   923     } 
   923 
   924 
   924   private:
   925   private:
   925 
   926 
   926     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
   927     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
   927     MapReaders readers;
   928     MapReaders readers;
   928    
   929    
   929     Graph& graph;   
   930     Graph& graph;   
   930     std::string id;
   931     std::string name;
   931     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
   932     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
   932 
   933 
   933     std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
   934     std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
   934   };
   935   };
   935 
   936 
   936   /// \ingroup io_group
   937   /// \ingroup io_group
   937   /// \brief SectionReader for reading a graph's edgeset.
   938   /// \brief SectionReader for reading a graph's edgeset.
   938   ///
   939   ///
   939   /// The lemon format can store multiple graph edgesets with several maps.
   940   /// The lemon format can store multiple graph edgesets with several maps.
   940   /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
   941   /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but the
   941   /// \c edgeset_id may be empty.
   942   /// \c edgeset_name may be empty.
   942   ///
   943   ///
   943   /// The first line of the section contains the names of the maps separated
   944   /// The first line of the section contains the names of the maps separated
   944   /// with white spaces. Each next lines describes an edge in the edgeset. The
   945   /// with white spaces. Each next lines describes an edge in the edgeset. The
   945   /// line contains the source and the target nodes' id and the mapped 
   946   /// line contains the source and the target nodes' id and the mapped 
   946   /// values for each map.
   947   /// values for each map.
   947   ///
   948   ///
   948   /// If the edgeset contains an \c "id" named map then it will be regarded
   949   /// If the edgeset contains an \c "label" named map then it will be regarded
   949   /// as id map. This map should contain only unique values and when the 
   950   /// as id map. This map should contain only unique values and when the 
   950   /// \c readId() member will read a value from the given stream it will
   951   /// \c readLabel() member will read a value from the given stream it will
   951   /// give back that edge which is mapped to this value.
   952   /// give back that edge which is mapped to this value.
   952   ///
   953   ///
   953   /// The edgeset reader needs a node id reader to identify which nodes
   954   /// The edgeset reader needs a node id reader to identify which nodes
   954   /// have to be connected. If a NodeSetReader reads an "id" named map,
   955   /// have to be connected. If a NodeSetReader reads an "label" named map,
   955   /// it will be able to resolve the nodes by ids.
   956   /// it will be able to resolve the nodes by ids.
   956   ///
   957   ///
   957   /// \relates LemonReader
   958   /// \relates LemonReader
   958   template <typename _Graph, typename _Traits = DefaultReaderTraits>
   959   template <typename _Graph, typename _Traits = DefaultReaderTraits>
   959   class EdgeSetReader : public LemonReader::SectionReader {
   960   class EdgeSetReader : public LemonReader::SectionReader {
   970     ///
   971     ///
   971     /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
   972     /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
   972     /// attach it into the given LemonReader. The edgeset reader will
   973     /// attach it into the given LemonReader. The edgeset reader will
   973     /// add the readed edges to the given Graph. It will use the given
   974     /// add the readed edges to the given Graph. It will use the given
   974     /// node id reader to read the source and target nodes of the edges.
   975     /// node id reader to read the source and target nodes of the edges.
   975     /// The reader will read the section only if the \c _id and the 
   976     /// The reader will read the section only if the \c _name and the 
   976     /// \c edgset_id are the same. 
   977     /// \c edgset_name are the same. 
   977     template <typename NodeIdReader>
   978     template <typename NodeLabelReader>
   978     EdgeSetReader(LemonReader& _reader, 
   979     EdgeSetReader(LemonReader& _reader, 
   979 		  Graph& _graph, 
   980 		  Graph& _graph, 
   980 		  const NodeIdReader& _nodeIdReader, 
   981 		  const NodeLabelReader& _nodeLabelReader, 
   981 		  const std::string& _id = std::string(),
   982 		  const std::string& _name = std::string(),
   982 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   983 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   983       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
   984       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
   984       checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
   985       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
   985       nodeIdReader.reset(new _reader_bits::
   986       nodeLabelReader.reset(new _reader_bits::
   986 			 IdReader<Node, NodeIdReader>(_nodeIdReader));
   987 			 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
   987     }
   988     }
   988     /// \brief Destructor.
   989     /// \brief Destructor.
   989     ///
   990     ///
   990     /// Destructor for EdgeSetReader.
   991     /// Destructor for EdgeSetReader.
   991     virtual ~EdgeSetReader() {
   992     virtual ~EdgeSetReader() {
  1075 
  1076 
  1076     /// \brief Gives back true when the SectionReader can process 
  1077     /// \brief Gives back true when the SectionReader can process 
  1077     /// the section with the given header line.
  1078     /// the section with the given header line.
  1078     ///
  1079     ///
  1079     /// It gives back true when the header line starts with \c \@edgeset,
  1080     /// It gives back true when the header line starts with \c \@edgeset,
  1080     /// and the header line's id and the edgeset's id are the same.
  1081     /// and the header line's name and the edgeset's name are the same.
  1081     virtual bool header(const std::string& line) {
  1082     virtual bool header(const std::string& line) {
  1082       std::istringstream ls(line);
  1083       std::istringstream ls(line);
  1083       std::string command;
  1084       std::string command;
  1084       std::string name;
  1085       std::string id;
  1085       ls >> command >> name;
  1086       ls >> command >> name;
  1086       return command == "@edgeset" && name == id;
  1087       return command == "@edgeset" && name == id;
  1087     }
  1088     }
  1088 
  1089 
  1089     /// \brief Reader function of the section.
  1090     /// \brief Reader function of the section.
  1090     ///
  1091     ///
  1091     /// It reads the content of the section.
  1092     /// It reads the content of the section.
  1092     virtual void read(std::istream& is) {
  1093     virtual void read(std::istream& is) {
  1093       if (!nodeIdReader->isIdReader()) {
  1094       if (!nodeLabelReader->isLabelReader()) {
  1094 	throw DataFormatError("Cannot find nodeset or ID map");
  1095 	throw DataFormatError("Cannot find nodeset or label map");
  1095       }
  1096       }
  1096       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
  1097       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
  1097       std::string line;
  1098       std::string line;
  1098 
  1099 
  1099       getline(is, line);
  1100       getline(is, line);
  1100       std::istringstream ls(line);	
  1101       std::istringstream ls(line);	
       
  1102       std::string id;
  1101       while (ls >> id) {
  1103       while (ls >> id) {
  1102 	typename MapReaders::iterator it = readers.find(id);
  1104 	typename MapReaders::iterator it = readers.find(id);
  1103 	if (it != readers.end()) {
  1105 	if (it != readers.end()) {
  1104 	  index.push_back(it->second);
  1106 	  index.push_back(it->second);
  1105 	  it->second->touch();
  1107 	  it->second->touch();
  1106 	} else {
  1108 	} else {
  1107 	  index.push_back(&skipper);
  1109 	  index.push_back(&skipper);
  1108 	}
  1110 	}
  1109 	if (id == "id" && inverter.get() == 0) {
  1111 	if (id == "label" || (id =="id" && inverter.get() == 0)) {
  1110 	  inverter.reset(index.back()->getInverter());
  1112 	  inverter.reset(index.back()->getInverter());
  1111 	  index.back() = inverter.get();
  1113 	  index.back() = inverter.get();
  1112 	}
  1114 	}
  1113       }
  1115       }
  1114       for (typename MapReaders::iterator it = readers.begin();
  1116       for (typename MapReaders::iterator it = readers.begin();
  1119 	  throw IOParameterError(msg.message());
  1121 	  throw IOParameterError(msg.message());
  1120 	}
  1122 	}
  1121       }
  1123       }
  1122       while (getline(is, line)) {	
  1124       while (getline(is, line)) {	
  1123 	std::istringstream ls(line);
  1125 	std::istringstream ls(line);
  1124 	Node from = nodeIdReader->read(ls);
  1126 	Node from = nodeLabelReader->read(ls);
  1125 	Node to = nodeIdReader->read(ls);
  1127 	Node to = nodeLabelReader->read(ls);
  1126 	Edge edge = graph.addEdge(from, to);
  1128 	Edge edge = graph.addEdge(from, to);
  1127 	for (int i = 0; i < (int)index.size(); ++i) {
  1129 	for (int i = 0; i < (int)index.size(); ++i) {
  1128 	  index[i]->read(ls, edge);
  1130 	  index[i]->read(ls, edge);
  1129 	}
  1131 	}
  1130       }
  1132       }
  1131     }
  1133     }
  1132 
  1134 
  1133   public:
  1135   public:
  1134 
  1136 
  1135     /// \brief Returns true if the edgeset can give back the edge by its id.
  1137     /// \brief Returns true if the edgeset can give back the edge by its label.
  1136     ///
  1138     ///
  1137     /// Returns true if the edgeset can give back the edge by its id.
  1139     /// Returns true if the edgeset can give back the edge by its label.
  1138     /// It is possible only if an "id" named map was read.
  1140     /// It is possible only if an "label" named map was read.
  1139     bool isIdReader() const {
  1141     bool isLabelReader() const {
  1140       return inverter.get() != 0;
  1142       return inverter.get() != 0;
  1141     }
  1143     }
  1142 
  1144 
  1143     /// \brief Gives back the edge by its id.
  1145     /// \brief Gives back the edge by its label.
  1144     ///
  1146     ///
  1145     /// It reads an id from the stream and gives back which edge belongs to
  1147     /// It reads an id from the stream and gives back which edge belongs to
  1146     /// it. It is possible only if there was read an "id" named map.
  1148     /// it. It is possible only if there was read an "label" named map.
  1147     void readId(std::istream& is, Edge& edge) const {
  1149     void readLabel(std::istream& is, Edge& edge) const {
  1148       edge = inverter->read(is);
  1150       edge = inverter->read(is);
  1149     } 
  1151     } 
  1150 
  1152 
  1151   private:
  1153   private:
  1152 
  1154 
  1153     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
  1155     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
  1154     MapReaders readers;
  1156     MapReaders readers;
  1155    
  1157    
  1156     Graph& graph;   
  1158     Graph& graph;   
  1157     std::string id;
  1159     std::string name;
  1158     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
  1160     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
  1159 
  1161 
  1160     std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
  1162     std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
  1161     std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
  1163     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  1162   };
  1164   };
  1163 
  1165 
  1164   /// \ingroup io_group
  1166   /// \ingroup io_group
  1165   /// \brief SectionReader for reading a undirected graph's edgeset.
  1167   /// \brief SectionReader for reading a undirected graph's edgeset.
  1166   ///
  1168   ///
  1167   /// The lemon format can store multiple undirected edgesets with several 
  1169   /// The lemon format can store multiple undirected edgesets with several 
  1168   /// maps. The undirected edgeset section's header line is \c \@undiredgeset 
  1170   /// maps. The undirected edgeset section's header line is \c \@undiredgeset 
  1169   /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
  1171   /// \c undiredgeset_name, but the \c undiredgeset_name may be empty.
  1170   ///
  1172   ///
  1171   /// The first line of the section contains the names of the maps separated
  1173   /// The first line of the section contains the names of the maps separated
  1172   /// with white spaces. Each next lines describes an edge in the edgeset. The
  1174   /// with white spaces. Each next lines describes an edge in the edgeset. The
  1173   /// line contains the connected nodes' id and the mapped values for each map.
  1175   /// line contains the connected nodes' id and the mapped values for each map.
  1174   ///
  1176   ///
  1176   /// undirected edge map describes one directed edge map. This two maps
  1178   /// undirected edge map describes one directed edge map. This two maps
  1177   /// are the forward map and the backward map and the names of this map
  1179   /// are the forward map and the backward map and the names of this map
  1178   /// is near the same just with a prefix \c '+' or \c '-' character 
  1180   /// is near the same just with a prefix \c '+' or \c '-' character 
  1179   /// difference.
  1181   /// difference.
  1180   ///
  1182   ///
  1181   /// If the edgeset contains an \c "id" named map then it will be regarded
  1183   /// If the edgeset contains an \c "label" named map then it will be regarded
  1182   /// as id map. This map should contain only unique values and when the 
  1184   /// as id map. This map should contain only unique values and when the 
  1183   /// \c readId() member will read a value from the given stream it will
  1185   /// \c readLabel() member will read a value from the given stream it will
  1184   /// give back that undiricted edge which is mapped to this value.
  1186   /// give back that undiricted edge which is mapped to this value.
  1185   ///
  1187   ///
  1186   /// The undirected edgeset reader needs a node id reader to identify which 
  1188   /// The undirected edgeset reader needs a node id reader to identify which 
  1187   /// nodes have to be connected. If a NodeSetReader reads an "id" named map,
  1189   /// nodes have to be connected. If a NodeSetReader reads an "label" named map,
  1188   /// it will be able to resolve the nodes by ids.
  1190   /// it will be able to resolve the nodes by ids.
  1189   ///
  1191   ///
  1190   /// \relates LemonReader
  1192   /// \relates LemonReader
  1191   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1193   template <typename _Graph, typename _Traits = DefaultReaderTraits>
  1192   class UndirEdgeSetReader : public LemonReader::SectionReader {
  1194   class UndirEdgeSetReader : public LemonReader::SectionReader {
  1205     /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader 
  1207     /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader 
  1206     /// and attach it into the given LemonReader. The undirected edgeset 
  1208     /// and attach it into the given LemonReader. The undirected edgeset 
  1207     /// reader will add the readed undirected edges to the given Graph. It 
  1209     /// reader will add the readed undirected edges to the given Graph. It 
  1208     /// will use the given node id reader to read the source and target 
  1210     /// will use the given node id reader to read the source and target 
  1209     /// nodes of the edges. The reader will read the section only if the 
  1211     /// nodes of the edges. The reader will read the section only if the 
  1210     /// \c _id and the \c undiredgset_id are the same. 
  1212     /// \c _name and the \c undiredgset_name are the same. 
  1211     template <typename NodeIdReader>
  1213     template <typename NodeLabelReader>
  1212     UndirEdgeSetReader(LemonReader& _reader, 
  1214     UndirEdgeSetReader(LemonReader& _reader, 
  1213 		       Graph& _graph, 
  1215 		       Graph& _graph, 
  1214 		       const NodeIdReader& _nodeIdReader, 
  1216 		       const NodeLabelReader& _nodeLabelReader, 
  1215 		       const std::string& _id = std::string(),
  1217 		       const std::string& _name = std::string(),
  1216 		       const DefaultSkipper& _skipper = DefaultSkipper()) 
  1218 		       const DefaultSkipper& _skipper = DefaultSkipper()) 
  1217       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
  1219       : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
  1218       checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
  1220       checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
  1219       nodeIdReader.reset(new _reader_bits::
  1221       nodeLabelReader.reset(new _reader_bits::
  1220 			 IdReader<Node, NodeIdReader>(_nodeIdReader));
  1222 			 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
  1221     }
  1223     }
  1222     /// \brief Destructor.
  1224     /// \brief Destructor.
  1223     ///
  1225     ///
  1224     /// Destructor for UndirEdgeSetReader.
  1226     /// Destructor for UndirEdgeSetReader.
  1225     virtual ~UndirEdgeSetReader() {
  1227     virtual ~UndirEdgeSetReader() {
  1370 
  1372 
  1371     /// \brief Gives back true when the SectionReader can process 
  1373     /// \brief Gives back true when the SectionReader can process 
  1372     /// the section with the given header line.
  1374     /// the section with the given header line.
  1373     ///
  1375     ///
  1374     /// It gives back true when the header line starts with \c \@undiredgeset,
  1376     /// It gives back true when the header line starts with \c \@undiredgeset,
  1375     /// and the header line's id and the edgeset's id are the same.
  1377     /// and the header line's name and the edgeset's name are the same.
  1376     virtual bool header(const std::string& line) {
  1378     virtual bool header(const std::string& line) {
  1377       std::istringstream ls(line);
  1379       std::istringstream ls(line);
  1378       std::string command;
  1380       std::string command;
  1379       std::string name;
  1381       std::string id;
  1380       ls >> command >> name;
  1382       ls >> command >> name;
  1381       return command == "@undiredgeset" && name == id;
  1383       return command == "@undiredgeset" && name == id;
  1382     }
  1384     }
  1383 
  1385 
  1384     /// \brief Reader function of the section.
  1386     /// \brief Reader function of the section.
  1385     ///
  1387     ///
  1386     /// It reads the content of the section.
  1388     /// It reads the content of the section.
  1387     virtual void read(std::istream& is) {
  1389     virtual void read(std::istream& is) {
  1388       if (!nodeIdReader->isIdReader()) {
  1390       if (!nodeLabelReader->isLabelReader()) {
  1389 	throw DataFormatError("Cannot find nodeset or ID map");
  1391 	throw DataFormatError("Cannot find nodeset or label map");
  1390       }
  1392       }
  1391       std::vector<_reader_bits::MapReaderBase<UndirEdge>* > index;
  1393       std::vector<_reader_bits::MapReaderBase<UndirEdge>* > index;
  1392       std::string line;
  1394       std::string line;
  1393 
  1395 
  1394       getline(is, line);
  1396       getline(is, line);
  1395       std::istringstream ls(line);	
  1397       std::istringstream ls(line);	
       
  1398       std::string id;
  1396       while (ls >> id) {
  1399       while (ls >> id) {
  1397 	typename MapReaders::iterator it = readers.find(id);
  1400 	typename MapReaders::iterator it = readers.find(id);
  1398 	if (it != readers.end()) {
  1401 	if (it != readers.end()) {
  1399 	  index.push_back(it->second);
  1402 	  index.push_back(it->second);
  1400 	  it->second->touch();
  1403 	  it->second->touch();
  1401 	} else {
  1404 	} else {
  1402 	  index.push_back(&skipper);
  1405 	  index.push_back(&skipper);
  1403 	}
  1406 	}
  1404 	if (id == "id" && inverter.get() == 0) {
  1407 	if (id == "label" || (id =="id" && inverter.get() == 0)) {
  1405 	  inverter.reset(index.back()->getInverter());
  1408 	  inverter.reset(index.back()->getInverter());
  1406 	  index.back() = inverter.get();
  1409 	  index.back() = inverter.get();
  1407 	}
  1410 	}
  1408       }
  1411       }
  1409       for (typename MapReaders::iterator it = readers.begin();
  1412       for (typename MapReaders::iterator it = readers.begin();
  1414 	  throw IOParameterError(msg.message());
  1417 	  throw IOParameterError(msg.message());
  1415 	}
  1418 	}
  1416       }
  1419       }
  1417       while (getline(is, line)) {	
  1420       while (getline(is, line)) {	
  1418 	std::istringstream ls(line);
  1421 	std::istringstream ls(line);
  1419 	Node from = nodeIdReader->read(ls);
  1422 	Node from = nodeLabelReader->read(ls);
  1420 	Node to = nodeIdReader->read(ls);
  1423 	Node to = nodeLabelReader->read(ls);
  1421 	UndirEdge edge = graph.addEdge(from, to);
  1424 	UndirEdge edge = graph.addEdge(from, to);
  1422 	for (int i = 0; i < (int)index.size(); ++i) {
  1425 	for (int i = 0; i < (int)index.size(); ++i) {
  1423 	  index[i]->read(ls, edge);
  1426 	  index[i]->read(ls, edge);
  1424 	}
  1427 	}
  1425       }
  1428       }
  1426     }
  1429     }
  1427 
  1430 
  1428   public:
  1431   public:
  1429 
  1432 
  1430     /// \brief Returns true if the edgeset can give back the edge by its id.
  1433     /// \brief Returns true if the edgeset can give back the edge by its label.
  1431     ///
  1434     ///
  1432     /// Returns true if the edgeset can give back the undirected edge by its 
  1435     /// Returns true if the edgeset can give back the undirected edge by its 
  1433     /// id. It is possible only if an "id" named map was read.
  1436     /// id. It is possible only if an "label" named map was read.
  1434     bool isIdReader() const {
  1437     bool isLabelReader() const {
  1435       return inverter.get() != 0;
  1438       return inverter.get() != 0;
  1436     }
  1439     }
  1437 
  1440 
  1438     /// \brief Gives back the undirected edge by its id.
  1441     /// \brief Gives back the undirected edge by its label.
  1439     ///
  1442     ///
  1440     /// It reads an id from the stream and gives back which undirected edge 
  1443     /// It reads an id from the stream and gives back which undirected edge 
  1441     /// belongs to it. It is possible only if there was read an "id" named map.
  1444     /// belongs to it. It is possible only if there was read an "label" named map.
  1442     void readId(std::istream& is, UndirEdge& undirEdge) const {
  1445     void readLabel(std::istream& is, UndirEdge& undirEdge) const {
  1443       undirEdge = inverter->read(is);
  1446       undirEdge = inverter->read(is);
  1444     } 
  1447     } 
  1445 
  1448 
  1446     /// \brief Gives back the directed edge by its id.
  1449     /// \brief Gives back the directed edge by its label.
  1447     ///
  1450     ///
  1448     /// It reads an id from the stream and gives back which directed edge 
  1451     /// It reads an id from the stream and gives back which directed edge 
  1449     /// belongs to it. The directed edge id is the \c '+' or \c '-' character
  1452     /// belongs to it. The directed edge id is the \c '+' or \c '-' character
  1450     /// and the undirected edge id. It is possible only if there was read 
  1453     /// and the undirected edge id. It is possible only if there was read 
  1451     /// an "id" named map.
  1454     /// an "label" named map.
  1452     void readId(std::istream& is, Edge& edge) const {
  1455     void readLabel(std::istream& is, Edge& edge) const {
  1453       char c;
  1456       char c;
  1454       is >> c;
  1457       is >> c;
  1455       UndirEdge undirEdge = inverter->read(is);
  1458       UndirEdge undirEdge = inverter->read(is);
  1456       if (c == '+') {
  1459       if (c == '+') {
  1457 	edge = graph.direct(undirEdge, true);
  1460 	edge = graph.direct(undirEdge, true);
  1468     typedef std::map<std::string, 
  1471     typedef std::map<std::string, 
  1469 		     _reader_bits::MapReaderBase<UndirEdge>*> MapReaders;
  1472 		     _reader_bits::MapReaderBase<UndirEdge>*> MapReaders;
  1470     MapReaders readers;
  1473     MapReaders readers;
  1471    
  1474    
  1472     Graph& graph;   
  1475     Graph& graph;   
  1473     std::string id;
  1476     std::string name;
  1474     _reader_bits::SkipReader<UndirEdge, DefaultSkipper> skipper;
  1477     _reader_bits::SkipReader<UndirEdge, DefaultSkipper> skipper;
  1475 
  1478 
  1476     std::auto_ptr<_reader_bits::MapInverterBase<UndirEdge> > inverter;
  1479     std::auto_ptr<_reader_bits::MapInverterBase<UndirEdge> > inverter;
  1477     std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
  1480     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  1478   };
  1481   };
  1479 
  1482 
  1480   /// \ingroup io_group
  1483   /// \ingroup io_group
  1481   /// \brief SectionReader for reading labeled nodes.
  1484   /// \brief SectionReader for reading labeled nodes.
  1482   ///
  1485   ///
  1483   /// The nodes section's header line is \c \@nodes \c nodes_id, but the
  1486   /// The nodes section's header line is \c \@nodes \c nodes_name, but the
  1484   /// \c nodes_id may be empty.
  1487   /// \c nodes_name may be empty.
  1485   ///
  1488   ///
  1486   /// Each line in the section contains the name of the node 
  1489   /// Each line in the section contains the name of the node 
  1487   /// and then the node id. 
  1490   /// and then the node id. 
  1488   ///
  1491   ///
  1489   /// \relates LemonReader
  1492   /// \relates LemonReader
  1497     /// \brief Constructor.
  1500     /// \brief Constructor.
  1498     ///
  1501     ///
  1499     /// Constructor for NodeReader. It creates the NodeReader and
  1502     /// Constructor for NodeReader. It creates the NodeReader and
  1500     /// attach it into the given LemonReader. It will use the given
  1503     /// attach it into the given LemonReader. It will use the given
  1501     /// node id reader to give back the nodes. The reader will read the 
  1504     /// node id reader to give back the nodes. The reader will read the 
  1502     /// section only if the \c _id and the \c nodes_id are the same. 
  1505     /// section only if the \c _name and the \c nodes_name are the same. 
  1503     template <typename _IdReader>
  1506     template <typename _LabelReader>
  1504     NodeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1507     NodeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  1505 	       const std::string& _id = std::string()) 
  1508 	       const std::string& _name = std::string()) 
  1506       : Parent(_reader), id(_id) {
  1509       : Parent(_reader), name(_name) {
  1507       checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>();
  1510       checkConcept<_reader_bits::ItemLabelReader<Node>, _LabelReader>();
  1508       nodeIdReader.reset(new _reader_bits::
  1511       nodeLabelReader.reset(new _reader_bits::
  1509 			 IdReader<Node, _IdReader>(_idReader));
  1512 			 LabelReader<Node, _LabelReader>(_labelReader));
  1510     }
  1513     }
  1511 
  1514 
  1512     /// \brief Destructor.
  1515     /// \brief Destructor.
  1513     ///
  1516     ///
  1514     /// Destructor for NodeReader.
  1517     /// Destructor for NodeReader.
  1536 
  1539 
  1537     /// \brief Gives back true when the SectionReader can process 
  1540     /// \brief Gives back true when the SectionReader can process 
  1538     /// the section with the given header line.
  1541     /// the section with the given header line.
  1539     ///
  1542     ///
  1540     /// It gives back true when the header line start with \c \@nodes,
  1543     /// It gives back true when the header line start with \c \@nodes,
  1541     /// and the header line's id and the reader's id are the same.
  1544     /// and the header line's name and the reader's name are the same.
  1542     virtual bool header(const std::string& line) {
  1545     virtual bool header(const std::string& line) {
  1543       std::istringstream ls(line);
  1546       std::istringstream ls(line);
  1544       std::string command;
  1547       std::string command;
  1545       std::string name;
  1548       std::string id;
  1546       ls >> command >> name;
  1549       ls >> command >> name;
  1547       return command == "@nodes" && name == id;
  1550       return command == "@nodes" && name == id;
  1548     }
  1551     }
  1549 
  1552 
  1550     /// \brief Reader function of the section.
  1553     /// \brief Reader function of the section.
  1551     ///
  1554     ///
  1552     /// It reads the content of the section.
  1555     /// It reads the content of the section.
  1553     virtual void read(std::istream& is) {
  1556     virtual void read(std::istream& is) {
  1554       if (!nodeIdReader->isIdReader()) {
  1557       if (!nodeLabelReader->isLabelReader()) {
  1555 	throw DataFormatError("Cannot find nodeset or ID map");
  1558 	throw DataFormatError("Cannot find nodeset or label map");
  1556       }
  1559       }
  1557       std::string line;
  1560       std::string line;
  1558       while (getline(is, line)) {
  1561       while (getline(is, line)) {
  1559 	std::istringstream ls(line);
  1562 	std::istringstream ls(line);
  1560 	std::string id;
  1563 	std::string id;
  1561 	ls >> id;
  1564 	ls >> id;
  1562 	typename NodeReaders::iterator it = readers.find(id);
  1565 	typename NodeReaders::iterator it = readers.find(id);
  1563 	if (it != readers.end()) {
  1566 	if (it != readers.end()) {
  1564 	  it->second.read(nodeIdReader->read(ls));
  1567 	  it->second.read(nodeLabelReader->read(ls));
  1565 	  it->second.touch();
  1568 	  it->second.touch();
  1566 	}	
  1569 	}	
  1567       }
  1570       }
  1568       for (typename NodeReaders::iterator it = readers.begin();
  1571       for (typename NodeReaders::iterator it = readers.begin();
  1569 	   it != readers.end(); ++it) {
  1572 	   it != readers.end(); ++it) {
  1575       }
  1578       }
  1576     }
  1579     }
  1577     
  1580     
  1578   private:
  1581   private:
  1579 
  1582 
  1580     std::string id;
  1583     std::string name;
  1581 
  1584 
  1582     typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
  1585     typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
  1583     NodeReaders readers;
  1586     NodeReaders readers;
  1584     std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader;
  1587     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
  1585   };
  1588   };
  1586 
  1589 
  1587   /// \ingroup io_group
  1590   /// \ingroup io_group
  1588   /// \brief SectionReader for reading labeled edges.
  1591   /// \brief SectionReader for reading labeled edges.
  1589   ///
  1592   ///
  1590   /// The edges section's header line is \c \@edges \c edges_id, but the
  1593   /// The edges section's header line is \c \@edges \c edges_name, but the
  1591   /// \c edges_id may be empty.
  1594   /// \c edges_name may be empty.
  1592   ///
  1595   ///
  1593   /// Each line in the section contains the name of the edge 
  1596   /// Each line in the section contains the name of the edge 
  1594   /// and then the edge id. 
  1597   /// and then the edge id. 
  1595   ///
  1598   ///
  1596   /// \relates LemonReader
  1599   /// \relates LemonReader
  1604     /// \brief Constructor.
  1607     /// \brief Constructor.
  1605     ///
  1608     ///
  1606     /// Constructor for EdgeReader. It creates the EdgeReader and
  1609     /// Constructor for EdgeReader. It creates the EdgeReader and
  1607     /// attach it into the given LemonReader. It will use the given
  1610     /// attach it into the given LemonReader. It will use the given
  1608     /// edge id reader to give back the edges. The reader will read the 
  1611     /// edge id reader to give back the edges. The reader will read the 
  1609     /// section only if the \c _id and the \c edges_id are the same. 
  1612     /// section only if the \c _name and the \c edges_name are the same. 
  1610     template <typename _IdReader>
  1613     template <typename _LabelReader>
  1611     EdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1614     EdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  1612 	       const std::string& _id = std::string()) 
  1615 	       const std::string& _name = std::string()) 
  1613       : Parent(_reader), id(_id) {
  1616       : Parent(_reader), name(_name) {
  1614       checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
  1617       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  1615       edgeIdReader.reset(new _reader_bits::
  1618       edgeLabelReader.reset(new _reader_bits::
  1616 			 IdReader<Edge, _IdReader>(_idReader));
  1619 			 LabelReader<Edge, _LabelReader>(_labelReader));
  1617     }
  1620     }
  1618 
  1621 
  1619     /// \brief Destructor.
  1622     /// \brief Destructor.
  1620     ///
  1623     ///
  1621     /// Destructor for EdgeReader.
  1624     /// Destructor for EdgeReader.
  1642 
  1645 
  1643     /// \brief Gives back true when the SectionReader can process 
  1646     /// \brief Gives back true when the SectionReader can process 
  1644     /// the section with the given header line.
  1647     /// the section with the given header line.
  1645     ///
  1648     ///
  1646     /// It gives back true when the header line start with \c \@edges,
  1649     /// It gives back true when the header line start with \c \@edges,
  1647     /// and the header line's id and the reader's id are the same.
  1650     /// and the header line's name and the reader's name are the same.
  1648     virtual bool header(const std::string& line) {
  1651     virtual bool header(const std::string& line) {
  1649       std::istringstream ls(line);
  1652       std::istringstream ls(line);
  1650       std::string command;
  1653       std::string command;
  1651       std::string name;
  1654       std::string id;
  1652       ls >> command >> name;
  1655       ls >> command >> name;
  1653       return command == "@edges" && name == id;
  1656       return command == "@edges" && name == id;
  1654     }
  1657     }
  1655 
  1658 
  1656     /// \brief Reader function of the section.
  1659     /// \brief Reader function of the section.
  1657     ///
  1660     ///
  1658     /// It reads the content of the section.
  1661     /// It reads the content of the section.
  1659     virtual void read(std::istream& is) {
  1662     virtual void read(std::istream& is) {
  1660       if (!edgeIdReader->isIdReader()) {
  1663       if (!edgeLabelReader->isLabelReader()) {
  1661 	throw DataFormatError("Cannot find edgeset or ID map");
  1664 	throw DataFormatError("Cannot find edgeset or label map");
  1662       }
  1665       }
  1663       std::string line;
  1666       std::string line;
  1664       while (getline(is, line)) {
  1667       while (getline(is, line)) {
  1665 	std::istringstream ls(line);
  1668 	std::istringstream ls(line);
  1666 	std::string id;
  1669 	std::string id;
  1667 	ls >> id;
  1670 	ls >> id;
  1668 	typename EdgeReaders::iterator it = readers.find(id);
  1671 	typename EdgeReaders::iterator it = readers.find(id);
  1669 	if (it != readers.end()) {
  1672 	if (it != readers.end()) {
  1670 	  it->second.read(edgeIdReader->read(ls));
  1673 	  it->second.read(edgeLabelReader->read(ls));
  1671 	  it->second.touch();
  1674 	  it->second.touch();
  1672 	}	
  1675 	}	
  1673       }
  1676       }
  1674       for (typename EdgeReaders::iterator it = readers.begin();
  1677       for (typename EdgeReaders::iterator it = readers.begin();
  1675 	   it != readers.end(); ++it) {
  1678 	   it != readers.end(); ++it) {
  1681       }
  1684       }
  1682     }
  1685     }
  1683     
  1686     
  1684   private:
  1687   private:
  1685 
  1688 
  1686     std::string id;
  1689     std::string name;
  1687 
  1690 
  1688     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1691     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1689     EdgeReaders readers;
  1692     EdgeReaders readers;
  1690     std::auto_ptr<_reader_bits::IdReaderBase<Edge> > edgeIdReader;
  1693     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  1691   };
  1694   };
  1692 
  1695 
  1693   /// \ingroup io_group
  1696   /// \ingroup io_group
  1694   /// \brief SectionReader for reading labeled undirected edges.
  1697   /// \brief SectionReader for reading labeled undirected edges.
  1695   ///
  1698   ///
  1696   /// The undirected edges section's header line is \c \@undiredges 
  1699   /// The undirected edges section's header line is \c \@undiredges 
  1697   /// \c undiredges_id, but the \c undiredges_id may be empty.
  1700   /// \c undiredges_name, but the \c undiredges_name may be empty.
  1698   ///
  1701   ///
  1699   /// Each line in the section contains the name of the undirected edge 
  1702   /// Each line in the section contains the name of the undirected edge 
  1700   /// and then the undirected edge id. 
  1703   /// and then the undirected edge id. 
  1701   ///
  1704   ///
  1702   /// \relates LemonReader
  1705   /// \relates LemonReader
  1711     /// \brief Constructor.
  1714     /// \brief Constructor.
  1712     ///
  1715     ///
  1713     /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and
  1716     /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and
  1714     /// attach it into the given LemonReader. It will use the given
  1717     /// attach it into the given LemonReader. It will use the given
  1715     /// undirected edge id reader to give back the edges. The reader will 
  1718     /// undirected edge id reader to give back the edges. The reader will 
  1716     /// read the section only if the \c _id and the \c undiredges_id are 
  1719     /// read the section only if the \c _name and the \c undiredges_name are 
  1717     /// the same. 
  1720     /// the same. 
  1718     template <typename _IdReader>
  1721     template <typename _LabelReader>
  1719     UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1722     UndirEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  1720 	       const std::string& _id = std::string()) 
  1723 	       const std::string& _name = std::string()) 
  1721       : Parent(_reader), id(_id) {
  1724       : Parent(_reader), name(_name) {
  1722       checkConcept<_reader_bits::ItemIdReader<UndirEdge>, _IdReader>();
  1725       checkConcept<_reader_bits::ItemLabelReader<UndirEdge>, _LabelReader>();
  1723       checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
  1726       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  1724       undirEdgeIdReader.reset(new _reader_bits::
  1727       undirEdgeLabelReader.reset(new _reader_bits::
  1725 			      IdReader<UndirEdge, _IdReader>(_idReader));
  1728 			      LabelReader<UndirEdge, _LabelReader>(_labelReader));
  1726       edgeIdReader.reset(new _reader_bits::
  1729       edgeLabelReader.reset(new _reader_bits::
  1727 			 IdReader<Edge, _IdReader>(_idReader));
  1730 			 LabelReader<Edge, _LabelReader>(_labelReader));
  1728     }
  1731     }
  1729 
  1732 
  1730     /// \brief Destructor.
  1733     /// \brief Destructor.
  1731     ///
  1734     ///
  1732     /// Destructor for UndirEdgeReader.
  1735     /// Destructor for UndirEdgeReader.
  1766 
  1769 
  1767     /// \brief Gives back true when the SectionReader can process 
  1770     /// \brief Gives back true when the SectionReader can process 
  1768     /// the section with the given header line.
  1771     /// the section with the given header line.
  1769     ///
  1772     ///
  1770     /// It gives back true when the header line start with \c \@edges,
  1773     /// It gives back true when the header line start with \c \@edges,
  1771     /// and the header line's id and the reader's id are the same.
  1774     /// and the header line's name and the reader's name are the same.
  1772     virtual bool header(const std::string& line) {
  1775     virtual bool header(const std::string& line) {
  1773       std::istringstream ls(line);
  1776       std::istringstream ls(line);
  1774       std::string command;
  1777       std::string command;
  1775       std::string name;
  1778       std::string id;
  1776       ls >> command >> name;
  1779       ls >> command >> name;
  1777       return command == "@undiredges" && name == id;
  1780       return command == "@undiredges" && name == id;
  1778     }
  1781     }
  1779 
  1782 
  1780     /// \brief Reader function of the section.
  1783     /// \brief Reader function of the section.
  1781     ///
  1784     ///
  1782     /// It reads the content of the section.
  1785     /// It reads the content of the section.
  1783     virtual void read(std::istream& is) {
  1786     virtual void read(std::istream& is) {
  1784       if (!edgeIdReader->isIdReader()) {
  1787       if (!edgeLabelReader->isLabelReader()) {
  1785 	throw DataFormatError("Cannot find undirected edgeset or ID map");
  1788 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1786       }
  1789       }
  1787       if (!undirEdgeIdReader->isIdReader()) {
  1790       if (!undirEdgeLabelReader->isLabelReader()) {
  1788 	throw DataFormatError("Cannot find undirected edgeset or ID map");
  1791 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1789       }
  1792       }
  1790       std::string line;
  1793       std::string line;
  1791       while (getline(is, line)) {
  1794       while (getline(is, line)) {
  1792 	std::istringstream ls(line);
  1795 	std::istringstream ls(line);
  1793 	std::string id;
  1796 	std::string id;
  1794 	ls >> id;
  1797 	ls >> id;
  1795 	{
  1798 	{
  1796 	  typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
  1799 	  typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
  1797 	  if (it != undirEdgeReaders.end()) {
  1800 	  if (it != undirEdgeReaders.end()) {
  1798 	    it->second.read(undirEdgeIdReader->read(ls));
  1801 	    it->second.read(undirEdgeLabelReader->read(ls));
  1799 	    it->second.touch();
  1802 	    it->second.touch();
  1800 	    continue;
  1803 	    continue;
  1801 	  }	
  1804 	  }	
  1802 	} {
  1805 	} {
  1803 	  typename EdgeReaders::iterator it = edgeReaders.find(id);
  1806 	  typename EdgeReaders::iterator it = edgeReaders.find(id);
  1804 	  if (it != edgeReaders.end()) {
  1807 	  if (it != edgeReaders.end()) {
  1805 	    it->second.read(edgeIdReader->read(ls));
  1808 	    it->second.read(edgeLabelReader->read(ls));
  1806 	    it->second.touch();
  1809 	    it->second.touch();
  1807 	    continue;
  1810 	    continue;
  1808 	  }	
  1811 	  }	
  1809 	}
  1812 	}
  1810       }
  1813       }
  1826       }
  1829       }
  1827     }
  1830     }
  1828     
  1831     
  1829   private:
  1832   private:
  1830 
  1833 
  1831     std::string id;
  1834     std::string name;
  1832 
  1835 
  1833     typedef std::map<std::string, 
  1836     typedef std::map<std::string, 
  1834 		     _reader_bits::ItemStore<UndirEdge> > UndirEdgeReaders;
  1837 		     _reader_bits::ItemStore<UndirEdge> > UndirEdgeReaders;
  1835     UndirEdgeReaders undirEdgeReaders;
  1838     UndirEdgeReaders undirEdgeReaders;
  1836     std::auto_ptr<_reader_bits::IdReaderBase<UndirEdge> > undirEdgeIdReader;
  1839     std::auto_ptr<_reader_bits::LabelReaderBase<UndirEdge> > undirEdgeLabelReader;
  1837 
  1840 
  1838     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1841     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1839     EdgeReaders edgeReaders;
  1842     EdgeReaders edgeReaders;
  1840     std::auto_ptr<_reader_bits::IdReaderBase<Edge> > edgeIdReader;
  1843     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  1841   };
  1844   };
  1842 
  1845 
  1843   /// \ingroup io_group
  1846   /// \ingroup io_group
  1844   /// \brief SectionReader for attributes.
  1847   /// \brief SectionReader for attributes.
  1845   ///
  1848   ///
  1846   /// The lemon format can store multiple attribute set. Each set has
  1849   /// The lemon format can store multiple attribute set. Each set has
  1847   /// the header line \c \@attributes \c attributeset_id, but the 
  1850   /// the header line \c \@attributes \c attributeset_name, but the 
  1848   /// attributeset_id may be empty.
  1851   /// attributeset_name may be empty.
  1849   ///
  1852   ///
  1850   /// The attributeset section contains several lines. Each of them starts
  1853   /// The attributeset section contains several lines. Each of them starts
  1851   /// with an attribute and then a the value for the id.
  1854   /// with an attribute and then a the value for the id.
  1852   ///
  1855   ///
  1853   /// \relates LemonReader
  1856   /// \relates LemonReader
  1858   public:
  1861   public:
  1859     /// \brief Constructor.
  1862     /// \brief Constructor.
  1860     ///
  1863     ///
  1861     /// Constructor for AttributeReader. It creates the AttributeReader and
  1864     /// Constructor for AttributeReader. It creates the AttributeReader and
  1862     /// attach it into the given LemonReader. The reader process a section
  1865     /// attach it into the given LemonReader. The reader process a section
  1863     /// only if the \c section_id and the \c _id are the same.
  1866     /// only if the \c section_name and the \c _name are the same.
  1864     AttributeReader(LemonReader& _reader, 
  1867     AttributeReader(LemonReader& _reader, 
  1865 		    const std::string& _id = std::string()) 
  1868 		    const std::string& _name = std::string()) 
  1866       : Parent(_reader), id(_id) {}
  1869       : Parent(_reader), name(_name) {}
  1867 
  1870 
  1868     /// \brief Destructor.
  1871     /// \brief Destructor.
  1869     ///
  1872     ///
  1870     /// Destructor for AttributeReader.
  1873     /// Destructor for AttributeReader.
  1871     virtual ~AttributeReader() {
  1874     virtual ~AttributeReader() {
  1914     /// It gives back true when the header line start with \c \@attributes,
  1917     /// It gives back true when the header line start with \c \@attributes,
  1915     /// and the header line's id and the attributeset's id are the same.
  1918     /// and the header line's id and the attributeset's id are the same.
  1916     bool header(const std::string& line) {
  1919     bool header(const std::string& line) {
  1917       std::istringstream ls(line);
  1920       std::istringstream ls(line);
  1918       std::string command;
  1921       std::string command;
  1919       std::string name;
  1922       std::string id;
  1920       ls >> command >> name;
  1923       ls >> command >> name;
  1921       return command == "@attributes" && name == id;
  1924       return command == "@attributes" && name == id;
  1922     }
  1925     }
  1923 
  1926 
  1924     /// \brief Reader function of the section.
  1927     /// \brief Reader function of the section.
  1931 	std::string id;
  1934 	std::string id;
  1932 	ls >> id;
  1935 	ls >> id;
  1933 	typename Readers::iterator it = readers.find(id);
  1936 	typename Readers::iterator it = readers.find(id);
  1934 	if (it != readers.end()) {
  1937 	if (it != readers.end()) {
  1935 	  it->second->read(ls);
  1938 	  it->second->read(ls);
  1936 	  it->second->touch();
  1939  	  it->second->touch();
  1937 	}
  1940 	}
  1938       }
  1941       }
  1939       for (typename Readers::iterator it = readers.begin();
  1942       for (typename Readers::iterator it = readers.begin();
  1940 	   it != readers.end(); ++it) {
  1943 	   it != readers.end(); ++it) {
  1941 	if (!it->second->touched()) {
  1944 	if (!it->second->touched()) {
  1945 	}	
  1948 	}	
  1946       }
  1949       }
  1947     }    
  1950     }    
  1948 
  1951 
  1949   private:
  1952   private:
  1950     std::string id;
  1953     std::string name;
  1951 
  1954 
  1952     typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  1955     typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  1953     Readers readers;  
  1956     Readers readers;  
  1954   };
  1957   };
  1955 
  1958 
  2201     }    
  2204     }    
  2202 
  2205 
  2203   private:
  2206   private:
  2204 
  2207 
  2205     void readMapNames(std::istream& is, std::vector<std::string>& maps) {
  2208     void readMapNames(std::istream& is, std::vector<std::string>& maps) {
  2206       std::string line, id;
  2209       std::string line, name;
  2207       std::getline(is, line);
  2210       std::getline(is, line);
  2208       std::istringstream ls(line);
  2211       std::istringstream ls(line);
  2209       while (ls >> id) {
  2212       while (ls >> name) {
  2210 	maps.push_back(id);
  2213 	maps.push_back(name);
  2211       }
  2214       }
  2212       while (getline(is, line));
  2215       while (getline(is, line));
  2213     }
  2216     }
  2214 
  2217 
  2215     void readItemNames(std::istream& is, std::vector<std::string>& maps) {
  2218     void readItemNames(std::istream& is, std::vector<std::string>& maps) {
  2216       std::string line, id;
  2219       std::string line, name;
  2217       while (std::getline(is, line)) {
  2220       while (std::getline(is, line)) {
  2218 	std::istringstream ls(line);
  2221 	std::istringstream ls(line);
  2219 	ls >> id;
  2222 	ls >> name;
  2220 	maps.push_back(id);
  2223 	maps.push_back(name);
  2221       }
  2224       }
  2222     }
  2225     }
  2223 
  2226 
  2224     struct SectionInfo {
  2227     struct SectionInfo {
  2225       std::string name;
  2228       std::string name;