lemon/bits/item_reader.h
author alpar
Mon, 30 Oct 2006 16:19:18 +0000
changeset 2274 432d0469a87e
parent 2016 ecb067198349
child 2386 81b47fc5c444
permissions -rw-r--r--
Turn off 32 bit only tests, cont'd.
deba@1408
     1
/* -*- C++ -*-
deba@1408
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1956
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1408
     8
 *
deba@1408
     9
 * Permission to use, modify and distribute this software is granted
deba@1408
    10
 * provided that this copyright notice appears in all copies. For
deba@1408
    11
 * precise terms see the accompanying LICENSE file.
deba@1408
    12
 *
deba@1408
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1408
    14
 * express or implied, and with no claim as to its suitability for any
deba@1408
    15
 * purpose.
deba@1408
    16
 *
deba@1408
    17
 */
deba@1408
    18
alpar@1946
    19
/// \ingroup item_io
deba@1408
    20
/// \file
deba@1408
    21
/// \brief Item reader bits for lemon input.
deba@1408
    22
deba@1408
    23
#ifndef LEMON_BITS_ITEM_READER_H
deba@1408
    24
#define LEMON_BITS_ITEM_READER_H
deba@1408
    25
deba@1408
    26
#include <iostream>
deba@1408
    27
#include <string>
deba@1408
    28
deba@1408
    29
#include <vector>
deba@1408
    30
#include <deque>
deba@1408
    31
#include <list>
deba@1408
    32
#include <set>
deba@1408
    33
deba@1408
    34
namespace lemon {
deba@1408
    35
  
deba@1408
    36
  template <typename Value>
deba@1408
    37
  class DefaultReader;
deba@1408
    38
alpar@1946
    39
  /// \ingroup item_io
deba@1408
    40
  ///
deba@2254
    41
  /// \brief Reader class for unformatted strings.
deba@2254
    42
  ///
deba@2254
    43
  /// Reader class for unformatted strings. This class want to be
deba@2254
    44
  /// a general reader type which can read the most 
deba@2254
    45
  ///
deba@2254
    46
  /// \author Balazs Dezso
deba@2254
    47
  class UnformattedReader {
deba@2254
    48
  public:
deba@2254
    49
    /// \brief The value type of reader.
deba@2254
    50
    ///
deba@2254
    51
    /// The value type of reader.
deba@2254
    52
    typedef std::string Value;
deba@2254
    53
    
deba@2254
    54
    /// \brief Constructor for the reader.
deba@2254
    55
    ///
deba@2254
    56
    /// Constructor for the reader.
deba@2254
    57
    UnformattedReader() {} 
deba@2254
    58
    
deba@2254
    59
    /// \brief Reads an unformatted string from the given stream.
deba@2254
    60
    ///
deba@2254
    61
    /// Reads an unformatted string from the given stream.
deba@2254
    62
    void read(std::istream& is, std::string& value) const {
deba@2254
    63
      char c;
deba@2254
    64
      value.clear();
deba@2254
    65
      is >> std::ws;
deba@2254
    66
      while (is.get(c) && !whiteSpace(c)) {
deba@2254
    67
        processChar(c, is, value);
deba@2254
    68
      }
deba@2254
    69
    }
deba@2254
    70
deba@2254
    71
  private:
deba@2254
    72
deba@2254
    73
    void processChar(char c, std::istream& is, Value& value) const {
deba@2254
    74
      switch (c) {
deba@2254
    75
      case '(':
deba@2254
    76
        is.putback(c);
deba@2254
    77
        readParsed('(', ')', is, value);
deba@2254
    78
        break;
deba@2254
    79
      case '[':
deba@2254
    80
        is.putback(c);
deba@2254
    81
        readParsed('[', ']', is, value);
deba@2254
    82
        break;
deba@2254
    83
      case '{':
deba@2254
    84
        is.putback(c);
deba@2254
    85
        readParsed('{', '}', is, value);
deba@2254
    86
        break;
deba@2254
    87
      case '/':
deba@2254
    88
        is.putback(c);
deba@2254
    89
        readParsed('/', '/', is, value);
deba@2254
    90
        break;
deba@2254
    91
      case '\"':
deba@2254
    92
        is.putback(c);
deba@2254
    93
        readQuoted('\"', is, value);
deba@2254
    94
        break;
deba@2254
    95
      case '\'':
deba@2254
    96
        is.putback(c);
deba@2254
    97
        readQuoted('\'', is, value);
deba@2254
    98
        break;
deba@2254
    99
      default:
deba@2254
   100
        value += c;
deba@2254
   101
        break;
deba@2254
   102
      }
deba@2254
   103
    }
deba@2254
   104
deba@2254
   105
    void readParsed(char open, char close, 
deba@2254
   106
                    std::istream& is, Value& value) const {
deba@2254
   107
      char c;
deba@2254
   108
      if (!is.get(c) || c != open)
deba@2254
   109
	throw DataFormatError("Unformatted string format error");
deba@2254
   110
      value += c;
deba@2254
   111
      while (is.get(c) && c != close) {
deba@2254
   112
        processChar(c, is, value);
deba@2254
   113
      }
deba@2254
   114
      if (!is) 
deba@2254
   115
        throw DataFormatError("Unformatted string format error");
deba@2254
   116
      value += c;      
deba@2254
   117
    }
deba@2254
   118
deba@2254
   119
    void readQuoted(char quote, std::istream& is, Value& value) const {
deba@2254
   120
      char c;
deba@2254
   121
      bool esc = false;
deba@2254
   122
      if (!is.get(c) || c != quote)
deba@2254
   123
	throw DataFormatError("Unformatted string format error");
deba@2254
   124
      value += c;
deba@2254
   125
      while (is.get(c) && (c != quote || esc)) {
deba@2254
   126
        if (c == '\\') esc = !esc;
deba@2254
   127
        else esc = false;
deba@2254
   128
        value += c;
deba@2254
   129
      }
deba@2254
   130
      if (!is) 
deba@2254
   131
        throw DataFormatError("Unformatted string format error");
deba@2254
   132
      value += c;
deba@2254
   133
    }
deba@2254
   134
deba@2254
   135
deba@2254
   136
deba@2254
   137
    static bool whiteSpace(char c) {
deba@2254
   138
      return c == ' ' || c == '\t' || c == '\v' || 
deba@2254
   139
        c == '\n' || c == '\r' || c == '\f'; 
deba@2254
   140
    }
deba@2254
   141
deba@2254
   142
    
deba@2254
   143
  };
deba@2254
   144
deba@2254
   145
  /// \ingroup item_io
deba@2254
   146
  ///
deba@1408
   147
  /// \brief Reader class for quoted strings.
deba@1408
   148
  ///
deba@1408
   149
  /// Reader class for quoted strings. It can process the escape
deba@1408
   150
  /// sequences in the string.
deba@1408
   151
  ///
deba@1408
   152
  /// \author Balazs Dezso
deba@1408
   153
  class QuotedStringReader {
deba@2254
   154
    friend class QuotedCharReader;
deba@1408
   155
  public:
deba@1408
   156
    /// \brief The value type of reader.
deba@1408
   157
    ///
deba@1408
   158
    /// The value type of reader.
deba@1408
   159
    typedef std::string Value;
deba@1408
   160
    
deba@1408
   161
    /// \brief Constructor for the reader.
deba@1408
   162
    ///
deba@1408
   163
    /// Constructor for the reader. If the given parameter is true
deba@1408
   164
    /// the reader processes the escape sequences.
deba@1408
   165
    QuotedStringReader(bool _escaped = true) 
deba@1408
   166
      : escaped(_escaped) {}
deba@1408
   167
    
deba@1408
   168
    /// \brief Reads a quoted string from the given stream.
deba@1408
   169
    ///
deba@1408
   170
    /// Reads a quoted string from the given stream.
deba@1408
   171
    void read(std::istream& is, std::string& value) const {
deba@1408
   172
      char c;
deba@1408
   173
      value.clear();
deba@1408
   174
      is >> std::ws;
deba@1408
   175
      if (!is.get(c) || c != '\"') 
deba@2254
   176
	throw DataFormatError("Quoted format error");
deba@1408
   177
      while (is.get(c) && c != '\"') {
deba@1408
   178
	if (escaped && c == '\\') {
deba@1408
   179
	  value += readEscape(is);
deba@1408
   180
	} else {
deba@1408
   181
	  value += c;
deba@1408
   182
	}
deba@1408
   183
      }
deba@2254
   184
      if (!is) throw DataFormatError("Quoted format error");
deba@1408
   185
    }
deba@1408
   186
deba@1408
   187
  private:
deba@1408
   188
    
deba@1408
   189
    static char readEscape(std::istream& is) {
deba@1408
   190
      char c;
deba@1408
   191
      switch (is.get(c), c) {
deba@1408
   192
      case '\\':
deba@1408
   193
	return '\\';
deba@1408
   194
      case '\"':
deba@1408
   195
	return '\"';
deba@1408
   196
      case '\'':
deba@1408
   197
	return '\'';
deba@1408
   198
      case '\?':
deba@1408
   199
	return '\?';
deba@1408
   200
      case 'a':
deba@1408
   201
	return '\a';
deba@1408
   202
      case 'b':
deba@1408
   203
	return '\b';
deba@1408
   204
      case 'f':
deba@1408
   205
	return '\f';
deba@1408
   206
      case 'n':
deba@1408
   207
	return '\n';
deba@1408
   208
      case 'r':
deba@1408
   209
	return '\r';
deba@1408
   210
      case 't':
deba@1408
   211
	return '\t';
deba@1408
   212
      case 'v':
deba@1408
   213
	return '\v';
deba@1408
   214
      case 'x':
deba@1408
   215
	{
deba@1408
   216
	  int code;
deba@1408
   217
	  if (!is.get(c) || !isHex(c)) 
deba@1408
   218
	    throw DataFormatError("Escape format error");
deba@1408
   219
	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
deba@1408
   220
	  else code = code * 16 + valueHex(c);
deba@1408
   221
	  return code;
deba@1408
   222
	}
deba@1408
   223
      default:
deba@1408
   224
	{
deba@1408
   225
	  int code;
deba@1408
   226
	  if (!isOct(c)) 
deba@1408
   227
	    throw DataFormatError("Escape format error");
deba@1408
   228
	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
deba@1408
   229
	    is.putback(c);
deba@1408
   230
	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
deba@1408
   231
	    is.putback(c);
deba@1408
   232
	  else code = code * 8 + valueOct(c);
deba@1408
   233
	  return code;
deba@1408
   234
	}	      
deba@1408
   235
      } 
deba@1408
   236
    }
deba@1408
   237
deba@1408
   238
    static bool isOct(char c) {
deba@1408
   239
      return '0' <= c && c <='7'; 
deba@1408
   240
    }
deba@1408
   241
    
deba@1408
   242
    static int valueOct(char c) {
deba@1408
   243
      return c - '0';
deba@1408
   244
    }
deba@1408
   245
deba@1408
   246
   static bool isHex(char c) {
deba@1408
   247
      return ('0' <= c && c <= '9') || 
deba@1408
   248
	('a' <= c && c <= 'z') || 
deba@1408
   249
	('A' <= c && c <= 'Z'); 
deba@1408
   250
    }
deba@1408
   251
    
deba@1408
   252
    static int valueHex(char c) {
deba@1408
   253
      if ('0' <= c && c <= '9') return c - '0';
deba@1408
   254
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
deba@1408
   255
      return c - 'A' + 10;
deba@1408
   256
    }
deba@1408
   257
deba@1408
   258
    bool escaped;
deba@1408
   259
  };
deba@1408
   260
alpar@1946
   261
  /// \ingroup item_io
deba@2254
   262
  ///
deba@2254
   263
  /// \brief Reader class for quoted strings.
deba@2254
   264
  ///
deba@2254
   265
  /// Reader class for quoted strings. It can process the escape
deba@2254
   266
  /// sequences in the string.
deba@2254
   267
  ///
deba@2254
   268
  /// \author Balazs Dezso
deba@2254
   269
  class QuotedCharReader {
deba@2254
   270
  public:
deba@2254
   271
    /// \brief The value type of reader.
deba@2254
   272
    ///
deba@2254
   273
    /// The value type of reader.
deba@2254
   274
    typedef char Value;
deba@2254
   275
    
deba@2254
   276
    /// \brief Constructor for the reader.
deba@2254
   277
    ///
deba@2254
   278
    /// Constructor for the reader. If the given parameter is true
deba@2254
   279
    /// the reader processes the escape sequences.
deba@2254
   280
    QuotedCharReader(bool _escaped = true) 
deba@2254
   281
      : escaped(_escaped) {}
deba@2254
   282
    
deba@2254
   283
    /// \brief Reads a quoted string from the given stream.
deba@2254
   284
    ///
deba@2254
   285
    /// Reads a quoted string from the given stream.
deba@2254
   286
    void read(std::istream& is, char& value) const {
deba@2254
   287
      char c;
deba@2254
   288
      is >> std::ws;
deba@2254
   289
      if (!is.get(c) || c != '\'') 
deba@2254
   290
	throw DataFormatError("Quoted format error");
deba@2254
   291
      if (!is.get(c)) 
deba@2254
   292
        throw DataFormatError("Quoted format error");
deba@2254
   293
      if (escaped && c == '\\') {
deba@2254
   294
        value = QuotedStringReader::readEscape(is);
deba@2254
   295
      } else {
deba@2254
   296
        value = c;
deba@2254
   297
      }
deba@2254
   298
      if (!is.get(c) || c != '\'') 
deba@2254
   299
	throw DataFormatError("Quoted format error");
deba@2254
   300
    }
deba@2254
   301
deba@2254
   302
  private:
deba@2254
   303
    bool escaped;
deba@2254
   304
  };
deba@2254
   305
deba@2254
   306
  /// \ingroup item_io
deba@1408
   307
  /// \brief Reader for standard containers.
deba@1408
   308
  ///
deba@1408
   309
  /// Reader for back insertable standard containers. The representation
deba@1408
   310
  /// of the container is the values enumerated between an open and a
deba@1408
   311
  /// close parse. 
deba@1408
   312
  ///
deba@1408
   313
  /// \author Balazs Dezso
deba@1408
   314
  template <
deba@1408
   315
    typename _Container, 
deba@1408
   316
    typename _ItemReader = DefaultReader<typename _Container::value_type> 
deba@1408
   317
  >
deba@1408
   318
  class PushBackReader {
deba@1408
   319
  public:
deba@1408
   320
    typedef _Container Value;
deba@1408
   321
    typedef _ItemReader ItemReader;
deba@1408
   322
deba@1408
   323
  private:
deba@1408
   324
deba@1408
   325
    ItemReader item_reader;
deba@1408
   326
deba@1408
   327
  public:
deba@1408
   328
deba@1852
   329
    /// \brief Constructor for InsertReader
deba@1852
   330
    ///
deba@1852
   331
    /// Constructor for InsertReader
deba@1852
   332
    PushBackReader(const ItemReader& _item_reader = ItemReader())
deba@1852
   333
      : item_reader(_item_reader) {}
deba@1852
   334
deba@1408
   335
    /// \brief Reads the values into the container from the given stream.
deba@1408
   336
    ///
deba@1408
   337
    /// Reads the values into the container from the given stream.
deba@1408
   338
    void read(std::istream& is, Value& value) const {
deba@1408
   339
      char c;
deba@1408
   340
      if (!(is >> c) || c != '(') 
deba@1408
   341
	throw DataFormatError("PushBackReader format error");
deba@1408
   342
      while (is >> c && c != ')') {
deba@1408
   343
	is.putback(c);
deba@1408
   344
	typename ItemReader::Value item;
deba@1408
   345
	item_reader.read(is, item);
deba@1408
   346
	value.push_back(item);
deba@1408
   347
      }
deba@1408
   348
      if (!is) throw DataFormatError("PushBackReader format error");
deba@1408
   349
    }
deba@1408
   350
deba@1408
   351
  };
deba@1408
   352
alpar@1946
   353
  /// \ingroup item_io
deba@1408
   354
  ///
deba@1408
   355
  /// \brief Reader for standard containers.
deba@1408
   356
  ///
deba@1408
   357
  /// Reader for insertable standard containers. The representation
deba@1408
   358
  /// of the container is the values enumerated between an open and a
deba@1408
   359
  /// close parse. 
deba@1408
   360
  ///
deba@1408
   361
  /// \author Balazs Dezso
deba@1408
   362
  template <
deba@1408
   363
    typename _Container, 
deba@1408
   364
    typename _ItemReader = DefaultReader<typename _Container::value_type> 
deba@1408
   365
  >
deba@1408
   366
  class InsertReader {
deba@1408
   367
  public:
deba@1408
   368
    typedef _Container Value;
deba@1408
   369
    typedef _ItemReader ItemReader;
deba@1408
   370
deba@1408
   371
  private:
deba@1408
   372
deba@1408
   373
    ItemReader item_reader;
deba@1408
   374
deba@1408
   375
  public:
deba@1408
   376
deba@1852
   377
    /// \brief Constructor for InsertReader
deba@1852
   378
    ///
deba@1852
   379
    /// Constructor for InsertReader
deba@1852
   380
    InsertReader(const ItemReader& _item_reader = ItemReader())
deba@1852
   381
      : item_reader(_item_reader) {}
deba@1852
   382
deba@1408
   383
    /// \brief Reads the values into the container from the given stream.
deba@1408
   384
    ///
deba@1408
   385
    /// Reads the values into the container from the given stream.
deba@1408
   386
    void read(std::istream& is, Value& value) const {
deba@1408
   387
      char c;
deba@1408
   388
      if (!(is >> c) || c != '(') 
deba@1408
   389
	throw DataFormatError("InsertReader format error");
deba@1408
   390
      while (is >> c && c != ')') {
deba@1408
   391
	is.putback(c);
deba@1408
   392
	typename ItemReader::Value item;
deba@1408
   393
	item_reader.read(is, item);
deba@1408
   394
	value.insert(item);
deba@1408
   395
      }
deba@1408
   396
      if (!is) throw DataFormatError("PushBackReader format error");
deba@1408
   397
    }
deba@1408
   398
deba@1408
   399
  };
deba@1408
   400
alpar@1946
   401
  /// \ingroup item_io
deba@1408
   402
  /// \brief Reader for parsed string.
deba@1408
   403
  ///
deba@1744
   404
  /// Reader for parsed strings. You can define the open and close
deba@1744
   405
  /// parse characters. It reads from the input a character sequence
deba@1744
   406
  /// which is right parsed.
deba@1408
   407
  ///
deba@1408
   408
  /// \author Balazs Dezso
deba@1408
   409
  class ParsedStringReader {
deba@1408
   410
  public:
deba@1408
   411
    typedef std::string Value;
deba@1408
   412
deba@1408
   413
    /// \brief Constructor.
deba@1408
   414
    ///
deba@1408
   415
    /// Constructor for ParsedStringReader. You can give as parameter
deba@1408
   416
    /// the open and close parse characters.
deba@1408
   417
    ParsedStringReader(char _open = '(', char _close = ')')
deba@1408
   418
      : open(_open), close(_close) {}
deba@1408
   419
    
deba@1408
   420
    
deba@1408
   421
    /// \brief Reads the parsed string from the given stream.
deba@1408
   422
    ///
deba@1408
   423
    /// Reads the parsed string from the given stream.
deba@1408
   424
    void read(std::istream& is, Value& value) const {
deba@1408
   425
      char c;
deba@2254
   426
      value.clear();
deba@1408
   427
      if (!(is >> c) || c != open) {
deba@1408
   428
	throw DataFormatError("ParsedStringReader format error");
deba@1408
   429
      }
deba@1408
   430
      value += c;
deba@1408
   431
      int counter = 1;
deba@1408
   432
      while (counter > 0 && is >> c) {
deba@1408
   433
	if (c == close) {
deba@1408
   434
	  --counter;
deba@1408
   435
	} else if (c == open) {
deba@1408
   436
	  ++counter;
deba@1408
   437
	}
deba@1408
   438
	value += c;
deba@1408
   439
      }
deba@1408
   440
      if (!is) {
deba@1408
   441
	throw DataFormatError("ParsedStrinReader format error");
deba@1408
   442
      }
deba@1408
   443
    }
deba@1408
   444
deba@1408
   445
  private:
deba@1408
   446
    char open, close;
deba@1408
   447
deba@1408
   448
  };
deba@1408
   449
alpar@1946
   450
  /// \ingroup item_io
deba@1408
   451
  /// \brief Reader for read the whole line.
deba@1408
   452
  ///
deba@1408
   453
  /// Reader for read the whole line.
deba@1408
   454
  ///
deba@1408
   455
  /// \author Balazs Dezso
deba@1408
   456
  class LineReader {
deba@1408
   457
  public:
deba@1408
   458
    typedef std::string Value;
deba@1408
   459
deba@1408
   460
    /// \brief Constructor.
deba@1408
   461
    ///
deba@1408
   462
    /// Constructor for the LineReader. If the given parameter is
deba@1408
   463
    /// true then the spaces before the first not space character are
deba@1408
   464
    /// skipped.
deba@1408
   465
    LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
deba@1408
   466
    
deba@1408
   467
    /// \brief Reads the line from the given stream.
deba@1408
   468
    ///
deba@1408
   469
    /// Reads the line from the given stream.
deba@1852
   470
    void read(std::istream& is, Value& value) const {
deba@1408
   471
      if (skipSpaces) is >> std::ws;
deba@1408
   472
      if (!getline(is, value)) {
deba@1852
   473
	throw DataFormatError("LineReader format error");
deba@1408
   474
      }
deba@1408
   475
    }
deba@1408
   476
  private:
deba@1408
   477
    bool skipSpaces;
deba@1408
   478
  };
deba@1408
   479
alpar@1946
   480
  /// \ingroup item_io
deba@1852
   481
  /// \brief Reader for std::pair.
deba@1852
   482
  ///
deba@1852
   483
  /// Reader for std::pair.
deba@1852
   484
  ///
deba@1852
   485
  /// \author Balazs Dezso
deba@1852
   486
  template <typename _Pair, 
deba@1852
   487
	    typename _FirstReader = 
deba@1852
   488
	    DefaultReader<typename _Pair::first_type>,
deba@1852
   489
	    typename _SecondReader = 
deba@1852
   490
	    DefaultReader<typename _Pair::second_type> >
deba@1852
   491
  class PairReader {
deba@1852
   492
  public:
deba@1852
   493
    typedef _Pair Value;
deba@1852
   494
deba@1852
   495
    typedef _FirstReader FirstReader;
deba@1852
   496
    typedef _SecondReader SecondReader;
deba@1852
   497
deba@1852
   498
  private:
deba@1852
   499
deba@1852
   500
    FirstReader first_reader;
deba@1852
   501
    SecondReader second_reader;
deba@1852
   502
deba@1852
   503
  public:
deba@1852
   504
    
deba@1852
   505
    /// \brief Constructor.
deba@1852
   506
    ///
deba@1852
   507
    /// Constructor for the PairReader.
deba@1852
   508
    PairReader(const FirstReader& _first_reader = FirstReader(), 
deba@1852
   509
	       const SecondReader& _second_reader = SecondReader()) 
deba@1852
   510
      : first_reader(_first_reader), second_reader(_second_reader) {}
deba@1852
   511
    
deba@1852
   512
    /// \brief Reads the pair from the given stream.
deba@1852
   513
    ///
deba@1852
   514
    /// Reads the pair from the given stream.
deba@1852
   515
    void read(std::istream& is, Value& value) const {
deba@1852
   516
      char c;
deba@1852
   517
      if (!(is >> c) || c != '(') {
deba@1852
   518
	throw DataFormatError("PairReader format error");
deba@1852
   519
      }
deba@1852
   520
      first_reader.read(is, value.first);
deba@1852
   521
      if (!(is >> c) || c != '=') {
deba@1852
   522
	throw DataFormatError("PairReader format error");
deba@1852
   523
      }
deba@1852
   524
      if (!(is >> c) || c != '>') {
deba@1852
   525
	throw DataFormatError("PairReader format error");
deba@1852
   526
      }
deba@1852
   527
      second_reader.read(is, value.second);
deba@1852
   528
      if (!(is >> c) || c != ')') {
deba@1852
   529
	throw DataFormatError("PairReader format error");
deba@1852
   530
      }
deba@1852
   531
    }
deba@1852
   532
  };
deba@1852
   533
alpar@1946
   534
  /// \ingroup item_io
deba@1408
   535
  /// 
deba@1408
   536
  /// \brief The default item reader template class.
deba@1408
   537
  ///
deba@1408
   538
  /// The default item reader template class. If some section reader
deba@1408
   539
  /// needs to read a value from a stream it will give the default way for it.
deba@1408
   540
  ///
deba@1408
   541
  /// \author Balazs Dezso
deba@1408
   542
  template <typename _Value>
deba@1408
   543
  class DefaultReader {
deba@1408
   544
  public:
deba@1408
   545
    /// The value type.
deba@1408
   546
    typedef _Value Value;
deba@1408
   547
    /// \brief Reads a value from the given stream.
deba@1408
   548
    ///
deba@1408
   549
    /// Reads a value from the given stream.
deba@1408
   550
    void read(std::istream& is, Value& value) const {
deba@1408
   551
      if (!(is >> value)) 
deba@1408
   552
	throw DataFormatError("DefaultReader format error");
deba@1408
   553
    }
deba@1408
   554
  };
deba@1408
   555
deba@1427
   556
  template <>
deba@1427
   557
  class DefaultReader<std::string> {
deba@1427
   558
  public:
deba@1427
   559
    typedef std::string Value;
deba@1427
   560
    
deba@1427
   561
    void read(std::istream& is, Value& value) const {
deba@1427
   562
      char c;
deba@2254
   563
      if (!(is >> std::ws >> c)) 
deba@2254
   564
        throw DataFormatError("DefaultReader<string> format error");
deba@1427
   565
      is.putback(c);
deba@1427
   566
      switch (c) {
deba@1427
   567
      case '\"':
deba@1427
   568
	QuotedStringReader().read(is, value);
deba@1427
   569
	break;
deba@1427
   570
      default:
deba@2254
   571
        UnformattedReader().read(is, value);
deba@1427
   572
	break;
deba@1427
   573
      }
deba@1427
   574
    }
deba@1427
   575
    
deba@1427
   576
  };
deba@1427
   577
deba@2254
   578
  template <>
deba@2254
   579
  class DefaultReader<char> {
deba@2254
   580
  public:
deba@2254
   581
    typedef char Value;
deba@2254
   582
    
deba@2254
   583
    void read(std::istream& is, Value& value) const {
deba@2254
   584
      char c;
deba@2254
   585
      if (!(is >> std::ws >> c))
deba@2254
   586
        throw DataFormatError("DefaultReader<char> format error");
deba@2254
   587
      is.putback(c);
deba@2254
   588
      switch (c) {
deba@2254
   589
      case '\'':
deba@2254
   590
	QuotedCharReader().read(is, value);
deba@2254
   591
	break;
deba@2254
   592
      default:
deba@2254
   593
        { 
deba@2254
   594
          int temp;          
deba@2254
   595
          if (!(is >> temp)) 
deba@2254
   596
            throw DataFormatError("DefaultReader<char> format error");
deba@2254
   597
          value = (char)temp;
deba@2254
   598
          break;
deba@2254
   599
        }
deba@2254
   600
      }
deba@2254
   601
    }    
deba@2254
   602
  };
deba@2254
   603
deba@2254
   604
  template <>
deba@2254
   605
  class DefaultReader<bool> {
deba@2254
   606
  public:
deba@2254
   607
    typedef bool Value;
deba@2254
   608
    
deba@2254
   609
    void read(std::istream& is, Value& value) const {
deba@2254
   610
      std::string rep;
deba@2254
   611
      if (!(is >> rep))
deba@2254
   612
        throw DataFormatError("DefaultReader<bool> format error");
deba@2254
   613
      if (rep == "true" || rep == "t" || rep == "1") {
deba@2254
   614
        value = true;
deba@2254
   615
      } else if (rep == "false" || rep == "f" || rep == "0") {
deba@2254
   616
        value = false;
deba@2254
   617
      } else throw DataFormatError("DefaultReader<bool> format error");
deba@2254
   618
    }    
deba@2254
   619
  };
deba@2254
   620
deba@1408
   621
  template <typename Item>
deba@1408
   622
  class DefaultReader<std::vector<Item> > 
deba@1408
   623
    : public PushBackReader<std::vector<Item> > {};
deba@1408
   624
deba@1408
   625
  template <typename Item>
deba@1408
   626
  class DefaultReader<std::deque<Item> > 
deba@1408
   627
    : public PushBackReader<std::deque<Item> > {};
deba@1408
   628
deba@1408
   629
  template <typename Item>
deba@1408
   630
  class DefaultReader<std::list<Item> > 
deba@1408
   631
    : public PushBackReader<std::list<Item> > {};
deba@1408
   632
deba@1408
   633
  template <typename Item>
deba@1408
   634
  class DefaultReader<std::set<Item> > 
deba@1408
   635
    : public InsertReader<std::set<Item> > {};
deba@1408
   636
deba@1852
   637
  template <typename Key, typename Value>
deba@1852
   638
  class DefaultReader<std::map<Key, Value> > 
deba@1852
   639
    : public InsertReader<std::map<Key, Value>,
deba@1852
   640
			  DefaultReader<std::pair<Key, Value> > > {};
deba@1852
   641
deba@1408
   642
  template <typename Item>
deba@1408
   643
  class DefaultReader<std::multiset<Item> > 
deba@1408
   644
    : public InsertReader<std::multiset<Item> > {};
deba@1408
   645
deba@1852
   646
  template <typename Key, typename Value>
deba@1852
   647
  class DefaultReader<std::multimap<Key, Value> > 
deba@1852
   648
    : public InsertReader<std::multimap<Key, Value>,
deba@1852
   649
			  DefaultReader<std::pair<Key, Value> > > {};
deba@1852
   650
deba@1852
   651
  template <typename First, typename Second>
deba@1852
   652
  class DefaultReader<std::pair<First, Second> > 
deba@1852
   653
    : public PairReader<std::pair<First, Second> > {};
deba@1852
   654
alpar@1946
   655
  /// \ingroup item_io
deba@1415
   656
  /// 
deba@1415
   657
  /// \brief The default item reader for skipping a value in the stream.
deba@1415
   658
  ///
deba@1415
   659
  /// The default item reader for skipping a value in the stream.
deba@1415
   660
  ///
deba@1415
   661
  /// \author Balazs Dezso
deba@2254
   662
  class DefaultSkipper : public UnformattedReader {};
deba@1415
   663
alpar@1946
   664
  /// \ingroup item_io  
deba@1408
   665
  /// \brief Standard ReaderTraits for the GraphReader class.
deba@1408
   666
  ///
deba@1408
   667
  /// Standard ReaderTraits for the GraphReader class.
deba@1408
   668
  /// It defines standard reading method for all type of value. 
deba@1408
   669
  /// \author Balazs Dezso
deba@1408
   670
  struct DefaultReaderTraits {
deba@1408
   671
deba@1408
   672
    template <typename _Value>
deba@1408
   673
    struct Reader : DefaultReader<_Value> {};
deba@1408
   674
deba@1408
   675
    typedef DefaultSkipper Skipper;
deba@1408
   676
deba@1408
   677
  };
deba@1408
   678
deba@1408
   679
}
deba@1408
   680
deba@1408
   681
#endif