lemon/lemon_reader.h
changeset 2475 1e9cc7b2eabc
parent 2464 d4bdbc35c927
child 2476 059dcdda37c5
equal deleted inserted replaced
35:24ffd88b8c8c 36:fa94397d72b3
    56     struct Less {
    56     struct Less {
    57       bool operator()(const T& p, const T& q) const {
    57       bool operator()(const T& p, const T& q) const {
    58 	return p < q;
    58 	return p < q;
    59       }
    59       }
    60     };
    60     };
    61 
    61     
    62     template <typename Item>
    62     template <typename Item>
    63     class ItemLabelReader {
    63     class ItemLabelReader {
    64     public:
    64     public:
    65 
    65 
    66       bool isLabelReader() { return true; }
    66       bool isLabelReader() { return true; }
   253 	typename Inverse::const_iterator it = inverse.find(value);
   253 	typename Inverse::const_iterator it = inverse.find(value);
   254 	if (it != inverse.end()) {
   254 	if (it != inverse.end()) {
   255 	  return it->second;
   255 	  return it->second;
   256 	} else {
   256 	} else {
   257 	  ErrorMessage msg;
   257 	  ErrorMessage msg;
   258 	  msg << "Invalid label error: " << value; 
   258 	  msg << "Invalid label error"; 
   259 	  throw DataFormatError(msg.message());
   259 	  throw DataFormatError(msg.message());
   260 	}
   260 	}
   261       }      
   261       }      
   262     };
   262     };
   263 
   263 
   287 	}
   287 	}
   288       }
   288       }
   289 
   289 
   290       virtual Item read(std::istream& is) const {
   290       virtual Item read(std::istream& is) const {
   291 	Value value;
   291 	Value value;
   292 	reader.read(is, value);	
   292 	reader.read(is, value);
   293 	typename Inverse::const_iterator it = inverse.find(value);
   293 	typename Inverse::const_iterator it = inverse.find(value);
   294 	if (it != inverse.end()) {
   294 	if (it != inverse.end()) {
   295 	  return it->second;
   295 	  return it->second;
   296 	} else {
   296 	} else {
   297 	  ErrorMessage msg;
   297 	  ErrorMessage msg;
   380     public:
   380     public:
   381       typedef _Item Item;
   381       typedef _Item Item;
   382       virtual ~LabelReaderBase() {}
   382       virtual ~LabelReaderBase() {}
   383       virtual Item read(std::istream& is) const = 0;
   383       virtual Item read(std::istream& is) const = 0;
   384       virtual bool isLabelReader() const = 0;
   384       virtual bool isLabelReader() const = 0;
       
   385       virtual LabelReaderBase<_Item>* clone() const = 0;
   385     };
   386     };
   386 
   387 
   387     template <typename _Item, typename _BoxedLabelReader>
   388     template <typename _Item, typename _BoxedLabelReader>
   388     class LabelReader : public LabelReaderBase<_Item> {
   389     class LabelReader : public LabelReaderBase<_Item> {
   389     public:
   390     public:
   390       typedef _Item Item;
   391       typedef _Item Item;
   391       typedef _BoxedLabelReader BoxedLabelReader;
   392       typedef _BoxedLabelReader BoxedLabelReader;
   392       
   393       
   393       const BoxedLabelReader& boxedLabelReader;
   394       const BoxedLabelReader& labelReader;
   394 
   395 
   395       LabelReader(const BoxedLabelReader& _boxedLabelReader) 
   396       LabelReader(const BoxedLabelReader& _labelReader) 
   396 	: boxedLabelReader(_boxedLabelReader) {}
   397 	: labelReader(_labelReader) {}
   397 
   398 
   398       virtual Item read(std::istream& is) const {
   399       virtual Item read(std::istream& is) const {
   399 	Item item;
   400 	Item item;
   400 	boxedLabelReader.readLabel(is, item);
   401 	labelReader.readLabel(is, item);
   401 	return item;
   402 	return item;
   402       }
   403       }
   403 
   404 
   404       virtual bool isLabelReader() const {
   405       virtual bool isLabelReader() const {
   405 	return boxedLabelReader.isLabelReader();
   406 	return labelReader.isLabelReader();
       
   407       }
       
   408       
       
   409       LabelReader<Item, BoxedLabelReader>* clone() const {
       
   410 	return new LabelReader<Item, BoxedLabelReader>(labelReader);
   406       }
   411       }
   407     };
   412     };
   408 
   413 
   409     template <typename _Item>
   414     template <typename _Item>
   410     class ItemStore {
   415     class ItemStore {
   721 	for (it = readers.begin(); it != readers.end(); ++it) {
   726 	for (it = readers.begin(); it != readers.end(); ++it) {
   722 	  if (it->first->header(line)) {
   727 	  if (it->first->header(line)) {
   723 	    it->second = true;
   728 	    it->second = true;
   724 	    char buf[2048];
   729 	    char buf[2048];
   725 	    FilterStreamBuf buffer(*is, line_num);
   730 	    FilterStreamBuf buffer(*is, line_num);
   726 
       
   727 	    try {
   731 	    try {
   728 	      buffer.pubsetbuf(buf, sizeof(buf));
   732 	      buffer.pubsetbuf(buf, sizeof(buf));
   729 	      std::istream ss(&buffer);
   733 	      std::istream ss(&buffer);
   730 	      it->first->read(ss);
   734 	      it->first->read(ss);
   731 	      break;
   735 	      break;
  1509 
  1513 
  1510     /// \brief Gives back the undirected edge by its label.
  1514     /// \brief Gives back the undirected edge by its label.
  1511     ///
  1515     ///
  1512     /// It reads an id from the stream and gives back which undirected edge 
  1516     /// It reads an id from the stream and gives back which undirected edge 
  1513     /// belongs to it. It is possible only if there was read an "label" named map.
  1517     /// belongs to it. It is possible only if there was read an "label" named map.
  1514     void readLabel(std::istream& is, UEdge& uEdge) const {
  1518     void readLabel(std::istream& is, UEdge& uedge) const {
  1515       uEdge = inverter->read(is);
  1519       uedge = inverter->read(is);
  1516     } 
  1520     } 
  1517 
  1521 
  1518     /// \brief Gives back the directed edge by its label.
  1522     /// \brief Gives back the directed edge by its label.
  1519     ///
  1523     ///
  1520     /// It reads an id from the stream and gives back which directed edge 
  1524     /// It reads an id from the stream and gives back which directed edge 
  1522     /// and the undirected edge id. It is possible only if there was read 
  1526     /// and the undirected edge id. It is possible only if there was read 
  1523     /// an "label" named map.
  1527     /// an "label" named map.
  1524     void readLabel(std::istream& is, Edge& edge) const {
  1528     void readLabel(std::istream& is, Edge& edge) const {
  1525       char c;
  1529       char c;
  1526       is >> c;
  1530       is >> c;
  1527       UEdge uEdge = inverter->read(is);
  1531       UEdge uedge = inverter->read(is);
  1528       if (c == '+') {
  1532       if (c == '+') {
  1529 	edge = graph.direct(uEdge, true);
  1533 	edge = graph.direct(uedge, true);
  1530       } else if (c == '-') {
  1534       } else if (c == '-') {
  1531         edge = graph.direct(uEdge, false);
  1535         edge = graph.direct(uedge, false);
  1532       } else {
  1536       } else {
  1533 	throw DataFormatError("Wrong id format for edge "
  1537 	throw DataFormatError("Wrong id format for edge "
  1534 			      "in undirected edgeset");
  1538 			      "in undirected edgeset");
  1535       }
  1539       }
  1536     } 
  1540     } 
  1805     UEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  1809     UEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader, 
  1806 	       const std::string& _name = std::string()) 
  1810 	       const std::string& _name = std::string()) 
  1807       : Parent(_reader), name(_name) {
  1811       : Parent(_reader), name(_name) {
  1808       checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
  1812       checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
  1809       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  1813       checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
  1810       uEdgeLabelReader.reset(new _reader_bits::
  1814       uedgeLabelReader.reset(new _reader_bits::
  1811 			      LabelReader<UEdge, _LabelReader>(_labelReader));
  1815 			     LabelReader<UEdge, _LabelReader>(_labelReader));
  1812       edgeLabelReader.reset(new _reader_bits::
  1816       edgeLabelReader.reset(new _reader_bits::
  1813 			 LabelReader<Edge, _LabelReader>(_labelReader));
  1817 			    LabelReader<Edge, _LabelReader>(_labelReader));
  1814     }
  1818     }
  1815 
  1819 
  1816     /// \brief Destructor.
  1820     /// \brief Destructor.
  1817     ///
  1821     ///
  1818     /// Destructor for UEdgeReader.
  1822     /// Destructor for UEdgeReader.
  1825 
  1829 
  1826     /// \brief Add an undirected edge reader command for the UEdgeReader.
  1830     /// \brief Add an undirected edge reader command for the UEdgeReader.
  1827     ///
  1831     ///
  1828     /// Add an undirected edge reader command for the UEdgeReader.
  1832     /// Add an undirected edge reader command for the UEdgeReader.
  1829     void readUEdge(std::string label, UEdge& item) {
  1833     void readUEdge(std::string label, UEdge& item) {
  1830       if (uEdgeReaders.find(label) != uEdgeReaders.end()) {
  1834       if (uedgeReaders.find(label) != uedgeReaders.end()) {
  1831 	ErrorMessage msg;
  1835 	ErrorMessage msg;
  1832 	msg << "Multiple read rule for undirected edge: " << label;
  1836 	msg << "Multiple read rule for undirected edge: " << label;
  1833 	throw IoParameterError(msg.message());
  1837 	throw IoParameterError(msg.message());
  1834       }
  1838       }
  1835       uEdgeReaders.insert(make_pair(label, _reader_bits::
  1839       uedgeReaders.insert(make_pair(label, _reader_bits::
  1836 					ItemStore<UEdge>(item)));
  1840 					ItemStore<UEdge>(item)));
  1837     }
  1841     }
  1838 
  1842 
  1839     /// \brief Add an edge reader command for the UEdgeReader.
  1843     /// \brief Add an edge reader command for the UEdgeReader.
  1840     ///
  1844     ///
  1868     /// It reads the content of the section.
  1872     /// It reads the content of the section.
  1869     virtual void read(std::istream& is) {
  1873     virtual void read(std::istream& is) {
  1870       if (!edgeLabelReader->isLabelReader()) {
  1874       if (!edgeLabelReader->isLabelReader()) {
  1871 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1875 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1872       }
  1876       }
  1873       if (!uEdgeLabelReader->isLabelReader()) {
  1877       if (!uedgeLabelReader->isLabelReader()) {
  1874 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1878 	throw DataFormatError("Cannot find undirected edgeset or label map");
  1875       }
  1879       }
  1876       std::string line;
  1880       std::string line;
  1877       while (getline(is, line)) {
  1881       while (getline(is, line)) {
  1878 	std::istringstream ls(line);
  1882 	std::istringstream ls(line);
  1879 	std::string id;
  1883 	std::string id;
  1880 	ls >> id;
  1884 	ls >> id;
  1881 	{
  1885 	{
  1882 	  typename UEdgeReaders::iterator it = uEdgeReaders.find(id);
  1886 	  typename UEdgeReaders::iterator it = uedgeReaders.find(id);
  1883 	  if (it != uEdgeReaders.end()) {
  1887 	  if (it != uedgeReaders.end()) {
  1884 	    it->second.read(uEdgeLabelReader->read(ls));
  1888 	    it->second.read(uedgeLabelReader->read(ls));
  1885 	    it->second.touch();
  1889 	    it->second.touch();
  1886 	    continue;
  1890 	    continue;
  1887 	  }	
  1891 	  }	
  1888 	} {
  1892 	} {
  1889 	  typename EdgeReaders::iterator it = edgeReaders.find(id);
  1893 	  typename EdgeReaders::iterator it = edgeReaders.find(id);
  1900 	  ErrorMessage msg;
  1904 	  ErrorMessage msg;
  1901 	  msg << "Edge not found in file: " << it->first;
  1905 	  msg << "Edge not found in file: " << it->first;
  1902 	  throw IoParameterError(msg.message());
  1906 	  throw IoParameterError(msg.message());
  1903 	}
  1907 	}
  1904       }
  1908       }
  1905       for (typename UEdgeReaders::iterator it = uEdgeReaders.begin();
  1909       for (typename UEdgeReaders::iterator it = uedgeReaders.begin();
  1906 	   it != uEdgeReaders.end(); ++it) {
  1910 	   it != uedgeReaders.end(); ++it) {
  1907 	if (!it->second.touched()) {
  1911 	if (!it->second.touched()) {
  1908 	  ErrorMessage msg;
  1912 	  ErrorMessage msg;
  1909 	  msg << "UEdge not found in file: " << it->first;
  1913 	  msg << "UEdge not found in file: " << it->first;
  1910 	  throw IoParameterError(msg.message());
  1914 	  throw IoParameterError(msg.message());
  1911 	}
  1915 	}
  1912       }
  1916       }
  1913     }
  1917     }
  1914 
  1918 
  1915     virtual void missing() {
  1919     virtual void missing() {
  1916       if (edgeReaders.empty() && uEdgeReaders.empty()) return;
  1920       if (edgeReaders.empty() && uedgeReaders.empty()) return;
  1917       ErrorMessage msg;
  1921       ErrorMessage msg;
  1918       msg << "UEdges section not found in file: @uedges " << name;
  1922       msg << "UEdges section not found in file: @uedges " << name;
  1919       throw IoParameterError(msg.message());
  1923       throw IoParameterError(msg.message());
  1920     }
  1924     }
  1921     
  1925     
  1923 
  1927 
  1924     std::string name;
  1928     std::string name;
  1925 
  1929 
  1926     typedef std::map<std::string, 
  1930     typedef std::map<std::string, 
  1927 		     _reader_bits::ItemStore<UEdge> > UEdgeReaders;
  1931 		     _reader_bits::ItemStore<UEdge> > UEdgeReaders;
  1928     UEdgeReaders uEdgeReaders;
  1932     UEdgeReaders uedgeReaders;
  1929     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uEdgeLabelReader;
  1933     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uedgeLabelReader;
  1930 
  1934 
  1931     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1935     typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
  1932     EdgeReaders edgeReaders;
  1936     EdgeReaders edgeReaders;
  1933     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  1937     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
  1934   };
  1938   };
  2049   private:
  2053   private:
  2050     std::string name;
  2054     std::string name;
  2051 
  2055 
  2052     typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  2056     typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
  2053     Readers readers;  
  2057     Readers readers;  
       
  2058   };
       
  2059 
       
  2060   /// \ingroup section_io
       
  2061   /// \brief SectionReader for reading extra node maps.
       
  2062   ///
       
  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.
       
  2067   ///
       
  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.
       
  2072   ///
       
  2073   /// \relates LemonReader
       
  2074   template <typename _Graph, typename _Traits = DefaultReaderTraits>
       
  2075   class NodeMapReader : public LemonReader::SectionReader {
       
  2076     typedef LemonReader::SectionReader Parent;
       
  2077   public:
       
  2078 
       
  2079     typedef _Graph Graph;
       
  2080     typedef typename Graph::Node Node;
       
  2081     typedef _Traits Traits;
       
  2082     typedef typename Traits::Skipper DefaultSkipper;
       
  2083 
       
  2084     /// \brief Constructor.
       
  2085     ///
       
  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));
       
  2098     } 
       
  2099 
       
  2100 
       
  2101     /// \brief Destructor.
       
  2102     ///
       
  2103     /// Destructor for NodeMapReader.
       
  2104     virtual ~NodeMapReader() {
       
  2105       for (typename MapReaders::iterator it = readers.begin(); 
       
  2106 	   it != readers.end(); ++it) {
       
  2107 	delete it->second;
       
  2108       }
       
  2109     }
       
  2110 
       
  2111   private:
       
  2112     NodeMapReader(const NodeMapReader&);
       
  2113     void operator=(const NodeMapReader&);
       
  2114   
       
  2115   public:
       
  2116 
       
  2117     /// \brief Add a new node map reader command for the reader.
       
  2118     ///
       
  2119     /// Add a new node map reader command for the reader.
       
  2120     template <typename Map>
       
  2121     NodeMapReader& readNodeMap(std::string label, Map& map) {
       
  2122       return _readMap<
       
  2123 	typename Traits::template Reader<typename Map::Value>, Map,
       
  2124 	typename _reader_bits::Arg<Map>::Type>(label, map);
       
  2125     }
       
  2126 
       
  2127     template <typename Map>
       
  2128     NodeMapReader& readNodeMap(std::string label, const Map& map) {
       
  2129       return _readMap<
       
  2130 	typename Traits::template Reader<typename Map::Value>, Map,
       
  2131 	typename _reader_bits::Arg<Map>::Type>(label, map);
       
  2132     }
       
  2133 
       
  2134     /// \brief Add a new node map reader command for the reader.
       
  2135     ///
       
  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>
       
  2141 	(label, map, ir);
       
  2142     }
       
  2143 
       
  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>
       
  2148 	(label, map, ir);
       
  2149     }
       
  2150 
       
  2151   private:
       
  2152 
       
  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()) {
       
  2159 	ErrorMessage msg;
       
  2160 	msg << "Multiple read rule for map: " << label;
       
  2161 	throw IoParameterError(msg.message());
       
  2162       }      
       
  2163       readers.insert(
       
  2164 	make_pair(label, new _reader_bits::
       
  2165 		  MapReader<Node, Map, ItemReader>(map, ir)));
       
  2166       return *this;
       
  2167     }
       
  2168 
       
  2169   public:
       
  2170 
       
  2171     /// \brief Add a new node map skipper command for the reader.
       
  2172     ///
       
  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()) {
       
  2178 	ErrorMessage msg;
       
  2179 	msg << "Multiple read rule for map: " << label;
       
  2180 	throw IoParameterError(msg.message());
       
  2181       }
       
  2182       readers.insert(make_pair(label, new _reader_bits::
       
  2183 			       SkipReader<Node, ItemReader>(ir)));
       
  2184       return *this;
       
  2185     }
       
  2186 
       
  2187   protected:
       
  2188 
       
  2189     /// \brief Gives back true when the SectionReader can process 
       
  2190     /// the section with the given header line.
       
  2191     ///
       
  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;
       
  2197       std::string id;
       
  2198       ls >> command >> id;
       
  2199       return command == "@nodemaps" && name == id;
       
  2200     }
       
  2201 
       
  2202     /// \brief Reader function of the section.
       
  2203     ///
       
  2204     /// It reads the content of the section.
       
  2205     virtual void read(std::istream& is) {
       
  2206       std::vector<_reader_bits::MapReaderBase<Node>* > index;
       
  2207       std::string line;
       
  2208 
       
  2209       {
       
  2210         getline(is, line);
       
  2211         std::istringstream ls(line);
       
  2212         std::string id;
       
  2213         while (ls >> id) {
       
  2214           typename MapReaders::iterator it = readers.find(id);
       
  2215           if (it != readers.end()) {
       
  2216             it->second->touch();
       
  2217             index.push_back(it->second);
       
  2218           } else {
       
  2219             index.push_back(&skipper);
       
  2220           }
       
  2221         }
       
  2222       }
       
  2223       for (typename MapReaders::iterator it = readers.begin();
       
  2224 	   it != readers.end(); ++it) {
       
  2225 	if (!it->second->touched()) {
       
  2226 	  ErrorMessage msg;
       
  2227 	  msg << "Map not found in file: " << it->first;
       
  2228 	  throw IoParameterError(msg.message());
       
  2229 	}
       
  2230       }
       
  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);
       
  2236 	}
       
  2237       }
       
  2238     }
       
  2239 
       
  2240     virtual void missing() {
       
  2241       if (readers.empty()) return;
       
  2242       ErrorMessage msg;
       
  2243       msg << "NodeMap section not found in file: @nodemaps " << name;
       
  2244       throw IoParameterError(msg.message());
       
  2245     }
       
  2246 
       
  2247   private:
       
  2248 
       
  2249     typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
       
  2250     MapReaders readers;
       
  2251    
       
  2252     const Graph& graph;   
       
  2253     std::string name;
       
  2254     _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
       
  2255     std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader;
       
  2256 
       
  2257   };
       
  2258 
       
  2259   /// \ingroup section_io
       
  2260   /// \brief SectionReader for reading extra edge maps.
       
  2261   ///
       
  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.
       
  2266   ///
       
  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.
       
  2271   ///
       
  2272   /// \relates LemonReader
       
  2273   template <typename _Graph, typename _Traits = DefaultReaderTraits>
       
  2274   class EdgeMapReader : public LemonReader::SectionReader {
       
  2275     typedef LemonReader::SectionReader Parent;
       
  2276   public:
       
  2277 
       
  2278     typedef _Graph Graph;
       
  2279     typedef typename Graph::Edge Edge;
       
  2280     typedef _Traits Traits;
       
  2281     typedef typename Traits::Skipper DefaultSkipper;
       
  2282 
       
  2283     /// \brief Constructor.
       
  2284     ///
       
  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));
       
  2297     } 
       
  2298 
       
  2299 
       
  2300     /// \brief Destructor.
       
  2301     ///
       
  2302     /// Destructor for EdgeMapReader.
       
  2303     virtual ~EdgeMapReader() {
       
  2304       for (typename MapReaders::iterator it = readers.begin(); 
       
  2305 	   it != readers.end(); ++it) {
       
  2306 	delete it->second;
       
  2307       }
       
  2308     }
       
  2309 
       
  2310   private:
       
  2311     EdgeMapReader(const EdgeMapReader&);
       
  2312     void operator=(const EdgeMapReader&);
       
  2313   
       
  2314   public:
       
  2315 
       
  2316     /// \brief Add a new edge map reader command for the reader.
       
  2317     ///
       
  2318     /// Add a new edge map reader command for the reader.
       
  2319     template <typename Map>
       
  2320     EdgeMapReader& readEdgeMap(std::string label, Map& map) {
       
  2321       return _readMap<
       
  2322 	typename Traits::template Reader<typename Map::Value>, Map,
       
  2323 	typename _reader_bits::Arg<Map>::Type>(label, map);
       
  2324     }
       
  2325 
       
  2326     template <typename Map>
       
  2327     EdgeMapReader& readEdgeMap(std::string label, const Map& map) {
       
  2328       return _readMap<
       
  2329 	typename Traits::template Reader<typename Map::Value>, Map,
       
  2330 	typename _reader_bits::Arg<Map>::Type>(label, map);
       
  2331     }
       
  2332 
       
  2333     /// \brief Add a new edge map reader command for the reader.
       
  2334     ///
       
  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>
       
  2340 	(label, map, ir);
       
  2341     }
       
  2342 
       
  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>
       
  2347 	(label, map, ir);
       
  2348     }
       
  2349 
       
  2350   private:
       
  2351 
       
  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()) {
       
  2358 	ErrorMessage msg;
       
  2359 	msg << "Multiple read rule for map: " << label;
       
  2360 	throw IoParameterError(msg.message());
       
  2361       }      
       
  2362       readers.insert(
       
  2363 	make_pair(label, new _reader_bits::
       
  2364 		  MapReader<Edge, Map, ItemReader>(map, ir)));
       
  2365       return *this;
       
  2366     }
       
  2367 
       
  2368   public:
       
  2369 
       
  2370     /// \brief Add a new edge map skipper command for the reader.
       
  2371     ///
       
  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()) {
       
  2377 	ErrorMessage msg;
       
  2378 	msg << "Multiple read rule for map: " << label;
       
  2379 	throw IoParameterError(msg.message());
       
  2380       }
       
  2381       readers.insert(make_pair(label, new _reader_bits::
       
  2382 			       SkipReader<Edge, ItemReader>(ir)));
       
  2383       return *this;
       
  2384     }
       
  2385 
       
  2386   protected:
       
  2387 
       
  2388     /// \brief Gives back true when the SectionReader can process 
       
  2389     /// the section with the given header line.
       
  2390     ///
       
  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;
       
  2396       std::string id;
       
  2397       ls >> command >> id;
       
  2398       return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
       
  2399     }
       
  2400 
       
  2401     /// \brief Reader function of the section.
       
  2402     ///
       
  2403     /// It reads the content of the section.
       
  2404     virtual void read(std::istream& is) {
       
  2405       std::vector<_reader_bits::MapReaderBase<Edge>* > index;
       
  2406       std::string line;
       
  2407 
       
  2408       {
       
  2409         getline(is, line);
       
  2410         std::istringstream ls(line);
       
  2411         std::string id;
       
  2412         while (ls >> id) {
       
  2413           typename MapReaders::iterator it = readers.find(id);
       
  2414           if (it != readers.end()) {
       
  2415             it->second->touch();
       
  2416             index.push_back(it->second);
       
  2417           } else {
       
  2418             index.push_back(&skipper);
       
  2419           }
       
  2420         }
       
  2421       }
       
  2422       for (typename MapReaders::iterator it = readers.begin();
       
  2423 	   it != readers.end(); ++it) {
       
  2424 	if (!it->second->touched()) {
       
  2425 	  ErrorMessage msg;
       
  2426 	  msg << "Map not found in file: " << it->first;
       
  2427 	  throw IoParameterError(msg.message());
       
  2428 	}
       
  2429       }
       
  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);
       
  2435 	}
       
  2436       }
       
  2437     }
       
  2438 
       
  2439     virtual void missing() {
       
  2440       if (readers.empty()) return;
       
  2441       ErrorMessage msg;
       
  2442       msg << "EdgeMap section not found in file: @edgemaps " << name;
       
  2443       throw IoParameterError(msg.message());
       
  2444     }
       
  2445 
       
  2446   private:
       
  2447 
       
  2448     typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
       
  2449     MapReaders readers;
       
  2450    
       
  2451     const Graph& graph;   
       
  2452     std::string name;
       
  2453     _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
       
  2454     std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader;
       
  2455 
       
  2456   };
       
  2457 
       
  2458   /// \ingroup section_io
       
  2459   /// \brief SectionReader for reading extra undirected edge maps.
       
  2460   ///
       
  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
       
  2465   /// edge maps.
       
  2466   ///
       
  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.
       
  2471   ///
       
  2472   /// \relates LemonReader
       
  2473   template <typename _Graph, typename _Traits = DefaultReaderTraits>
       
  2474   class UEdgeMapReader : public LemonReader::SectionReader {
       
  2475     typedef LemonReader::SectionReader Parent;
       
  2476   public:
       
  2477 
       
  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;
       
  2483 
       
  2484     /// \brief Constructor.
       
  2485     ///
       
  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));
       
  2497     } 
       
  2498 
       
  2499 
       
  2500     /// \brief Destructor.
       
  2501     ///
       
  2502     /// Destructor for UEdgeMapReader.
       
  2503     virtual ~UEdgeMapReader() {
       
  2504       for (typename MapReaders::iterator it = readers.begin(); 
       
  2505 	   it != readers.end(); ++it) {
       
  2506 	delete it->second;
       
  2507       }
       
  2508     }
       
  2509 
       
  2510   private:
       
  2511     UEdgeMapReader(const UEdgeMapReader&);
       
  2512     void operator=(const UEdgeMapReader&);
       
  2513   
       
  2514   public:
       
  2515 
       
  2516     /// \brief Add a new undirected edge map reader command for the
       
  2517     /// reader.
       
  2518     ///
       
  2519     /// Add a new undirected edge map reader command for the reader.
       
  2520     template <typename Map>
       
  2521     UEdgeMapReader& readUEdgeMap(std::string label, Map& map) {
       
  2522       return _readMap<
       
  2523 	typename Traits::template Reader<typename Map::Value>, Map,
       
  2524 	typename _reader_bits::Arg<Map>::Type>(label, map);
       
  2525     }
       
  2526 
       
  2527     template <typename Map>
       
  2528     UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) {
       
  2529       return _readMap<
       
  2530 	typename Traits::template Reader<typename Map::Value>, Map,
       
  2531 	typename _reader_bits::Arg<Map>::Type>(label, map);
       
  2532     }
       
  2533 
       
  2534     /// \brief Add a new undirected edge map reader command for the
       
  2535     /// reader.
       
  2536     ///
       
  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>
       
  2542 	(label, map, ir);
       
  2543     }
       
  2544 
       
  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>
       
  2549 	(label, map, ir);
       
  2550     }
       
  2551 
       
  2552   private:
       
  2553 
       
  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()) {
       
  2560 	ErrorMessage msg;
       
  2561 	msg << "Multiple read rule for map: " << label;
       
  2562 	throw IoParameterError(msg.message());
       
  2563       }      
       
  2564       readers.insert(
       
  2565 	make_pair(label, new _reader_bits::
       
  2566 		  MapReader<UEdge, Map, ItemReader>(map, ir)));
       
  2567       return *this;
       
  2568     }
       
  2569 
       
  2570   public:
       
  2571 
       
  2572     /// \brief Add a new undirected edge map skipper command for the
       
  2573     /// reader.
       
  2574     ///
       
  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()) {
       
  2580 	ErrorMessage msg;
       
  2581 	msg << "Multiple read rule for map: " << label;
       
  2582 	throw IoParameterError(msg.message());
       
  2583       }
       
  2584       readers.insert(make_pair(label, new _reader_bits::
       
  2585 			       SkipReader<Edge, ItemReader>(ir)));
       
  2586       return *this;
       
  2587     }
       
  2588 
       
  2589     /// \brief Add a new directed edge map reader command for the reader.
       
  2590     ///
       
  2591     /// Add a new directed edge map reader command for the reader.
       
  2592     template <typename Map>
       
  2593     UEdgeMapReader& readEdgeMap(std::string label, Map& map) {
       
  2594       return _readDirMap<
       
  2595 	typename Traits::template Reader<typename Map::Value>, Map,
       
  2596 	typename _reader_bits::Arg<Map>::Type>(label, map);
       
  2597     }
       
  2598 
       
  2599     template <typename Map>
       
  2600     UEdgeMapReader& readEdgeMap(std::string label, const Map& map) {
       
  2601       return _readDirMap<
       
  2602 	typename Traits::template Reader<typename Map::Value>, Map,
       
  2603 	typename _reader_bits::Arg<Map>::Type>(label, map);
       
  2604     }
       
  2605 
       
  2606     /// \brief Add a new directed edge map reader command for the reader.
       
  2607     ///
       
  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);
       
  2614     }
       
  2615 
       
  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);
       
  2621     }
       
  2622 
       
  2623   private:
       
  2624 
       
  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);
       
  2634       return *this;      
       
  2635     }
       
  2636 
       
  2637   public:
       
  2638 
       
  2639     /// \brief Add a new directed edge map skipper command for the reader.
       
  2640     ///
       
  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);
       
  2647       return *this;
       
  2648     }
       
  2649 
       
  2650   protected:
       
  2651 
       
  2652     /// \brief Gives back true when the SectionReader can process 
       
  2653     /// the section with the given header line.
       
  2654     ///
       
  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;
       
  2660       std::string id;
       
  2661       ls >> command >> id;
       
  2662       return (command == "@edgemaps" || command == "@uedgemaps") && name == id;
       
  2663     }
       
  2664 
       
  2665     /// \brief Reader function of the section.
       
  2666     ///
       
  2667     /// It reads the content of the section.
       
  2668     virtual void read(std::istream& is) {
       
  2669       std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
       
  2670       std::string line;
       
  2671 
       
  2672       {
       
  2673         getline(is, line);
       
  2674         std::istringstream ls(line);
       
  2675         std::string id;
       
  2676         while (ls >> id) {
       
  2677           typename MapReaders::iterator it = readers.find(id);
       
  2678           if (it != readers.end()) {
       
  2679             it->second->touch();
       
  2680             index.push_back(it->second);
       
  2681           } else {
       
  2682             index.push_back(&skipper);
       
  2683           }
       
  2684         }
       
  2685       }
       
  2686       for (typename MapReaders::iterator it = readers.begin();
       
  2687 	   it != readers.end(); ++it) {
       
  2688 	if (!it->second->touched()) {
       
  2689 	  ErrorMessage msg;
       
  2690 	  msg << "Map not found in file: " << it->first;
       
  2691 	  throw IoParameterError(msg.message());
       
  2692 	}
       
  2693       }
       
  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);
       
  2699 	}
       
  2700       }
       
  2701     }
       
  2702 
       
  2703     virtual void missing() {
       
  2704       if (readers.empty()) return;
       
  2705       ErrorMessage msg;
       
  2706       msg << "UEdgeMap section not found in file: @uedgemaps " << name;
       
  2707       throw IoParameterError(msg.message());
       
  2708     }
       
  2709 
       
  2710   private:
       
  2711 
       
  2712     const Graph& graph;   
       
  2713     std::string name;
       
  2714 
       
  2715     typedef std::map<std::string, 
       
  2716 		     _reader_bits::MapReaderBase<UEdge>*> MapReaders;
       
  2717    
       
  2718     MapReaders readers;
       
  2719     _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
       
  2720 
       
  2721     std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader;
       
  2722 
  2054   };
  2723   };
  2055 
  2724 
  2056   /// \ingroup section_io
  2725   /// \ingroup section_io
  2057   /// \brief SectionReader for retrieve what is in the file.
  2726   /// \brief SectionReader for retrieve what is in the file.
  2058   ///
  2727   ///