src/lemon/lemon_reader.h
changeset 1421 7a21e1414c38
parent 1409 d2d1f8fa187b
child 1423 78502c63f771
equal deleted inserted replaced
1:eebb67bff1d6 2:e15fd46c7cb5
    16 
    16 
    17 ///\ingroup io_group
    17 ///\ingroup io_group
    18 ///\file
    18 ///\file
    19 ///\brief Lemon Format reader.
    19 ///\brief Lemon Format reader.
    20 
    20 
       
    21 
    21 #ifndef LEMON_LEMON_READER_H
    22 #ifndef LEMON_LEMON_READER_H
    22 #define LEMON_LEMON_READER_H
    23 #define LEMON_LEMON_READER_H
       
    24 
    23 
    25 
    24 #include <iostream>
    26 #include <iostream>
    25 #include <fstream>
    27 #include <fstream>
    26 #include <string>
    28 #include <string>
    27 #include <vector>
    29 #include <vector>
    28 #include <algorithm>
    30 #include <algorithm>
    29 #include <map>
    31 #include <map>
    30 #include <memory>
    32 #include <memory>
    31 
    33 
    32 #include <lemon/error.h>
    34 #include <lemon/error.h>
       
    35 #include <lemon/graph_utils.h>
       
    36 #include <lemon/utility.h>
    33 #include <lemon/bits/item_reader.h>
    37 #include <lemon/bits/item_reader.h>
    34 
    38 
    35 
    39 
    36 namespace lemon {
    40 namespace lemon {
       
    41 
       
    42   namespace _reader_bits {
       
    43   
       
    44     template <typename T>
       
    45     bool operator<(T, T) {
       
    46       throw DataFormatError("Id is not comparable");
       
    47     }
       
    48 
       
    49     template <typename T>
       
    50     struct Less {
       
    51       bool operator()(const T& p, const T& q) const {
       
    52 	return p < q;
       
    53       }
       
    54     };
       
    55 
       
    56     template <typename M1, typename M2>
       
    57     class WriteComposeMap {
       
    58     public:
       
    59       typedef True NeedCopy;
       
    60       
       
    61       typedef typename M2::Key Key;
       
    62       typedef typename M1::Value Value;
       
    63 
       
    64       WriteComposeMap(typename SmartParameter<M1>::Type _m1, const M2& _m2) 
       
    65 	: m1(_m1), m2(_m2) {}
       
    66       
       
    67       void set(const Key& key, const Value& value) {
       
    68 	m1.set(m2[key], value);
       
    69       }
       
    70 
       
    71     private:
       
    72       
       
    73       typename SmartReference<M1>::Type m1;
       
    74       typename SmartConstReference<M2>::Type m2;
       
    75       
       
    76     };
       
    77 
       
    78     template <typename M1, typename M2>
       
    79     WriteComposeMap<M1, M2> writeComposeMap(M1& m1, const M2& m2) {
       
    80       return WriteComposeMap<M1, M2>(m1, m2);
       
    81     }
       
    82 
       
    83     template <typename M1, typename M2>
       
    84     WriteComposeMap<M1, M2> writeComposeMap(const M1& m1, const M2& m2) {
       
    85       return WriteComposeMap<M1, M2>(m1, m2);
       
    86     }
       
    87   
       
    88   }
    37 
    89 
    38   /// \ingroup io_group
    90   /// \ingroup io_group
    39   /// \brief Lemon Format reader class.
    91   /// \brief Lemon Format reader class.
    40   /// 
    92   /// 
    41   /// The Lemon Format contains several sections. We do not want to
    93   /// The Lemon Format contains several sections. We do not want to
   336       virtual Item read(std::istream&) const = 0;
   388       virtual Item read(std::istream&) const = 0;
   337 
   389 
   338       virtual InverterBase<_Item>* getInverter() {
   390       virtual InverterBase<_Item>* getInverter() {
   339 	return this;
   391 	return this;
   340       }
   392       }
   341 
       
   342 
       
   343     };
   393     };
   344 
   394 
   345     template <typename _Item, typename _Map, typename _Reader>
   395     template <typename _Item, typename _Map, typename _Reader>
   346     class MapReaderInverter : public InverterBase<_Item> {
   396     class MapReaderInverter : public InverterBase<_Item> {
   347     public:
   397     public:
   348       typedef _Item Item;
   398       typedef _Item Item;
   349       typedef _Reader Reader;
   399       typedef _Reader Reader;
   350       typedef typename Reader::Value Value;
   400       typedef typename Reader::Value Value;
   351       typedef _Map Map;
   401       typedef _Map Map;
   352       typedef std::map<Value, Item> Inverse;
   402       typedef std::map<Value, Item, 
   353 
   403 		       typename _reader_bits::template Less<Value> > Inverse;
   354       Map& map;
   404 
       
   405       typename SmartReference<Map>::Type map;
   355       Reader reader;
   406       Reader reader;
   356       Inverse inverse;
   407       Inverse inverse;
   357 
   408 
   358       MapReaderInverter(Map& _map, const Reader& _reader) 
   409       MapReaderInverter(typename SmartParameter<Map>::Type _map,
       
   410 			const Reader& _reader) 
   359 	: map(_map), reader(_reader) {}
   411 	: map(_map), reader(_reader) {}
   360 
   412 
   361       virtual ~MapReaderInverter() {}
   413       virtual ~MapReaderInverter() {}
   362 
   414 
   363       virtual void read(std::istream& is, const Item& item) {
   415       virtual void read(std::istream& is, const Item& item) {
   380 	  return it->second;
   432 	  return it->second;
   381 	} else {
   433 	} else {
   382 	  throw DataFormatError("Invalid ID error");
   434 	  throw DataFormatError("Invalid ID error");
   383 	}
   435 	}
   384       }      
   436       }      
   385 
       
   386     };
   437     };
   387 
   438 
   388     template <typename _Item, typename _Reader>
   439     template <typename _Item, typename _Reader>
   389     class SkipReaderInverter : public InverterBase<_Item> {
   440     class SkipReaderInverter : public InverterBase<_Item> {
   390     public:
   441     public:
   391       typedef _Item Item;
   442       typedef _Item Item;
   392       typedef _Reader Reader;
   443       typedef _Reader Reader;
   393       typedef typename Reader::Value Value;
   444       typedef typename Reader::Value Value;
   394       typedef std::map<Value, Item> Inverse;
   445       typedef std::map<Value, Item, 
       
   446 		       typename _reader_bits::template Less<Value> > Inverse;
   395 
   447 
   396       Reader reader;
   448       Reader reader;
   397 
   449 
   398       SkipReaderInverter(const Reader& _reader) 
   450       SkipReaderInverter(const Reader& _reader) 
   399 	: reader(_reader) {}
   451 	: reader(_reader) {}
   424 
   476 
   425     private:
   477     private:
   426       Inverse inverse;
   478       Inverse inverse;
   427     };
   479     };
   428 
   480 
   429     // Readers
       
   430 
       
   431     template <typename _Item>    
   481     template <typename _Item>    
   432     class ReaderBase {
   482     class ReaderBase {
   433     public:
   483     public:
   434       typedef _Item Item;
   484       typedef _Item Item;
   435 
   485 
   445       typedef _Map Map;
   495       typedef _Map Map;
   446       typedef _Reader Reader;
   496       typedef _Reader Reader;
   447       typedef typename Reader::Value Value;
   497       typedef typename Reader::Value Value;
   448       typedef _Item Item;
   498       typedef _Item Item;
   449       
   499       
   450       Map& map;
   500       typename SmartReference<Map>::Type map;
   451       Reader reader;
   501       Reader reader;
   452 
   502 
   453       MapReader(Map& _map, const Reader& _reader) 
   503       MapReader(typename SmartParameter<Map>::Type _map, 
       
   504 		const Reader& _reader) 
   454 	: map(_map), reader(_reader) {}
   505 	: map(_map), reader(_reader) {}
   455 
   506 
   456       virtual ~MapReader() {}
   507       virtual ~MapReader() {}
   457 
   508 
   458       virtual void read(std::istream& is, const Item& item) {
   509       virtual void read(std::istream& is, const Item& item) {
   567     ///
   618     ///
   568     /// Constructor for NodeSetReader. It creates the NodeSetReader and
   619     /// Constructor for NodeSetReader. It creates the NodeSetReader and
   569     /// attach it into the given LemonReader. The nodeset reader will
   620     /// attach it into the given LemonReader. The nodeset reader will
   570     /// add the readed nodes to the given Graph. The reader will read
   621     /// add the readed nodes to the given Graph. The reader will read
   571     /// the section when the \c section_id and the \c _id are the same. 
   622     /// the section when the \c section_id and the \c _id are the same. 
   572     NodeSetReader(LemonReader& _reader, Graph& _graph, 
   623     NodeSetReader(LemonReader& _reader, 
       
   624 		  typename SmartParameter<Graph>::Type _graph, 
   573 		  const std::string& _id = std::string(),
   625 		  const std::string& _id = std::string(),
   574 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   626 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   575       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {} 
   627       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {} 
   576 
   628 
   577 
   629 
   593 
   645 
   594     /// \brief Add a new node map reader command for the reader.
   646     /// \brief Add a new node map reader command for the reader.
   595     ///
   647     ///
   596     /// Add a new node map reader command for the reader.
   648     /// Add a new node map reader command for the reader.
   597     template <typename Map>
   649     template <typename Map>
   598     NodeSetReader& readMap(std::string name, Map& map) {
   650     NodeSetReader& readNodeMap(std::string name, Map& map) {
   599       return readMap<typename Traits::
   651       return _readMap<
   600 	template Reader<typename Map::Value>, Map>(name, map);
   652 	typename Traits::template Reader<typename Map::Value>, Map,
       
   653 	typename SmartParameter<Map>::Type>(name, map);
       
   654     }
       
   655 
       
   656     template <typename Map>
       
   657     NodeSetReader& readNodeMap(std::string name, const Map& map) {
       
   658       return _readMap<
       
   659 	typename Traits::template Reader<typename Map::Value>, Map,
       
   660 	typename SmartParameter<Map>::Type>(name, map);
   601     }
   661     }
   602 
   662 
   603     /// \brief Add a new node map reader command for the reader.
   663     /// \brief Add a new node map reader command for the reader.
   604     ///
   664     ///
   605     /// Add a new node map reader command for the reader.
   665     /// Add a new node map reader command for the reader.
   606     template <typename Reader, typename Map>
   666     template <typename Reader, typename Map>
   607     NodeSetReader& readMap(std::string name, Map& map, 
   667     NodeSetReader& readNodeMap(std::string name, Map& map, 
   608 			     const Reader& reader = Reader()) {
   668 			       const Reader& reader = Reader()) {
       
   669       return _readMap<
       
   670 	typename Traits::template Reader<typename Map::Value>, Map,
       
   671 	typename SmartParameter<Map>::Type>(name, map, reader);
       
   672     }
       
   673 
       
   674     template <typename Reader, typename Map>
       
   675     NodeSetReader& readNodeMap(std::string name, const Map& map, 
       
   676 			       const Reader& reader = Reader()) {
       
   677       return _readMap<
       
   678 	typename Traits::template Reader<typename Map::Value>, Map, 
       
   679 	typename SmartParameter<Map>::Type>(name, map, reader);
       
   680     }
       
   681 
       
   682   private:
       
   683 
       
   684     template <typename Reader, typename Map, typename MapParameter>
       
   685     NodeSetReader& _readMap(std::string name, MapParameter map, 
       
   686 			    const Reader& reader = Reader()) {
   609       if (readers.find(name) != readers.end()) {
   687       if (readers.find(name) != readers.end()) {
   610 	ErrorMessage msg;
   688 	ErrorMessage msg;
   611 	msg << "Multiple read rule for node map: " << name;
   689 	msg << "Multiple read rule for node map: " << name;
   612 	throw IOParameterError(msg.message());
   690 	throw IOParameterError(msg.message());
   613       }
   691       }
   614       readers.insert(
   692       readers.insert(
   615 	make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
   693 	make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
   616       return *this;
   694       return *this;
   617     }
   695     }
   618 
   696 
       
   697   public:
       
   698 
   619     /// \brief Add a new node map skipper command for the reader.
   699     /// \brief Add a new node map skipper command for the reader.
   620     ///
   700     ///
   621     /// Add a new node map skipper command for the reader.
   701     /// Add a new node map skipper command for the reader.
   622     template <typename Reader>
   702     template <typename Reader>
   623     NodeSetReader& skipMap(std::string name, 
   703     NodeSetReader& skipNodeMap(std::string name, 
   624 			   const Reader& reader = Reader()) {
   704 			   const Reader& reader = Reader()) {
   625       if (readers.find(name) != readers.end()) {
   705       if (readers.find(name) != readers.end()) {
   626 	ErrorMessage msg;
   706 	ErrorMessage msg;
   627 	msg << "Multiple read rule for node map: " << name;
   707 	msg << "Multiple read rule for node map: " << name;
   628 	throw IOParameterError(msg.message());
   708 	throw IOParameterError(msg.message());
   634   protected:
   714   protected:
   635 
   715 
   636     /// \brief Gives back true when the SectionReader can process 
   716     /// \brief Gives back true when the SectionReader can process 
   637     /// the section with the given header line.
   717     /// the section with the given header line.
   638     ///
   718     ///
   639     /// It gives back true when the header line starts with \c @nodeset,
   719     /// It gives back true when the header line starts with \c \@nodeset,
   640     /// and the header line's id and the nodeset's id are the same.
   720     /// and the header line's id and the nodeset's id are the same.
   641     virtual bool header(const std::string& line) {
   721     virtual bool header(const std::string& line) {
   642       std::istringstream ls(line);
   722       std::istringstream ls(line);
   643       std::string command;
   723       std::string command;
   644       std::string name;
   724       std::string name;
   688 
   768 
   689     /// \brief Gives back the node by its id.
   769     /// \brief Gives back the node by its id.
   690     ///
   770     ///
   691     /// It reads an id from the stream and gives back which node belongs to
   771     /// It reads an id from the stream and gives back which node belongs to
   692     /// it. It is possible only if there was read an "id" named map.
   772     /// it. It is possible only if there was read an "id" named map.
   693     typename Graph::Node readId(std::istream& is) const {
   773     Item readId(std::istream& is) const {
   694       return inverter->read(is);
   774       return inverter->read(is);
   695     } 
   775     } 
   696 
   776 
   697   private:
   777   private:
   698 
   778 
   699     typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
   779     typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
   700     MapReaders readers;
   780     MapReaders readers;
   701    
   781    
   702     Graph& graph;   
   782     typename SmartReference<Graph>::Type graph;   
   703     std::string id;
   783     std::string id;
   704     SkipReader<Item, DefaultSkipper> skipper;
   784     SkipReader<Item, DefaultSkipper> skipper;
   705 
   785 
   706     std::auto_ptr<InverterBase<Item> > inverter;
   786     std::auto_ptr<InverterBase<Item> > inverter;
   707   };
   787   };
   712   /// The lemon format can store multiple graph edgesets with several maps.
   792   /// The lemon format can store multiple graph edgesets with several maps.
   713   /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
   793   /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
   714   /// \c edgeset_id may be empty.
   794   /// \c edgeset_id may be empty.
   715   ///
   795   ///
   716   /// The first line of the section contains the names of the maps separated
   796   /// The first line of the section contains the names of the maps separated
   717   /// with white spaces. Each next lines describes a node in the nodeset. The
   797   /// with white spaces. Each next lines describes an edge in the edgeset. The
   718   /// line contains the two nodes' id and the mapped values for each map.
   798   /// line contains the source and the target nodes' id and the mapped 
       
   799   /// values for each map.
   719   ///
   800   ///
   720   /// If the edgeset contains an \c "id" named map then it will be regarded
   801   /// If the edgeset contains an \c "id" named map then it will be regarded
   721   /// as id map. This map should contain only unique values and when the 
   802   /// as id map. This map should contain only unique values and when the 
   722   /// \c readId() member will read a value from the given stream it will
   803   /// \c readId() member will read a value from the given stream it will
   723   /// give back that edge which is mapped to this value.
   804   /// give back that edge which is mapped to this value.
   744     /// add the readed edges to the given Graph. It will use the given
   825     /// add the readed edges to the given Graph. It will use the given
   745     /// node id reader to read the source and target nodes of the edges.
   826     /// node id reader to read the source and target nodes of the edges.
   746     /// The reader will read the section only if the \c _id and the 
   827     /// The reader will read the section only if the \c _id and the 
   747     /// \c edgset_id are the same. 
   828     /// \c edgset_id are the same. 
   748     template <typename NodeIdReader>
   829     template <typename NodeIdReader>
   749     EdgeSetReader(LemonReader& _reader, Graph& _graph, 
   830     EdgeSetReader(LemonReader& _reader, 
       
   831 		  typename SmartParameter<Graph>::Type _graph, 
   750 		  const NodeIdReader& _nodeIdReader, 
   832 		  const NodeIdReader& _nodeIdReader, 
   751 		  const std::string& _id = std::string(),
   833 		  const std::string& _id = std::string(),
   752 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   834 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
   753       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
   835       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
   754 	nodeIdReader(new IdReader<typename Graph::Node, NodeIdReader>
   836 	nodeIdReader(new IdReader<typename Graph::Node, NodeIdReader>
   772 
   854 
   773     /// \brief Add a new edge map reader command for the reader.
   855     /// \brief Add a new edge map reader command for the reader.
   774     ///
   856     ///
   775     /// Add a new edge map reader command for the reader.
   857     /// Add a new edge map reader command for the reader.
   776     template <typename Map>
   858     template <typename Map>
   777     EdgeSetReader& readMap(std::string name, Map& map) {
   859     EdgeSetReader& readEdgeMap(std::string name, Map& map) {
   778       return readMap<typename Traits::
   860       return _readMap<
   779 	template Reader<typename Map::Value>, Map>(name, map);
   861 	typename Traits::template Reader<typename Map::Value>, Map,
       
   862 	typename SmartParameter<Map>::Type>(name, map);
       
   863     }
       
   864 
       
   865     template <typename Map>
       
   866     EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
       
   867       return _readMap<
       
   868 	typename Traits::template Reader<typename Map::Value>, Map,
       
   869 	typename SmartParameter<Map>::Type>(name, map);
   780     }
   870     }
   781 
   871 
   782     /// \brief Add a new edge map reader command for the reader.
   872     /// \brief Add a new edge map reader command for the reader.
   783     ///
   873     ///
   784     /// Add a new edge map reader command for the reader.
   874     /// Add a new edge map reader command for the reader.
   785     template <typename Reader, typename Map>
   875     template <typename Reader, typename Map>
   786     EdgeSetReader& readMap(std::string name, Map& map, 
   876     EdgeSetReader& readEdgeMap(std::string name, Map& map, 
   787 			     const Reader& reader = Reader()) {
   877 			   const Reader& reader = Reader()) {
       
   878       return _readMap<
       
   879 	typename Traits::template Reader<typename Map::Value>, Map,
       
   880 	typename SmartParameter<Map>::Type>(name, map, reader);
       
   881     }
       
   882 
       
   883     template <typename Reader, typename Map>
       
   884     EdgeSetReader& readEdgeMap(std::string name, const Map& map, 
       
   885 			       const Reader& reader = Reader()) {
       
   886       return _readMap<
       
   887 	typename Traits::template Reader<typename Map::Value>, Map,
       
   888 	typename SmartParameter<Map>::Type>(name, map, reader);
       
   889     }
       
   890 
       
   891   private:
       
   892 
       
   893     template <typename Reader, typename Map, typename MapParameter>
       
   894     EdgeSetReader& _readMap(std::string name, MapParameter map, 
       
   895 			    const Reader& reader = Reader()) {
   788       if (readers.find(name) != readers.end()) {
   896       if (readers.find(name) != readers.end()) {
   789 	ErrorMessage msg;
   897 	ErrorMessage msg;
   790 	msg << "Multiple read rule for edge map: " << name;
   898 	msg << "Multiple read rule for edge map: " << name;
   791 	throw IOParameterError(msg.message());
   899 	throw IOParameterError(msg.message());
   792       }
   900       }
   793       readers.insert(
   901       readers.insert(
   794 	make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
   902 	make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
   795       return *this;
   903       return *this;
   796     }
   904     }
   797 
   905 
       
   906   public:
       
   907 
   798     /// \brief Add a new edge map skipper command for the reader.
   908     /// \brief Add a new edge map skipper command for the reader.
   799     ///
   909     ///
   800     /// Add a new edge map skipper command for the reader.
   910     /// Add a new edge map skipper command for the reader.
   801     template <typename Reader>
   911     template <typename Reader>
   802     EdgeSetReader& skipMap(std::string name, 
   912     EdgeSetReader& skipEdgeMap(std::string name, 
   803 			   const Reader& reader = Reader()) {
   913 			       const Reader& reader = Reader()) {
   804       if (readers.find(name) != readers.end()) {
   914       if (readers.find(name) != readers.end()) {
   805 	ErrorMessage msg;
   915 	ErrorMessage msg;
   806 	msg << "Multiple read rule for node map: " << name;
   916 	msg << "Multiple read rule for edge map: " << name;
   807 	throw IOParameterError(msg.message());
   917 	throw IOParameterError(msg.message());
   808       }
   918       }
   809       readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
   919       readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
   810       return *this;
   920       return *this;
   811     }
   921     }
   813   protected:
   923   protected:
   814 
   924 
   815     /// \brief Gives back true when the SectionReader can process 
   925     /// \brief Gives back true when the SectionReader can process 
   816     /// the section with the given header line.
   926     /// the section with the given header line.
   817     ///
   927     ///
   818     /// It gives back true when the header line starts with \c @edgeset,
   928     /// It gives back true when the header line starts with \c \@edgeset,
   819     /// and the header line's id and the edgeset's id are the same.
   929     /// and the header line's id and the edgeset's id are the same.
   820     virtual bool header(const std::string& line) {
   930     virtual bool header(const std::string& line) {
   821       std::istringstream ls(line);
   931       std::istringstream ls(line);
   822       std::string command;
   932       std::string command;
   823       std::string name;
   933       std::string name;
   869 
   979 
   870     /// \brief Gives back the edge by its id.
   980     /// \brief Gives back the edge by its id.
   871     ///
   981     ///
   872     /// It reads an id from the stream and gives back which edge belongs to
   982     /// It reads an id from the stream and gives back which edge belongs to
   873     /// it. It is possible only if there was read an "id" named map.
   983     /// it. It is possible only if there was read an "id" named map.
   874     typename Graph::Edge readId(std::istream& is) const {
   984     Item readId(std::istream& is) const {
   875       return inverter->read(is);
   985       return inverter->read(is);
   876     } 
   986     } 
   877 
   987 
   878   private:
   988   private:
   879 
   989 
   880     typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
   990     typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
   881     MapReaders readers;
   991     MapReaders readers;
   882    
   992    
   883     Graph& graph;   
   993     typename SmartReference<Graph>::Type graph;   
       
   994     std::string id;
       
   995     SkipReader<Item, DefaultSkipper> skipper;
       
   996 
       
   997     std::auto_ptr<InverterBase<Item> > inverter;
       
   998     std::auto_ptr<IdReaderBase<typename Graph::Node> > nodeIdReader;
       
   999   };
       
  1000 
       
  1001   /// \ingroup io_group
       
  1002   /// \brief SectionReader for reading a undirected graph's edgeset.
       
  1003   ///
       
  1004   /// The lemon format can store multiple undirected edgesets with several 
       
  1005   /// maps. The undirected edgeset section's header line is \c \@undiredgeset 
       
  1006   /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
       
  1007   ///
       
  1008   /// The first line of the section contains the names of the maps separated
       
  1009   /// with white spaces. Each next lines describes an edge in the edgeset. The
       
  1010   /// line contains the connected nodes' id and the mapped values for each map.
       
  1011   ///
       
  1012   /// The section can handle the directed as a syntactical sugar. Two
       
  1013   /// undirected edge map describes one directed edge map. This two maps
       
  1014   /// are the forward map and the backward map and the names of this map
       
  1015   /// is near the same just with a prefix \c '+' or \c '-' character 
       
  1016   /// difference.
       
  1017   ///
       
  1018   /// If the edgeset contains an \c "id" named map then it will be regarded
       
  1019   /// as id map. This map should contain only unique values and when the 
       
  1020   /// \c readId() member will read a value from the given stream it will
       
  1021   /// give back that undiricted edge which is mapped to this value.
       
  1022   ///
       
  1023   /// The undirected edgeset reader needs a node id reader to identify which 
       
  1024   /// nodes have to be connected. If a NodeSetReader reads an "id" named map,
       
  1025   /// it will be able to resolve the nodes by ids.
       
  1026   ///
       
  1027   /// \relates LemonReader
       
  1028   template <typename _Graph, typename _Traits = DefaultReaderTraits>
       
  1029   class UndirEdgeSetReader : public CommonSectionReaderBase {
       
  1030     typedef CommonSectionReaderBase Parent;
       
  1031   public:
       
  1032 
       
  1033     typedef _Graph Graph;
       
  1034     typedef _Traits Traits;
       
  1035     typedef typename Graph::UndirEdge Item;
       
  1036     typedef typename Traits::Skipper DefaultSkipper;
       
  1037 
       
  1038     /// \brief Constructor.
       
  1039     ///
       
  1040     /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader 
       
  1041     /// and attach it into the given LemonReader. The undirected edgeset 
       
  1042     /// reader will add the readed undirected edges to the given Graph. It 
       
  1043     /// will use the given node id reader to read the source and target 
       
  1044     /// nodes of the edges. The reader will read the section only if the 
       
  1045     /// \c _id and the \c undiredgset_id are the same. 
       
  1046     template <typename NodeIdReader>
       
  1047     UndirEdgeSetReader(LemonReader& _reader, 
       
  1048 		       typename SmartParameter<Graph>::Type _graph, 
       
  1049 		       const NodeIdReader& _nodeIdReader, 
       
  1050 		       const std::string& _id = std::string(),
       
  1051 		       const DefaultSkipper& _skipper = DefaultSkipper()) 
       
  1052       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
       
  1053 	nodeIdReader(new IdReader<typename Graph::Node, NodeIdReader>
       
  1054 		     (_nodeIdReader)) {} 
       
  1055 
       
  1056     /// \brief Destructor.
       
  1057     ///
       
  1058     /// Destructor for UndirEdgeSetReader.
       
  1059     virtual ~UndirEdgeSetReader() {
       
  1060       for (typename MapReaders::iterator it = readers.begin(); 
       
  1061 	   it != readers.end(); ++it) {
       
  1062 	delete it->second;
       
  1063       }
       
  1064     }
       
  1065 
       
  1066   private:
       
  1067     UndirEdgeSetReader(const UndirEdgeSetReader&);
       
  1068     void operator=(const UndirEdgeSetReader&);
       
  1069 
       
  1070   public:
       
  1071 
       
  1072     /// \brief Add a new undirected edge map reader command for the reader.
       
  1073     ///
       
  1074     /// Add a new edge undirected map reader command for the reader.
       
  1075     template <typename Map>
       
  1076     UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) {
       
  1077       return _readMap<
       
  1078 	typename Traits::template Reader<typename Map::Value>, Map, 
       
  1079 	typename SmartParameter<Map>::Type>(name, map);
       
  1080     }
       
  1081 
       
  1082     template <typename Map>
       
  1083     UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) {
       
  1084       return _readMap<
       
  1085 	typename Traits::template Reader<typename Map::Value>, Map, 
       
  1086 	typename SmartParameter<Map>::Type>(name, map);
       
  1087     }
       
  1088 
       
  1089     /// \brief Add a new undirected edge map reader command for the reader.
       
  1090     ///
       
  1091     /// Add a new edge undirected map reader command for the reader.
       
  1092     template <typename Reader, typename Map>
       
  1093     UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map, 
       
  1094 					 const Reader& reader = Reader()) {
       
  1095       return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
       
  1096 	(name, map, reader);
       
  1097     }
       
  1098 
       
  1099     template <typename Reader, typename Map>
       
  1100     UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map, 
       
  1101 					 const Reader& reader = Reader()) {
       
  1102       return _readMap<Reader, Map, typename SmartParameter<Map>::Type >
       
  1103 	(name, map, reader);
       
  1104     }
       
  1105 
       
  1106   private:
       
  1107 
       
  1108     template <typename Reader, typename Map, typename MapParameter>
       
  1109     UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
       
  1110 				 const Reader& reader = Reader()) {
       
  1111       if (readers.find(name) != readers.end()) {
       
  1112 	ErrorMessage msg;
       
  1113 	msg << "Multiple read rule for edge map: " << name;
       
  1114 	throw IOParameterError(msg.message());
       
  1115       }
       
  1116       readers.insert(
       
  1117 	make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
       
  1118       return *this;
       
  1119     }
       
  1120 
       
  1121   public:
       
  1122 
       
  1123     /// \brief Add a new undirected edge map skipper command for the reader.
       
  1124     ///
       
  1125     /// Add a new undirected edge map skipper command for the reader.
       
  1126     template <typename Reader>
       
  1127     UndirEdgeSetReader& skipUndirEdgeMap(std::string name, 
       
  1128 					 const Reader& reader = Reader()) {
       
  1129       if (readers.find(name) != readers.end()) {
       
  1130 	ErrorMessage msg;
       
  1131 	msg << "Multiple read rule for node map: " << name;
       
  1132 	throw IOParameterError(msg.message());
       
  1133       }
       
  1134       readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
       
  1135       return *this;
       
  1136     }
       
  1137 
       
  1138     /// \brief Add a new directed edge map reader command for the reader.
       
  1139     ///
       
  1140     /// Add a new directed edge map reader command for the reader.
       
  1141     template <typename Map>
       
  1142     UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) {
       
  1143       return _readDirMap<
       
  1144 	typename Traits::template Reader<typename Map::Value>, Map,
       
  1145 	typename SmartParameter<Map>::Type>(name, map);
       
  1146     }
       
  1147 
       
  1148     template <typename Map>
       
  1149     UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
       
  1150       return _readDirMap<
       
  1151 	typename Traits::template Reader<typename Map::Value>, Map,
       
  1152 	typename SmartParameter<Map>::Type>(name, map);
       
  1153     }
       
  1154 
       
  1155     /// \brief Add a new directed edge map reader command for the reader.
       
  1156     ///
       
  1157     /// Add a new directed edge map reader command for the reader.
       
  1158     template <typename Reader, typename Map>
       
  1159     UndirEdgeSetReader& readEdgeMap(std::string name, Map& map, 
       
  1160 				    const Reader& reader = Reader()) {
       
  1161       return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
       
  1162 	(name, map, reader);
       
  1163     }
       
  1164 
       
  1165     template <typename Reader, typename Map>
       
  1166     UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map, 
       
  1167 				    const Reader& reader = Reader()) {
       
  1168       return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
       
  1169 	(name, map, reader);
       
  1170     }
       
  1171 
       
  1172   private:
       
  1173 
       
  1174     template <typename Reader, typename Map, typename MapParameter>
       
  1175     UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
       
  1176 				    const Reader& reader = Reader()) {
       
  1177       readMap("+" + name, 
       
  1178 	      _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
       
  1179       readMap("-" + name, 
       
  1180 	      _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
       
  1181       return *this;      
       
  1182     }
       
  1183 
       
  1184   public:
       
  1185 
       
  1186     /// \brief Add a new directed edge map skipper command for the reader.
       
  1187     ///
       
  1188     /// Add a new directed edge map skipper command for the reader.
       
  1189     template <typename Reader>
       
  1190     UndirEdgeSetReader& skipEdgeMap(std::string name, 
       
  1191 				    const Reader& reader = Reader()) {
       
  1192       skipMap("+" + name, reader);
       
  1193       skipMap("-" + name, reader);
       
  1194       return *this;
       
  1195     }
       
  1196 
       
  1197   protected:
       
  1198 
       
  1199     /// \brief Gives back true when the SectionReader can process 
       
  1200     /// the section with the given header line.
       
  1201     ///
       
  1202     /// It gives back true when the header line starts with \c \@undiredgeset,
       
  1203     /// and the header line's id and the edgeset's id are the same.
       
  1204     virtual bool header(const std::string& line) {
       
  1205       std::istringstream ls(line);
       
  1206       std::string command;
       
  1207       std::string name;
       
  1208       ls >> command >> name;
       
  1209       return command == "@undiredgeset" && name == id;
       
  1210     }
       
  1211 
       
  1212     /// \brief Reader function of the section.
       
  1213     ///
       
  1214     /// It reads the content of the section.
       
  1215     virtual void read(std::istream& is) {
       
  1216       std::vector<ReaderBase<Item>* > index;
       
  1217       std::string line;
       
  1218 
       
  1219       getline(is, line);
       
  1220       std::istringstream ls(line);	
       
  1221       while (ls >> id) {
       
  1222 	typename MapReaders::iterator it = readers.find(id);
       
  1223 	if (it != readers.end()) {
       
  1224 	  index.push_back(it->second);
       
  1225 	} else {
       
  1226 	  index.push_back(&skipper);
       
  1227 	}
       
  1228 	if (id == "id" && inverter.get() == 0) {
       
  1229 	  inverter.reset(index.back()->getInverter());
       
  1230 	  index.back() = inverter.get();
       
  1231 	}
       
  1232       }
       
  1233       while (getline(is, line)) {	
       
  1234 	std::istringstream ls(line);
       
  1235 	typename Graph::Node from = nodeIdReader->read(ls);
       
  1236 	typename Graph::Node to = nodeIdReader->read(ls);
       
  1237 	typename Graph::UndirEdge edge = graph.addEdge(from, to);
       
  1238 	for (int i = 0; i < (int)index.size(); ++i) {
       
  1239 	  index[i]->read(ls, edge);
       
  1240 	}
       
  1241       }
       
  1242     }
       
  1243 
       
  1244   public:
       
  1245 
       
  1246     /// \brief Returns true if the edgeset can give back the edge by its id.
       
  1247     ///
       
  1248     /// Returns true if the edgeset can give back the undirected edge by its 
       
  1249     /// id. It is possible only if an "id" named map was read.
       
  1250     bool isIdReader() const {
       
  1251       return inverter.get() != 0;
       
  1252     }
       
  1253 
       
  1254     /// \brief Gives back the undirected edge by its id.
       
  1255     ///
       
  1256     /// It reads an id from the stream and gives back which undirected edge 
       
  1257     /// belongs to it. It is possible only if there was read an "id" named map.
       
  1258     Item readId(std::istream& is) const {
       
  1259       return inverter->read(is);
       
  1260     } 
       
  1261 
       
  1262   private:
       
  1263 
       
  1264     typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
       
  1265     MapReaders readers;
       
  1266    
       
  1267     typename SmartReference<Graph>::Type graph;   
   884     std::string id;
  1268     std::string id;
   885     SkipReader<Item, DefaultSkipper> skipper;
  1269     SkipReader<Item, DefaultSkipper> skipper;
   886 
  1270 
   887     std::auto_ptr<InverterBase<Item> > inverter;
  1271     std::auto_ptr<InverterBase<Item> > inverter;
   888     std::auto_ptr<IdReaderBase<typename Graph::Node> > nodeIdReader;
  1272     std::auto_ptr<IdReaderBase<typename Graph::Node> > nodeIdReader;
   943   protected:
  1327   protected:
   944 
  1328 
   945     /// \brief Gives back true when the SectionReader can process 
  1329     /// \brief Gives back true when the SectionReader can process 
   946     /// the section with the given header line.
  1330     /// the section with the given header line.
   947     ///
  1331     ///
   948     /// It gives back true when the header line start with \c @nodes,
  1332     /// It gives back true when the header line start with \c \@nodes,
   949     /// and the header line's id and the reader's id are the same.
  1333     /// and the header line's id and the reader's id are the same.
   950     virtual bool header(const std::string& line) {
  1334     virtual bool header(const std::string& line) {
   951       std::istringstream ls(line);
  1335       std::istringstream ls(line);
   952       std::string command;
  1336       std::string command;
   953       std::string name;
  1337       std::string name;
  1000     /// \brief Constructor.
  1384     /// \brief Constructor.
  1001     ///
  1385     ///
  1002     /// Constructor for EdgeReader. It creates the EdgeReader and
  1386     /// Constructor for EdgeReader. It creates the EdgeReader and
  1003     /// attach it into the given LemonReader. It will use the given
  1387     /// attach it into the given LemonReader. It will use the given
  1004     /// edge id reader to give back the edges. The reader will read the 
  1388     /// edge id reader to give back the edges. The reader will read the 
  1005     /// section only if the \c _id and the \c nodes_id are the same. 
  1389     /// section only if the \c _id and the \c edges_id are the same. 
  1006     template <typename _IdReader>
  1390     template <typename _IdReader>
  1007     EdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1391     EdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
  1008 	       const std::string& _id = std::string()) 
  1392 	       const std::string& _id = std::string()) 
  1009       : Parent(_reader), id(_id), 
  1393       : Parent(_reader), id(_id), 
  1010 	idReader(new IdReader<typename Graph::Edge, _IdReader>(_idReader)) {} 
  1394 	idReader(new IdReader<typename Graph::Edge, _IdReader>(_idReader)) {} 
  1034   protected:
  1418   protected:
  1035 
  1419 
  1036     /// \brief Gives back true when the SectionReader can process 
  1420     /// \brief Gives back true when the SectionReader can process 
  1037     /// the section with the given header line.
  1421     /// the section with the given header line.
  1038     ///
  1422     ///
  1039     /// It gives back true when the header line start with \c @edges,
  1423     /// It gives back true when the header line start with \c \@edges,
  1040     /// and the header line's id and the reader's id are the same.
  1424     /// and the header line's id and the reader's id are the same.
  1041     virtual bool header(const std::string& line) {
  1425     virtual bool header(const std::string& line) {
  1042       std::istringstream ls(line);
  1426       std::istringstream ls(line);
  1043       std::string command;
  1427       std::string command;
  1044       std::string name;
  1428       std::string name;
  1070     ItemReaders readers;
  1454     ItemReaders readers;
  1071     std::auto_ptr<IdReaderBase<Item> > idReader;
  1455     std::auto_ptr<IdReaderBase<Item> > idReader;
  1072   };
  1456   };
  1073 
  1457 
  1074   /// \ingroup io_group
  1458   /// \ingroup io_group
       
  1459   /// \brief SectionReader for reading labeled undirected edges.
       
  1460   ///
       
  1461   /// The undirected edges section's header line is \c \@undiredges 
       
  1462   /// \c undiredges_id, but the \c undiredges_id may be empty.
       
  1463   ///
       
  1464   /// Each line in the section contains the name of the undirected edge 
       
  1465   /// and then the undirected edge id. 
       
  1466   ///
       
  1467   /// \relates LemonReader
       
  1468   template <typename _Graph>
       
  1469   class UndirEdgeReader : public CommonSectionReaderBase {
       
  1470     typedef CommonSectionReaderBase Parent;
       
  1471     typedef _Graph Graph;
       
  1472     typedef typename Graph::UndirEdge Item;
       
  1473   public:
       
  1474     
       
  1475     /// \brief Constructor.
       
  1476     ///
       
  1477     /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and
       
  1478     /// attach it into the given LemonReader. It will use the given
       
  1479     /// undirected edge id reader to give back the edges. The reader will 
       
  1480     /// read the section only if the \c _id and the \c undiredges_id are 
       
  1481     /// the same. 
       
  1482     template <typename _IdReader>
       
  1483     UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
       
  1484 	       const std::string& _id = std::string()) 
       
  1485       : Parent(_reader), id(_id), 
       
  1486 	idReader(new IdReader<typename Graph::UndirEdge, _IdReader>(_idReader))
       
  1487     {} 
       
  1488 
       
  1489     /// \brief Destructor.
       
  1490     ///
       
  1491     /// Destructor for UndirEdgeReader.
       
  1492     virtual ~UndirEdgeReader() {}
       
  1493   private:
       
  1494     UndirEdgeReader(const UndirEdgeReader&);
       
  1495     void operator=(const UndirEdgeReader&);
       
  1496 
       
  1497   public:
       
  1498 
       
  1499     /// \brief Add an undirected edge reader command for the UndirEdgeReader.
       
  1500     ///
       
  1501     /// Add an undirected edge reader command for the UndirEdgeReader.
       
  1502     void readUndirEdge(const std::string& name, Item& item) {
       
  1503       if (readers.find(name) != readers.end()) {
       
  1504 	ErrorMessage msg;
       
  1505 	msg << "Multiple read rule for edge: " << name;
       
  1506 	throw IOParameterError(msg.message());
       
  1507       }
       
  1508       readers.insert(make_pair(name, &item));
       
  1509     }
       
  1510 
       
  1511   protected:
       
  1512 
       
  1513     /// \brief Gives back true when the SectionReader can process 
       
  1514     /// the section with the given header line.
       
  1515     ///
       
  1516     /// It gives back true when the header line start with \c \@edges,
       
  1517     /// and the header line's id and the reader's id are the same.
       
  1518     virtual bool header(const std::string& line) {
       
  1519       std::istringstream ls(line);
       
  1520       std::string command;
       
  1521       std::string name;
       
  1522       ls >> command >> name;
       
  1523       return command == "@edges" && name == id;
       
  1524     }
       
  1525 
       
  1526     /// \brief Reader function of the section.
       
  1527     ///
       
  1528     /// It reads the content of the section.
       
  1529     virtual void read(std::istream& is) {
       
  1530       std::string line;
       
  1531       while (getline(is, line)) {
       
  1532 	std::istringstream ls(line);
       
  1533 	std::string id;
       
  1534 	ls >> id;
       
  1535 	typename ItemReaders::iterator it = readers.find(id);
       
  1536 	if (it != readers.end()) {
       
  1537 	  *(it->second) = idReader->read(ls); 
       
  1538 	}	
       
  1539       }
       
  1540     }
       
  1541     
       
  1542   private:
       
  1543 
       
  1544     std::string id;
       
  1545 
       
  1546     typedef std::map<std::string, Item*> ItemReaders;
       
  1547     ItemReaders readers;
       
  1548     std::auto_ptr<IdReaderBase<Item> > idReader;
       
  1549   };
       
  1550 
       
  1551   /// \ingroup io_group
  1075   /// \brief SectionReader for attributes.
  1552   /// \brief SectionReader for attributes.
  1076   ///
  1553   ///
  1077   /// The lemon format can store multiple attribute set. Each set has
  1554   /// The lemon format can store multiple attribute set. Each set has
  1078   /// the header line \c \@attributes \c attributeset_id, but the 
  1555   /// the header line \c \@attributes \c attributeset_id, but the 
  1079   /// attributeset_id may be empty.
  1556   /// attributeset_id may be empty.
  1139   protected:
  1616   protected:
  1140 
  1617 
  1141     /// \brief Gives back true when the SectionReader can process 
  1618     /// \brief Gives back true when the SectionReader can process 
  1142     /// the section with the given header line.
  1619     /// the section with the given header line.
  1143     ///
  1620     ///
  1144     /// It gives back true when the header line start with \c @attributes,
  1621     /// It gives back true when the header line start with \c \@attributes,
  1145     /// and the header line's id and the attributeset's id are the same.
  1622     /// and the header line's id and the attributeset's id are the same.
  1146     bool header(const std::string& line) {
  1623     bool header(const std::string& line) {
  1147       std::istringstream ls(line);
  1624       std::istringstream ls(line);
  1148       std::string command;
  1625       std::string command;
  1149       std::string name;
  1626       std::string name;
  1172 
  1649 
  1173     typedef std::map<std::string, ValueReaderBase*> Readers;
  1650     typedef std::map<std::string, ValueReaderBase*> Readers;
  1174     Readers readers;  
  1651     Readers readers;  
  1175   };
  1652   };
  1176 
  1653 
  1177 
       
  1178 }
  1654 }
  1179 #endif
  1655 #endif