Set props.
     3  * This file is a part of LEMON, a generic C++ optimization library
 
     5  * Copyright (C) 2003-2006
 
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     9  * Permission to use, modify and distribute this software is granted
 
    10  * provided that this copyright notice appears in all copies. For
 
    11  * precise terms see the accompanying LICENSE file.
 
    13  * This software is provided "AS IS" with no warranty of any kind,
 
    14  * express or implied, and with no claim as to its suitability for any
 
    21 /// \brief Item reader bits for lemon input.
 
    23 #ifndef LEMON_BITS_ITEM_READER_H
 
    24 #define LEMON_BITS_ITEM_READER_H
 
    36   template <typename Value>
 
    41   /// \brief Reader class for quoted strings.
 
    43   /// Reader class for quoted strings. It can process the escape
 
    44   /// sequences in the string.
 
    46   /// \author Balazs Dezso
 
    47   class QuotedStringReader {
 
    49     /// \brief The value type of reader.
 
    51     /// The value type of reader.
 
    52     typedef std::string Value;
 
    54     /// \brief Constructor for the reader.
 
    56     /// Constructor for the reader. If the given parameter is true
 
    57     /// the reader processes the escape sequences.
 
    58     QuotedStringReader(bool _escaped = true) 
 
    59       : escaped(_escaped) {}
 
    61     /// \brief Reads a quoted string from the given stream.
 
    63     /// Reads a quoted string from the given stream.
 
    64     void read(std::istream& is, std::string& value) const {
 
    68       if (!is.get(c) || c != '\"') 
 
    69 	throw DataFormatError("Quoted string format error");
 
    70       while (is.get(c) && c != '\"') {
 
    71 	if (escaped && c == '\\') {
 
    72 	  value += readEscape(is);
 
    77       if (!is) throw DataFormatError("Quoted string format error");
 
    82     static char readEscape(std::istream& is) {
 
    84       switch (is.get(c), c) {
 
   110 	  if (!is.get(c) || !isHex(c)) 
 
   111 	    throw DataFormatError("Escape format error");
 
   112 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
 
   113 	  else code = code * 16 + valueHex(c);
 
   120 	    throw DataFormatError("Escape format error");
 
   121 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
 
   123 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
 
   125 	  else code = code * 8 + valueOct(c);
 
   131     static bool isOct(char c) {
 
   132       return '0' <= c && c <='7'; 
 
   135     static int valueOct(char c) {
 
   139    static bool isHex(char c) {
 
   140       return ('0' <= c && c <= '9') || 
 
   141 	('a' <= c && c <= 'z') || 
 
   142 	('A' <= c && c <= 'Z'); 
 
   145     static int valueHex(char c) {
 
   146       if ('0' <= c && c <= '9') return c - '0';
 
   147       if ('a' <= c && c <= 'z') return c - 'a' + 10;
 
   155   /// \brief Reader for standard containers.
 
   157   /// Reader for back insertable standard containers. The representation
 
   158   /// of the container is the values enumerated between an open and a
 
   161   /// \author Balazs Dezso
 
   164     typename _ItemReader = DefaultReader<typename _Container::value_type> 
 
   166   class PushBackReader {
 
   168     typedef _Container Value;
 
   169     typedef _ItemReader ItemReader;
 
   173     ItemReader item_reader;
 
   177     /// \brief Constructor for InsertReader
 
   179     /// Constructor for InsertReader
 
   180     PushBackReader(const ItemReader& _item_reader = ItemReader())
 
   181       : item_reader(_item_reader) {}
 
   183     /// \brief Reads the values into the container from the given stream.
 
   185     /// Reads the values into the container from the given stream.
 
   186     void read(std::istream& is, Value& value) const {
 
   188       if (!(is >> c) || c != '(') 
 
   189 	throw DataFormatError("PushBackReader format error");
 
   190       while (is >> c && c != ')') {
 
   192 	typename ItemReader::Value item;
 
   193 	item_reader.read(is, item);
 
   194 	value.push_back(item);
 
   196       if (!is) throw DataFormatError("PushBackReader format error");
 
   203   /// \brief Reader for standard containers.
 
   205   /// Reader for insertable standard containers. The representation
 
   206   /// of the container is the values enumerated between an open and a
 
   209   /// \author Balazs Dezso
 
   212     typename _ItemReader = DefaultReader<typename _Container::value_type> 
 
   216     typedef _Container Value;
 
   217     typedef _ItemReader ItemReader;
 
   221     ItemReader item_reader;
 
   225     /// \brief Constructor for InsertReader
 
   227     /// Constructor for InsertReader
 
   228     InsertReader(const ItemReader& _item_reader = ItemReader())
 
   229       : item_reader(_item_reader) {}
 
   231     /// \brief Reads the values into the container from the given stream.
 
   233     /// Reads the values into the container from the given stream.
 
   234     void read(std::istream& is, Value& value) const {
 
   236       if (!(is >> c) || c != '(') 
 
   237 	throw DataFormatError("InsertReader format error");
 
   238       while (is >> c && c != ')') {
 
   240 	typename ItemReader::Value item;
 
   241 	item_reader.read(is, item);
 
   244       if (!is) throw DataFormatError("PushBackReader format error");
 
   250   /// \brief Reader for parsed string.
 
   252   /// Reader for parsed strings. You can define the open and close
 
   253   /// parse characters. It reads from the input a character sequence
 
   254   /// which is right parsed.
 
   256   /// \author Balazs Dezso
 
   257   class ParsedStringReader {
 
   259     typedef std::string Value;
 
   261     /// \brief Constructor.
 
   263     /// Constructor for ParsedStringReader. You can give as parameter
 
   264     /// the open and close parse characters.
 
   265     ParsedStringReader(char _open = '(', char _close = ')')
 
   266       : open(_open), close(_close) {}
 
   269     /// \brief Reads the parsed string from the given stream.
 
   271     /// Reads the parsed string from the given stream.
 
   272     void read(std::istream& is, Value& value) const {
 
   274       if (!(is >> c) || c != open) {
 
   275 	throw DataFormatError("ParsedStringReader format error");
 
   279       while (counter > 0 && is >> c) {
 
   282 	} else if (c == open) {
 
   288 	throw DataFormatError("ParsedStrinReader format error");
 
   298   /// \brief Reader for read the whole line.
 
   300   /// Reader for read the whole line.
 
   302   /// \author Balazs Dezso
 
   305     typedef std::string Value;
 
   307     /// \brief Constructor.
 
   309     /// Constructor for the LineReader. If the given parameter is
 
   310     /// true then the spaces before the first not space character are
 
   312     LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
 
   314     /// \brief Reads the line from the given stream.
 
   316     /// Reads the line from the given stream.
 
   317     void read(std::istream& is, Value& value) const {
 
   318       if (skipSpaces) is >> std::ws;
 
   319       if (!getline(is, value)) {
 
   320 	throw DataFormatError("LineReader format error");
 
   328   /// \brief Reader for std::pair.
 
   330   /// Reader for std::pair.
 
   332   /// \author Balazs Dezso
 
   333   template <typename _Pair, 
 
   334 	    typename _FirstReader = 
 
   335 	    DefaultReader<typename _Pair::first_type>,
 
   336 	    typename _SecondReader = 
 
   337 	    DefaultReader<typename _Pair::second_type> >
 
   342     typedef _FirstReader FirstReader;
 
   343     typedef _SecondReader SecondReader;
 
   347     FirstReader first_reader;
 
   348     SecondReader second_reader;
 
   352     /// \brief Constructor.
 
   354     /// Constructor for the PairReader.
 
   355     PairReader(const FirstReader& _first_reader = FirstReader(), 
 
   356 	       const SecondReader& _second_reader = SecondReader()) 
 
   357       : first_reader(_first_reader), second_reader(_second_reader) {}
 
   359     /// \brief Reads the pair from the given stream.
 
   361     /// Reads the pair from the given stream.
 
   362     void read(std::istream& is, Value& value) const {
 
   364       if (!(is >> c) || c != '(') {
 
   365 	throw DataFormatError("PairReader format error");
 
   367       first_reader.read(is, value.first);
 
   368       if (!(is >> c) || c != '=') {
 
   369 	throw DataFormatError("PairReader format error");
 
   371       if (!(is >> c) || c != '>') {
 
   372 	throw DataFormatError("PairReader format error");
 
   374       second_reader.read(is, value.second);
 
   375       if (!(is >> c) || c != ')') {
 
   376 	throw DataFormatError("PairReader format error");
 
   383   /// \brief The default item reader template class.
 
   385   /// The default item reader template class. If some section reader
 
   386   /// needs to read a value from a stream it will give the default way for it.
 
   388   /// \author Balazs Dezso
 
   389   template <typename _Value>
 
   390   class DefaultReader {
 
   393     typedef _Value Value;
 
   394     /// \brief Reads a value from the given stream.
 
   396     /// Reads a value from the given stream.
 
   397     void read(std::istream& is, Value& value) const {
 
   399 	throw DataFormatError("DefaultReader format error");
 
   404   class DefaultReader<std::string> {
 
   406     typedef std::string Value;
 
   408     void read(std::istream& is, Value& value) const {
 
   410       if (!(is >> std::ws >> c)) return;
 
   414 	QuotedStringReader().read(is, value);
 
   417 	ParsedStringReader().read(is, value);
 
   420 	ParsedStringReader('[', ']').read(is, value);
 
   423 	ParsedStringReader('/', '/').read(is, value);
 
   427 	  throw DataFormatError("DefaultReader format error");
 
   434   template <typename Item>
 
   435   class DefaultReader<std::vector<Item> > 
 
   436     : public PushBackReader<std::vector<Item> > {};
 
   438   template <typename Item>
 
   439   class DefaultReader<std::deque<Item> > 
 
   440     : public PushBackReader<std::deque<Item> > {};
 
   442   template <typename Item>
 
   443   class DefaultReader<std::list<Item> > 
 
   444     : public PushBackReader<std::list<Item> > {};
 
   446   template <typename Item>
 
   447   class DefaultReader<std::set<Item> > 
 
   448     : public InsertReader<std::set<Item> > {};
 
   450   template <typename Key, typename Value>
 
   451   class DefaultReader<std::map<Key, Value> > 
 
   452     : public InsertReader<std::map<Key, Value>,
 
   453 			  DefaultReader<std::pair<Key, Value> > > {};
 
   455   template <typename Item>
 
   456   class DefaultReader<std::multiset<Item> > 
 
   457     : public InsertReader<std::multiset<Item> > {};
 
   459   template <typename Key, typename Value>
 
   460   class DefaultReader<std::multimap<Key, Value> > 
 
   461     : public InsertReader<std::multimap<Key, Value>,
 
   462 			  DefaultReader<std::pair<Key, Value> > > {};
 
   464   template <typename First, typename Second>
 
   465   class DefaultReader<std::pair<First, Second> > 
 
   466     : public PairReader<std::pair<First, Second> > {};
 
   470   /// \brief The default item reader for skipping a value in the stream.
 
   472   /// The default item reader for skipping a value in the stream.
 
   474   /// \author Balazs Dezso
 
   475   class DefaultSkipper : public DefaultReader<std::string> {};
 
   478   /// \brief Standard ReaderTraits for the GraphReader class.
 
   480   /// Standard ReaderTraits for the GraphReader class.
 
   481   /// It defines standard reading method for all type of value. 
 
   482   /// \author Balazs Dezso
 
   483   struct DefaultReaderTraits {
 
   485     template <typename _Value>
 
   486     struct Reader : DefaultReader<_Value> {};
 
   488     typedef DefaultSkipper Skipper;