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 unformatted strings.
 
    43   /// Reader class for unformatted strings. This class want to be
 
    44   /// a general reader type which can read the most 
 
    46   /// \author Balazs Dezso
 
    47   class UnformattedReader {
 
    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.
 
    57     UnformattedReader() {} 
 
    59     /// \brief Reads an unformatted string from the given stream.
 
    61     /// Reads an unformatted string from the given stream.
 
    62     void read(std::istream& is, std::string& value) const {
 
    66       while (is.get(c) && !whiteSpace(c)) {
 
    67         processChar(c, is, value);
 
    73     void processChar(char c, std::istream& is, Value& value) const {
 
    77         readParsed('(', ')', is, value);
 
    81         readParsed('[', ']', is, value);
 
    85         readParsed('{', '}', is, value);
 
    89         readParsed('/', '/', is, value);
 
    93         readQuoted('\"', is, value);
 
    97         readQuoted('\'', is, value);
 
   105     void readParsed(char open, char close, 
 
   106                     std::istream& is, Value& value) const {
 
   108       if (!is.get(c) || c != open)
 
   109 	throw DataFormatError("Unformatted string format error");
 
   111       while (is.get(c) && c != close) {
 
   112         processChar(c, is, value);
 
   115         throw DataFormatError("Unformatted string format error");
 
   119     void readQuoted(char quote, std::istream& is, Value& value) const {
 
   122       if (!is.get(c) || c != quote)
 
   123 	throw DataFormatError("Unformatted string format error");
 
   125       while (is.get(c) && (c != quote || esc)) {
 
   126         if (c == '\\') esc = !esc;
 
   131         throw DataFormatError("Unformatted string format error");
 
   137     static bool whiteSpace(char c) {
 
   138       return c == ' ' || c == '\t' || c == '\v' || 
 
   139         c == '\n' || c == '\r' || c == '\f'; 
 
   147   /// \brief Reader class for quoted strings.
 
   149   /// Reader class for quoted strings. It can process the escape
 
   150   /// sequences in the string.
 
   152   /// \author Balazs Dezso
 
   153   class QuotedStringReader {
 
   154     friend class QuotedCharReader;
 
   156     /// \brief The value type of reader.
 
   158     /// The value type of reader.
 
   159     typedef std::string Value;
 
   161     /// \brief Constructor for the reader.
 
   163     /// Constructor for the reader. If the given parameter is true
 
   164     /// the reader processes the escape sequences.
 
   165     QuotedStringReader(bool _escaped = true) 
 
   166       : escaped(_escaped) {}
 
   168     /// \brief Reads a quoted string from the given stream.
 
   170     /// Reads a quoted string from the given stream.
 
   171     void read(std::istream& is, std::string& value) const {
 
   175       if (!is.get(c) || c != '\"') 
 
   176 	throw DataFormatError("Quoted format error");
 
   177       while (is.get(c) && c != '\"') {
 
   178 	if (escaped && c == '\\') {
 
   179 	  value += readEscape(is);
 
   184       if (!is) throw DataFormatError("Quoted format error");
 
   189     static char readEscape(std::istream& is) {
 
   191       switch (is.get(c), c) {
 
   217 	  if (!is.get(c) || !isHex(c)) 
 
   218 	    throw DataFormatError("Escape format error");
 
   219 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
 
   220 	  else code = code * 16 + valueHex(c);
 
   227 	    throw DataFormatError("Escape format error");
 
   228 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
 
   230 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
 
   232 	  else code = code * 8 + valueOct(c);
 
   238     static bool isOct(char c) {
 
   239       return '0' <= c && c <='7'; 
 
   242     static int valueOct(char c) {
 
   246    static bool isHex(char c) {
 
   247       return ('0' <= c && c <= '9') || 
 
   248 	('a' <= c && c <= 'z') || 
 
   249 	('A' <= c && c <= 'Z'); 
 
   252     static int valueHex(char c) {
 
   253       if ('0' <= c && c <= '9') return c - '0';
 
   254       if ('a' <= c && c <= 'z') return c - 'a' + 10;
 
   263   /// \brief Reader class for quoted strings.
 
   265   /// Reader class for quoted strings. It can process the escape
 
   266   /// sequences in the string.
 
   268   /// \author Balazs Dezso
 
   269   class QuotedCharReader {
 
   271     /// \brief The value type of reader.
 
   273     /// The value type of reader.
 
   276     /// \brief Constructor for the reader.
 
   278     /// Constructor for the reader. If the given parameter is true
 
   279     /// the reader processes the escape sequences.
 
   280     QuotedCharReader(bool _escaped = true) 
 
   281       : escaped(_escaped) {}
 
   283     /// \brief Reads a quoted string from the given stream.
 
   285     /// Reads a quoted string from the given stream.
 
   286     void read(std::istream& is, char& value) const {
 
   289       if (!is.get(c) || c != '\'') 
 
   290 	throw DataFormatError("Quoted format error");
 
   292         throw DataFormatError("Quoted format error");
 
   293       if (escaped && c == '\\') {
 
   294         value = QuotedStringReader::readEscape(is);
 
   298       if (!is.get(c) || c != '\'') 
 
   299 	throw DataFormatError("Quoted format error");
 
   307   /// \brief Reader for standard containers.
 
   309   /// Reader for back insertable standard containers. The representation
 
   310   /// of the container is the values enumerated between an open and a
 
   313   /// \author Balazs Dezso
 
   316     typename _ItemReader = DefaultReader<typename _Container::value_type> 
 
   318   class PushBackReader {
 
   320     typedef _Container Value;
 
   321     typedef _ItemReader ItemReader;
 
   325     ItemReader item_reader;
 
   329     /// \brief Constructor for InsertReader
 
   331     /// Constructor for InsertReader
 
   332     PushBackReader(const ItemReader& _item_reader = ItemReader())
 
   333       : item_reader(_item_reader) {}
 
   335     /// \brief Reads the values into the container from the given stream.
 
   337     /// Reads the values into the container from the given stream.
 
   338     void read(std::istream& is, Value& value) const {
 
   340       if (!(is >> c) || c != '(') 
 
   341 	throw DataFormatError("PushBackReader format error");
 
   342       while (is >> c && c != ')') {
 
   344 	typename ItemReader::Value item;
 
   345 	item_reader.read(is, item);
 
   346 	value.push_back(item);
 
   348       if (!is) throw DataFormatError("PushBackReader format error");
 
   355   /// \brief Reader for standard containers.
 
   357   /// Reader for insertable standard containers. The representation
 
   358   /// of the container is the values enumerated between an open and a
 
   361   /// \author Balazs Dezso
 
   364     typename _ItemReader = DefaultReader<typename _Container::value_type> 
 
   368     typedef _Container Value;
 
   369     typedef _ItemReader ItemReader;
 
   373     ItemReader item_reader;
 
   377     /// \brief Constructor for InsertReader
 
   379     /// Constructor for InsertReader
 
   380     InsertReader(const ItemReader& _item_reader = ItemReader())
 
   381       : item_reader(_item_reader) {}
 
   383     /// \brief Reads the values into the container from the given stream.
 
   385     /// Reads the values into the container from the given stream.
 
   386     void read(std::istream& is, Value& value) const {
 
   388       if (!(is >> c) || c != '(') 
 
   389 	throw DataFormatError("InsertReader format error");
 
   390       while (is >> c && c != ')') {
 
   392 	typename ItemReader::Value item;
 
   393 	item_reader.read(is, item);
 
   396       if (!is) throw DataFormatError("PushBackReader format error");
 
   402   /// \brief Reader for parsed string.
 
   404   /// Reader for parsed strings. You can define the open and close
 
   405   /// parse characters. It reads from the input a character sequence
 
   406   /// which is right parsed.
 
   408   /// \author Balazs Dezso
 
   409   class ParsedStringReader {
 
   411     typedef std::string Value;
 
   413     /// \brief Constructor.
 
   415     /// Constructor for ParsedStringReader. You can give as parameter
 
   416     /// the open and close parse characters.
 
   417     ParsedStringReader(char _open = '(', char _close = ')')
 
   418       : open(_open), close(_close) {}
 
   421     /// \brief Reads the parsed string from the given stream.
 
   423     /// Reads the parsed string from the given stream.
 
   424     void read(std::istream& is, Value& value) const {
 
   427       if (!(is >> c) || c != open) {
 
   428 	throw DataFormatError("ParsedStringReader format error");
 
   432       while (counter > 0 && is >> c) {
 
   435 	} else if (c == open) {
 
   441 	throw DataFormatError("ParsedStrinReader format error");
 
   451   /// \brief Reader for read the whole line.
 
   453   /// Reader for read the whole line.
 
   455   /// \author Balazs Dezso
 
   458     typedef std::string Value;
 
   460     /// \brief Constructor.
 
   462     /// Constructor for the LineReader. If the given parameter is
 
   463     /// true then the spaces before the first not space character are
 
   465     LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
 
   467     /// \brief Reads the line from the given stream.
 
   469     /// Reads the line from the given stream.
 
   470     void read(std::istream& is, Value& value) const {
 
   471       if (skipSpaces) is >> std::ws;
 
   472       if (!getline(is, value)) {
 
   473 	throw DataFormatError("LineReader format error");
 
   481   /// \brief Reader for std::pair.
 
   483   /// Reader for std::pair.
 
   485   /// \author Balazs Dezso
 
   486   template <typename _Pair, 
 
   487 	    typename _FirstReader = 
 
   488 	    DefaultReader<typename _Pair::first_type>,
 
   489 	    typename _SecondReader = 
 
   490 	    DefaultReader<typename _Pair::second_type> >
 
   495     typedef _FirstReader FirstReader;
 
   496     typedef _SecondReader SecondReader;
 
   500     FirstReader first_reader;
 
   501     SecondReader second_reader;
 
   505     /// \brief Constructor.
 
   507     /// Constructor for the PairReader.
 
   508     PairReader(const FirstReader& _first_reader = FirstReader(), 
 
   509 	       const SecondReader& _second_reader = SecondReader()) 
 
   510       : first_reader(_first_reader), second_reader(_second_reader) {}
 
   512     /// \brief Reads the pair from the given stream.
 
   514     /// Reads the pair from the given stream.
 
   515     void read(std::istream& is, Value& value) const {
 
   517       if (!(is >> c) || c != '(') {
 
   518 	throw DataFormatError("PairReader format error");
 
   520       first_reader.read(is, value.first);
 
   521       if (!(is >> c) || c != '=') {
 
   522 	throw DataFormatError("PairReader format error");
 
   524       if (!(is >> c) || c != '>') {
 
   525 	throw DataFormatError("PairReader format error");
 
   527       second_reader.read(is, value.second);
 
   528       if (!(is >> c) || c != ')') {
 
   529 	throw DataFormatError("PairReader format error");
 
   536   /// \brief The default item reader template class.
 
   538   /// The default item reader template class. If some section reader
 
   539   /// needs to read a value from a stream it will give the default way for it.
 
   541   /// \author Balazs Dezso
 
   542   template <typename _Value>
 
   543   class DefaultReader {
 
   546     typedef _Value Value;
 
   547     /// \brief Reads a value from the given stream.
 
   549     /// Reads a value from the given stream.
 
   550     void read(std::istream& is, Value& value) const {
 
   552 	throw DataFormatError("DefaultReader format error");
 
   557   class DefaultReader<std::string> {
 
   559     typedef std::string Value;
 
   561     void read(std::istream& is, Value& value) const {
 
   563       if (!(is >> std::ws >> c)) 
 
   564         throw DataFormatError("DefaultReader<string> format error");
 
   568 	QuotedStringReader().read(is, value);
 
   571         UnformattedReader().read(is, value);
 
   579   class DefaultReader<char> {
 
   583     void read(std::istream& is, Value& value) const {
 
   585       if (!(is >> std::ws >> c))
 
   586         throw DataFormatError("DefaultReader<char> format error");
 
   590 	QuotedCharReader().read(is, value);
 
   596             throw DataFormatError("DefaultReader<char> format error");
 
   605   class DefaultReader<bool> {
 
   609     void read(std::istream& is, Value& value) const {
 
   612         throw DataFormatError("DefaultReader<bool> format error");
 
   613       if (rep == "true" || rep == "t" || rep == "1") {
 
   615       } else if (rep == "false" || rep == "f" || rep == "0") {
 
   617       } else throw DataFormatError("DefaultReader<bool> format error");
 
   621   template <typename Item>
 
   622   class DefaultReader<std::vector<Item> > 
 
   623     : public PushBackReader<std::vector<Item> > {};
 
   625   template <typename Item>
 
   626   class DefaultReader<std::deque<Item> > 
 
   627     : public PushBackReader<std::deque<Item> > {};
 
   629   template <typename Item>
 
   630   class DefaultReader<std::list<Item> > 
 
   631     : public PushBackReader<std::list<Item> > {};
 
   633   template <typename Item>
 
   634   class DefaultReader<std::set<Item> > 
 
   635     : public InsertReader<std::set<Item> > {};
 
   637   template <typename Key, typename Value>
 
   638   class DefaultReader<std::map<Key, Value> > 
 
   639     : public InsertReader<std::map<Key, Value>,
 
   640 			  DefaultReader<std::pair<Key, Value> > > {};
 
   642   template <typename Item>
 
   643   class DefaultReader<std::multiset<Item> > 
 
   644     : public InsertReader<std::multiset<Item> > {};
 
   646   template <typename Key, typename Value>
 
   647   class DefaultReader<std::multimap<Key, Value> > 
 
   648     : public InsertReader<std::multimap<Key, Value>,
 
   649 			  DefaultReader<std::pair<Key, Value> > > {};
 
   651   template <typename First, typename Second>
 
   652   class DefaultReader<std::pair<First, Second> > 
 
   653     : public PairReader<std::pair<First, Second> > {};
 
   657   /// \brief The default item reader for skipping a value in the stream.
 
   659   /// The default item reader for skipping a value in the stream.
 
   661   /// \author Balazs Dezso
 
   662   class DefaultSkipper : public UnformattedReader {};
 
   665   /// \brief Standard ReaderTraits for the GraphReader class.
 
   667   /// Standard ReaderTraits for the GraphReader class.
 
   668   /// It defines standard reading method for all type of value. 
 
   669   /// \author Balazs Dezso
 
   670   struct DefaultReaderTraits {
 
   672     template <typename _Value>
 
   673     struct Reader : DefaultReader<_Value> {};
 
   675     typedef DefaultSkipper Skipper;