lemon/bits/item_reader.h
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1946 17eb3eaad9f8
child 2016 ecb067198349
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

The ResGraphAdaptor is based on this composition.
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 /// @defgroin item_io Item Readers and Writers
    20 /// @ingroup io_groin
    21 /// \brief Item Readers and Writers
    22 /// 
    23 /// The Input-Output classes can handle more data type by example
    24 /// as map or attribute value. Each of these should be written and
    25 /// read some way. The module make possible to do this.  
    26 
    27 /// \ingroup item_io
    28 /// \file
    29 /// \brief Item reader bits for lemon input.
    30 
    31 #ifndef LEMON_BITS_ITEM_READER_H
    32 #define LEMON_BITS_ITEM_READER_H
    33 
    34 #include <iostream>
    35 #include <string>
    36 
    37 #include <vector>
    38 #include <deque>
    39 #include <list>
    40 #include <set>
    41 
    42 namespace lemon {
    43   
    44   template <typename Value>
    45   class DefaultReader;
    46 
    47   /// \ingroup item_io
    48   ///
    49   /// \brief Reader class for quoted strings.
    50   ///
    51   /// Reader class for quoted strings. It can process the escape
    52   /// sequences in the string.
    53   ///
    54   /// \author Balazs Dezso
    55   class QuotedStringReader {
    56   public:
    57     /// \brief The value type of reader.
    58     ///
    59     /// The value type of reader.
    60     typedef std::string Value;
    61     
    62     /// \brief Constructor for the reader.
    63     ///
    64     /// Constructor for the reader. If the given parameter is true
    65     /// the reader processes the escape sequences.
    66     QuotedStringReader(bool _escaped = true) 
    67       : escaped(_escaped) {}
    68     
    69     /// \brief Reads a quoted string from the given stream.
    70     ///
    71     /// Reads a quoted string from the given stream.
    72     void read(std::istream& is, std::string& value) const {
    73       char c;
    74       value.clear();
    75       is >> std::ws;
    76       if (!is.get(c) || c != '\"') 
    77 	throw DataFormatError("Quoted string format error");
    78       while (is.get(c) && c != '\"') {
    79 	if (escaped && c == '\\') {
    80 	  value += readEscape(is);
    81 	} else {
    82 	  value += c;
    83 	}
    84       }
    85       if (!is) throw DataFormatError("Quoted string format error");
    86     }
    87 
    88   private:
    89     
    90     static char readEscape(std::istream& is) {
    91       char c;
    92       switch (is.get(c), c) {
    93       case '\\':
    94 	return '\\';
    95       case '\"':
    96 	return '\"';
    97       case '\'':
    98 	return '\'';
    99       case '\?':
   100 	return '\?';
   101       case 'a':
   102 	return '\a';
   103       case 'b':
   104 	return '\b';
   105       case 'f':
   106 	return '\f';
   107       case 'n':
   108 	return '\n';
   109       case 'r':
   110 	return '\r';
   111       case 't':
   112 	return '\t';
   113       case 'v':
   114 	return '\v';
   115       case 'x':
   116 	{
   117 	  int code;
   118 	  if (!is.get(c) || !isHex(c)) 
   119 	    throw DataFormatError("Escape format error");
   120 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   121 	  else code = code * 16 + valueHex(c);
   122 	  return code;
   123 	}
   124       default:
   125 	{
   126 	  int code;
   127 	  if (!isOct(c)) 
   128 	    throw DataFormatError("Escape format error");
   129 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
   130 	    is.putback(c);
   131 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
   132 	    is.putback(c);
   133 	  else code = code * 8 + valueOct(c);
   134 	  return code;
   135 	}	      
   136       } 
   137     }
   138 
   139     static bool isOct(char c) {
   140       return '0' <= c && c <='7'; 
   141     }
   142     
   143     static int valueOct(char c) {
   144       return c - '0';
   145     }
   146 
   147    static bool isHex(char c) {
   148       return ('0' <= c && c <= '9') || 
   149 	('a' <= c && c <= 'z') || 
   150 	('A' <= c && c <= 'Z'); 
   151     }
   152     
   153     static int valueHex(char c) {
   154       if ('0' <= c && c <= '9') return c - '0';
   155       if ('a' <= c && c <= 'z') return c - 'a' + 10;
   156       return c - 'A' + 10;
   157     }
   158 
   159     bool escaped;
   160   };
   161 
   162   /// \ingroup item_io
   163   /// \brief Reader for standard containers.
   164   ///
   165   /// Reader for back insertable standard containers. The representation
   166   /// of the container is the values enumerated between an open and a
   167   /// close parse. 
   168   ///
   169   /// \author Balazs Dezso
   170   template <
   171     typename _Container, 
   172     typename _ItemReader = DefaultReader<typename _Container::value_type> 
   173   >
   174   class PushBackReader {
   175   public:
   176     typedef _Container Value;
   177     typedef _ItemReader ItemReader;
   178 
   179   private:
   180 
   181     ItemReader item_reader;
   182 
   183   public:
   184 
   185     /// \brief Constructor for InsertReader
   186     ///
   187     /// Constructor for InsertReader
   188     PushBackReader(const ItemReader& _item_reader = ItemReader())
   189       : item_reader(_item_reader) {}
   190 
   191     /// \brief Reads the values into the container from the given stream.
   192     ///
   193     /// Reads the values into the container from the given stream.
   194     void read(std::istream& is, Value& value) const {
   195       char c;
   196       if (!(is >> c) || c != '(') 
   197 	throw DataFormatError("PushBackReader format error");
   198       while (is >> c && c != ')') {
   199 	is.putback(c);
   200 	typename ItemReader::Value item;
   201 	item_reader.read(is, item);
   202 	value.push_back(item);
   203       }
   204       if (!is) throw DataFormatError("PushBackReader format error");
   205     }
   206 
   207   };
   208 
   209   /// \ingroup item_io
   210   ///
   211   /// \brief Reader for standard containers.
   212   ///
   213   /// Reader for insertable standard containers. The representation
   214   /// of the container is the values enumerated between an open and a
   215   /// close parse. 
   216   ///
   217   /// \author Balazs Dezso
   218   template <
   219     typename _Container, 
   220     typename _ItemReader = DefaultReader<typename _Container::value_type> 
   221   >
   222   class InsertReader {
   223   public:
   224     typedef _Container Value;
   225     typedef _ItemReader ItemReader;
   226 
   227   private:
   228 
   229     ItemReader item_reader;
   230 
   231   public:
   232 
   233     /// \brief Constructor for InsertReader
   234     ///
   235     /// Constructor for InsertReader
   236     InsertReader(const ItemReader& _item_reader = ItemReader())
   237       : item_reader(_item_reader) {}
   238 
   239     /// \brief Reads the values into the container from the given stream.
   240     ///
   241     /// Reads the values into the container from the given stream.
   242     void read(std::istream& is, Value& value) const {
   243       char c;
   244       if (!(is >> c) || c != '(') 
   245 	throw DataFormatError("InsertReader format error");
   246       while (is >> c && c != ')') {
   247 	is.putback(c);
   248 	typename ItemReader::Value item;
   249 	item_reader.read(is, item);
   250 	value.insert(item);
   251       }
   252       if (!is) throw DataFormatError("PushBackReader format error");
   253     }
   254 
   255   };
   256 
   257   /// \ingroup item_io
   258   /// \brief Reader for parsed string.
   259   ///
   260   /// Reader for parsed strings. You can define the open and close
   261   /// parse characters. It reads from the input a character sequence
   262   /// which is right parsed.
   263   ///
   264   /// \author Balazs Dezso
   265   class ParsedStringReader {
   266   public:
   267     typedef std::string Value;
   268 
   269     /// \brief Constructor.
   270     ///
   271     /// Constructor for ParsedStringReader. You can give as parameter
   272     /// the open and close parse characters.
   273     ParsedStringReader(char _open = '(', char _close = ')')
   274       : open(_open), close(_close) {}
   275     
   276     
   277     /// \brief Reads the parsed string from the given stream.
   278     ///
   279     /// Reads the parsed string from the given stream.
   280     void read(std::istream& is, Value& value) const {
   281       char c;
   282       if (!(is >> c) || c != open) {
   283 	throw DataFormatError("ParsedStringReader format error");
   284       }
   285       value += c;
   286       int counter = 1;
   287       while (counter > 0 && is >> c) {
   288 	if (c == close) {
   289 	  --counter;
   290 	} else if (c == open) {
   291 	  ++counter;
   292 	}
   293 	value += c;
   294       }
   295       if (!is) {
   296 	throw DataFormatError("ParsedStrinReader format error");
   297       }
   298     }
   299 
   300   private:
   301     char open, close;
   302 
   303   };
   304 
   305   /// \ingroup item_io
   306   /// \brief Reader for read the whole line.
   307   ///
   308   /// Reader for read the whole line.
   309   ///
   310   /// \author Balazs Dezso
   311   class LineReader {
   312   public:
   313     typedef std::string Value;
   314 
   315     /// \brief Constructor.
   316     ///
   317     /// Constructor for the LineReader. If the given parameter is
   318     /// true then the spaces before the first not space character are
   319     /// skipped.
   320     LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
   321     
   322     /// \brief Reads the line from the given stream.
   323     ///
   324     /// Reads the line from the given stream.
   325     void read(std::istream& is, Value& value) const {
   326       if (skipSpaces) is >> std::ws;
   327       if (!getline(is, value)) {
   328 	throw DataFormatError("LineReader format error");
   329       }
   330     }
   331   private:
   332     bool skipSpaces;
   333   };
   334 
   335   /// \ingroup item_io
   336   /// \brief Reader for std::pair.
   337   ///
   338   /// Reader for std::pair.
   339   ///
   340   /// \author Balazs Dezso
   341   template <typename _Pair, 
   342 	    typename _FirstReader = 
   343 	    DefaultReader<typename _Pair::first_type>,
   344 	    typename _SecondReader = 
   345 	    DefaultReader<typename _Pair::second_type> >
   346   class PairReader {
   347   public:
   348     typedef _Pair Value;
   349 
   350     typedef _FirstReader FirstReader;
   351     typedef _SecondReader SecondReader;
   352 
   353   private:
   354 
   355     FirstReader first_reader;
   356     SecondReader second_reader;
   357 
   358   public:
   359     
   360     /// \brief Constructor.
   361     ///
   362     /// Constructor for the PairReader.
   363     PairReader(const FirstReader& _first_reader = FirstReader(), 
   364 	       const SecondReader& _second_reader = SecondReader()) 
   365       : first_reader(_first_reader), second_reader(_second_reader) {}
   366     
   367     /// \brief Reads the pair from the given stream.
   368     ///
   369     /// Reads the pair from the given stream.
   370     void read(std::istream& is, Value& value) const {
   371       char c;
   372       if (!(is >> c) || c != '(') {
   373 	throw DataFormatError("PairReader format error");
   374       }
   375       first_reader.read(is, value.first);
   376       if (!(is >> c) || c != '=') {
   377 	throw DataFormatError("PairReader format error");
   378       }
   379       if (!(is >> c) || c != '>') {
   380 	throw DataFormatError("PairReader format error");
   381       }
   382       second_reader.read(is, value.second);
   383       if (!(is >> c) || c != ')') {
   384 	throw DataFormatError("PairReader format error");
   385       }
   386     }
   387   };
   388 
   389   /// \ingroup item_io
   390   /// 
   391   /// \brief The default item reader template class.
   392   ///
   393   /// The default item reader template class. If some section reader
   394   /// needs to read a value from a stream it will give the default way for it.
   395   ///
   396   /// \author Balazs Dezso
   397   template <typename _Value>
   398   class DefaultReader {
   399   public:
   400     /// The value type.
   401     typedef _Value Value;
   402     /// \brief Reads a value from the given stream.
   403     ///
   404     /// Reads a value from the given stream.
   405     void read(std::istream& is, Value& value) const {
   406       if (!(is >> value)) 
   407 	throw DataFormatError("DefaultReader format error");
   408     }
   409   };
   410 
   411   template <>
   412   class DefaultReader<std::string> {
   413   public:
   414     typedef std::string Value;
   415     
   416     void read(std::istream& is, Value& value) const {
   417       char c;
   418       if (!(is >> std::ws >> c)) return;
   419       is.putback(c);
   420       switch (c) {
   421       case '\"':
   422 	QuotedStringReader().read(is, value);
   423 	break;
   424       case '(':
   425 	ParsedStringReader().read(is, value);
   426 	break;
   427       case '[':
   428 	ParsedStringReader('[', ']').read(is, value);
   429 	break;
   430       case '/':
   431 	ParsedStringReader('/', '/').read(is, value);
   432 	break;
   433       default:
   434 	if (!(is >> value)) 
   435 	  throw DataFormatError("DefaultReader format error");
   436 	break;
   437       }
   438     }
   439     
   440   };
   441 
   442   template <typename Item>
   443   class DefaultReader<std::vector<Item> > 
   444     : public PushBackReader<std::vector<Item> > {};
   445 
   446   template <typename Item>
   447   class DefaultReader<std::deque<Item> > 
   448     : public PushBackReader<std::deque<Item> > {};
   449 
   450   template <typename Item>
   451   class DefaultReader<std::list<Item> > 
   452     : public PushBackReader<std::list<Item> > {};
   453 
   454   template <typename Item>
   455   class DefaultReader<std::set<Item> > 
   456     : public InsertReader<std::set<Item> > {};
   457 
   458   template <typename Key, typename Value>
   459   class DefaultReader<std::map<Key, Value> > 
   460     : public InsertReader<std::map<Key, Value>,
   461 			  DefaultReader<std::pair<Key, Value> > > {};
   462 
   463   template <typename Item>
   464   class DefaultReader<std::multiset<Item> > 
   465     : public InsertReader<std::multiset<Item> > {};
   466 
   467   template <typename Key, typename Value>
   468   class DefaultReader<std::multimap<Key, Value> > 
   469     : public InsertReader<std::multimap<Key, Value>,
   470 			  DefaultReader<std::pair<Key, Value> > > {};
   471 
   472   template <typename First, typename Second>
   473   class DefaultReader<std::pair<First, Second> > 
   474     : public PairReader<std::pair<First, Second> > {};
   475 
   476   /// \ingroup item_io
   477   /// 
   478   /// \brief The default item reader for skipping a value in the stream.
   479   ///
   480   /// The default item reader for skipping a value in the stream.
   481   ///
   482   /// \author Balazs Dezso
   483   class DefaultSkipper : public DefaultReader<std::string> {};
   484 
   485   /// \ingroup item_io  
   486   /// \brief Standard ReaderTraits for the GraphReader class.
   487   ///
   488   /// Standard ReaderTraits for the GraphReader class.
   489   /// It defines standard reading method for all type of value. 
   490   /// \author Balazs Dezso
   491   struct DefaultReaderTraits {
   492 
   493     template <typename _Value>
   494     struct Reader : DefaultReader<_Value> {};
   495 
   496     typedef DefaultSkipper Skipper;
   497 
   498   };
   499 
   500 }
   501 
   502 #endif