lemon/bits/item_writer.h
author deba
Mon, 24 Jul 2006 16:15:48 +0000
changeset 2164 160ca7667159
parent 1946 17eb3eaad9f8
child 2254 50cb2b90daa9
permissions -rw-r--r--
long long just for gnu compilers
deba@1409
     1
/* -*- C++ -*-
deba@1409
     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@1409
     8
 *
deba@1409
     9
 * Permission to use, modify and distribute this software is granted
deba@1409
    10
 * provided that this copyright notice appears in all copies. For
deba@1409
    11
 * precise terms see the accompanying LICENSE file.
deba@1409
    12
 *
deba@1409
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1409
    14
 * express or implied, and with no claim as to its suitability for any
deba@1409
    15
 * purpose.
deba@1409
    16
 *
deba@1409
    17
 */
deba@1409
    18
alpar@1946
    19
/// \ingroup item_io
deba@1409
    20
/// \file
deba@1409
    21
/// \brief Item writer bits for lemon output.
deba@1409
    22
deba@1409
    23
#ifndef LEMON_BITS_ITEM_WRITER_H
deba@1409
    24
#define LEMON_BITS_ITEM_WRITER_H
deba@1409
    25
deba@1409
    26
#include <iostream>
deba@1409
    27
#include <string>
deba@1409
    28
deba@1409
    29
#include <vector>
deba@1409
    30
#include <deque>
deba@1409
    31
#include <list>
deba@1409
    32
#include <set>
deba@1409
    33
deba@1409
    34
namespace lemon {
deba@1409
    35
  
deba@1409
    36
  template <typename Value>
deba@1409
    37
  class DefaultWriter;
deba@1409
    38
alpar@1946
    39
  /// \ingroup item_io
deba@1409
    40
  /// \brief Writer class for quoted strings.
deba@1409
    41
  ///
deba@1409
    42
  /// Writer class for quoted strings. It can process the escape
deba@1409
    43
  /// sequences in the string.
deba@1409
    44
  /// \author Balazs Dezso
deba@1409
    45
  class QuotedStringWriter {
deba@1409
    46
  public:
deba@1409
    47
    typedef std::string Value;
deba@1409
    48
deba@1409
    49
    /// \brief Constructor for the writer.
deba@1409
    50
    ///
deba@1409
    51
    /// Constructor for the writer. If the given parameter is true
deba@1409
    52
    /// the writer creates escape sequences from special characters.
deba@1409
    53
    QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
deba@1409
    54
deba@1409
    55
    /// \brief Writes a quoted string to the given stream.
deba@1409
    56
    ///
deba@1409
    57
    /// Writes a quoted string to the given stream.
deba@1852
    58
    void write(std::ostream& os, const std::string& value) const {
deba@1409
    59
      os << "\"";
deba@1409
    60
      if (escaped) {
klao@1535
    61
	std::ostringstream ls;
deba@1409
    62
	for (int i = 0; i < (int)value.size(); ++i) {
deba@1409
    63
	  writeEscape(ls, value[i]);
deba@1409
    64
	}
deba@1409
    65
	os << ls.str();
deba@1409
    66
      } else {
deba@1409
    67
	os << value;
deba@1409
    68
      }
deba@1409
    69
      os << "\"";
deba@1409
    70
    }
deba@1409
    71
deba@1409
    72
  private:
deba@1409
    73
    
deba@1409
    74
    static void writeEscape(std::ostream& os, char c) {
deba@1409
    75
      switch (c) {
deba@1409
    76
      case '\\':
deba@1409
    77
	os << "\\\\";
deba@1409
    78
	return;
deba@1409
    79
      case '\"':
deba@1409
    80
	os << "\\\"";
deba@1409
    81
	return;
deba@1409
    82
      case '\'':
deba@1409
    83
	os << "\\\'";
deba@1409
    84
	return;
deba@1409
    85
      case '\?':
deba@1409
    86
	os << "\\\?";
deba@1409
    87
	return;
deba@1409
    88
      case '\a':
deba@1409
    89
	os << "\\a";
deba@1409
    90
	return;
deba@1409
    91
      case '\b':
deba@1409
    92
	os << "\\b";
deba@1409
    93
	return;
deba@1409
    94
      case '\f':
deba@1409
    95
	os << "\\f";
deba@1409
    96
	return;
deba@1409
    97
      case '\r':
deba@1409
    98
	os << "\\r";
deba@1409
    99
	return;
deba@1409
   100
      case '\n':
deba@1409
   101
	os << "\\n";
deba@1409
   102
	return;
deba@1409
   103
      case '\t':
deba@1409
   104
	os << "\\t";
deba@1409
   105
	return;
deba@1409
   106
      case '\v':
deba@1409
   107
	os << "\\v";
deba@1409
   108
	return;
deba@1409
   109
      default:
deba@1409
   110
	if (c < 0x20) {
deba@1409
   111
	  os << '\\' << std::oct << (int)c;
deba@1409
   112
	} else {
deba@1409
   113
	  os << c;
deba@1409
   114
	}
deba@1409
   115
	return;
deba@1409
   116
      }     
deba@1409
   117
    }
deba@1409
   118
  private:
deba@1409
   119
    bool escaped;
deba@1409
   120
  };
deba@1409
   121
alpar@1946
   122
  /// \ingroup item_io
deba@1533
   123
  /// \brief Writer class for quoted char array.
deba@1533
   124
  ///
deba@1533
   125
  /// Writer class for quoted char array. It can process the escape
deba@1533
   126
  /// sequences in the char array.
deba@1533
   127
  /// \author Balazs Dezso
deba@1533
   128
  class QuotedCharArrayWriter {
deba@1533
   129
  public:
deba@1533
   130
    typedef const char* Value;
deba@1533
   131
deba@1533
   132
    /// \brief Constructor for the writer.
deba@1533
   133
    ///
deba@1533
   134
    /// Constructor for the writer. If the given parameter is true
deba@1533
   135
    /// the writer creates escape sequences from special characters.
deba@1533
   136
    QuotedCharArrayWriter(bool _escaped = true) : escaped(_escaped) {}
deba@1533
   137
deba@1533
   138
    /// \brief Writes a quoted char array to the given stream.
deba@1533
   139
    ///
deba@1533
   140
    /// Writes a quoted char array to the given stream.
deba@1852
   141
    void write(std::ostream& os, const char* value) const {
deba@1533
   142
      QuotedStringWriter(escaped).write(os, std::string(value));
deba@1533
   143
    }
deba@1533
   144
deba@1533
   145
  private:    
deba@1533
   146
    bool escaped;
deba@1533
   147
  };
deba@1533
   148
deba@1533
   149
alpar@1946
   150
  /// \ingroup item_io
deba@1409
   151
  ///
deba@1409
   152
  /// \brief Writer for standard containers.
deba@1409
   153
  ///
deba@1409
   154
  /// Writer for each iterable standard containers. The representation
deba@1409
   155
  /// of the container is the values enumerated between an open and a
deba@1409
   156
  /// close parse. 
deba@1409
   157
  ///
deba@1409
   158
  /// \author Balazs Dezso
deba@1409
   159
  template <
deba@1409
   160
    typename _Container, 
deba@1409
   161
    typename _ItemWriter = DefaultWriter<typename _Container::value_type> 
deba@1409
   162
  >
deba@1409
   163
  class IterableWriter {
deba@1409
   164
  public:
deba@1409
   165
    typedef _Container Value;
deba@1409
   166
    typedef _ItemWriter ItemWriter;
deba@1409
   167
deba@1409
   168
  private:
deba@1409
   169
deba@1409
   170
    ItemWriter item_writer;
deba@1409
   171
deba@1409
   172
  public:
deba@1409
   173
deba@1852
   174
    IterableWriter(const ItemWriter& _item_writer = ItemWriter())
deba@1852
   175
      : item_writer(_item_writer) {}
deba@1852
   176
deba@1409
   177
    /// \brief Writes the values of the container to the given stream.
deba@1409
   178
    ///
deba@1409
   179
    /// Writes the values of the container to the given stream.
deba@1409
   180
    void write(std::ostream& os, const Value& value) const {
deba@1409
   181
      typename Value::const_iterator it;
deba@1409
   182
      os << '(';
deba@1409
   183
      for (it = value.begin(); it != value.end(); ++it) {
deba@1409
   184
	item_writer.write(os, *it);
deba@1409
   185
	os << ' ';
deba@1409
   186
      }
deba@1409
   187
      os << ')';
deba@1409
   188
    }
deba@1409
   189
deba@1409
   190
  };
deba@1409
   191
alpar@1946
   192
  /// \ingroup item_io
deba@1852
   193
  ///
deba@1852
   194
  /// \brief Writer for standard pairs.
deba@1852
   195
  ///
deba@1852
   196
  /// Writer for standard pairs. The representation of a pair is
alpar@1946
   197
  ///\code ( first_value => second_value ) \endcode.
deba@1852
   198
  /// \author Balazs Dezso
deba@1852
   199
  template <typename _Pair, 
deba@1852
   200
	    typename _FirstWriter = 
deba@1852
   201
	    DefaultWriter<typename _Pair::first_type>,
deba@1852
   202
	    typename _SecondWriter = 
deba@1852
   203
	    DefaultWriter<typename _Pair::second_type> >
deba@1852
   204
  class PairWriter {
deba@1852
   205
  public:
deba@1852
   206
deba@1852
   207
    typedef _Pair Value;
deba@1852
   208
deba@1852
   209
    typedef _FirstWriter FirstWriter;
deba@1852
   210
    typedef _SecondWriter SecondWriter;
deba@1852
   211
deba@1852
   212
  private:
deba@1852
   213
deba@1852
   214
    FirstWriter first_writer;
deba@1852
   215
    SecondWriter second_writer;
deba@1852
   216
deba@1852
   217
  public:
deba@1852
   218
    
deba@1852
   219
    /// \brief Constructor.
deba@1852
   220
    ///
deba@1852
   221
    /// Constructor for the PairWriter.
deba@1852
   222
    PairWriter(const FirstWriter& _first_writer = FirstWriter(), 
deba@1852
   223
	       const SecondWriter& _second_writer = SecondWriter()) 
deba@1852
   224
      : first_writer(_first_writer), second_writer(_second_writer) {}
deba@1852
   225
    
deba@1852
   226
    /// \brief Writes the pair from the given stream.
deba@1852
   227
    ///
deba@1852
   228
    /// Writes the pair from the given stream.
deba@1852
   229
    void write(std::ostream& os, const Value& value) const {
deba@1852
   230
      os << "( ";
deba@1852
   231
      first_writer.write(os, value.first);
deba@1852
   232
      os << " => ";
deba@1852
   233
      second_writer.write(os, value.second);
deba@1852
   234
      os << " )";
deba@1852
   235
    }
deba@1852
   236
deba@1852
   237
  };
deba@1852
   238
alpar@1946
   239
  /// \ingroup item_io
deba@1409
   240
  /// 
deba@1409
   241
  /// \brief The default item writer template class.
deba@1409
   242
  ///
deba@1409
   243
  /// The default item writer template class. If some section writer
deba@1409
   244
  /// needs to write a value to the stream it will give the default way for it.
deba@1409
   245
  ///
deba@1409
   246
  /// \author Balazs Dezso
deba@1409
   247
  template <typename _Value>
deba@1409
   248
  class DefaultWriter {
deba@1409
   249
  public:
deba@1409
   250
    /// The value type.
deba@1409
   251
    typedef _Value Value;
deba@1409
   252
    /// \brief Writes the value to the given stream.
deba@1409
   253
    ///
deba@1409
   254
    /// Writes the value to the given stream.
deba@1409
   255
    void write(std::ostream& os, const Value& value) const {
deba@1409
   256
      os << value;
deba@1409
   257
    }
deba@1409
   258
  };
deba@1409
   259
deba@1429
   260
  template <>
deba@1429
   261
  class DefaultWriter<std::string> 
ladanyi@1434
   262
    : public QuotedStringWriter {};
deba@1429
   263
deba@1533
   264
  template <int length>
deba@1533
   265
  class DefaultWriter<char[length]> 
deba@1533
   266
    : public QuotedCharArrayWriter {};
deba@1533
   267
deba@1533
   268
  template <int length>
deba@1533
   269
  class DefaultWriter<const char[length]> 
deba@1533
   270
    : public QuotedCharArrayWriter {};
deba@1533
   271
deba@1852
   272
  template <>
deba@1852
   273
  class DefaultWriter<char*> 
deba@1852
   274
    : public QuotedCharArrayWriter {};
deba@1852
   275
deba@1852
   276
  template <>
deba@1852
   277
  class DefaultWriter<const char*> 
deba@1852
   278
    : public QuotedCharArrayWriter {};
deba@1852
   279
deba@1409
   280
  template <typename Item>
deba@1409
   281
  class DefaultWriter<std::vector<Item> > 
deba@1409
   282
    : public IterableWriter<std::vector<Item> > {};
deba@1409
   283
deba@1409
   284
  template <typename Item>
deba@1409
   285
  class DefaultWriter<std::deque<Item> > 
deba@1409
   286
    : public IterableWriter<std::deque<Item> > {};
deba@1409
   287
deba@1409
   288
  template <typename Item>
deba@1409
   289
  class DefaultWriter<std::list<Item> > 
deba@1409
   290
    : public IterableWriter<std::list<Item> > {};
deba@1409
   291
  
deba@1409
   292
  template <typename Item>
deba@1409
   293
  class DefaultWriter<std::set<Item> > 
deba@1409
   294
    : public IterableWriter<std::set<Item> > {};
deba@1409
   295
deba@1852
   296
  template <typename Key, typename Value>
deba@1852
   297
  class DefaultWriter<std::map<Key, Value> > 
deba@1852
   298
    : public IterableWriter<std::map<Key, Value> > {};
deba@1852
   299
deba@1409
   300
  template <typename Item>
deba@1409
   301
  class DefaultWriter<std::multiset<Item> > 
deba@1409
   302
    : public IterableWriter<std::multiset<Item> > {};
deba@1409
   303
deba@1852
   304
  template <typename Key, typename Value>
deba@1852
   305
  class DefaultWriter<std::multimap<Key, Value> > 
deba@1852
   306
    : public IterableWriter<std::multimap<Key, Value> > {};
deba@1852
   307
deba@1852
   308
  template <typename First, typename Second>
deba@1852
   309
  class DefaultWriter<std::pair<First, Second> > 
deba@1852
   310
    : public PairWriter<std::pair<First, Second> > {};
deba@1852
   311
alpar@1946
   312
  /// \ingroup item_io
deba@1409
   313
  /// \brief Standard WriterTraits for the section writers.
deba@1409
   314
  ///
deba@1409
   315
  /// Standard WriterTraits for the section writers.
deba@1409
   316
  /// It defines standard writing method for all type of value. 
deba@1409
   317
  /// \author Balazs Dezso
deba@1409
   318
  struct DefaultWriterTraits {
deba@1409
   319
deba@1409
   320
    template <typename _Value>
deba@1533
   321
    struct Writer : DefaultWriter<_Value> {
deba@1533
   322
      typedef DefaultWriter<_Value> Parent;
deba@1533
   323
    };
deba@1409
   324
deba@1409
   325
  };
deba@1409
   326
deba@1409
   327
}
deba@1409
   328
deba@1409
   329
#endif