COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/bits/item_writer.h @ 2276:1a8a66b6c6ce

Last change on this file since 2276:1a8a66b6c6ce was 2255:4a9cc8c800ae, checked in by Balazs Dezso, 18 years ago

It have not been saved

File size: 11.8 KB
Line 
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/// \ingroup item_io
20/// \file
21/// \brief Item writer bits for lemon output.
22
23#ifndef LEMON_BITS_ITEM_WRITER_H
24#define LEMON_BITS_ITEM_WRITER_H
25
26#include <iostream>
27#include <sstream>
28#include <string>
29
30#include <vector>
31#include <deque>
32#include <list>
33#include <set>
34
35namespace lemon {
36 
37  template <typename Value>
38  class DefaultWriter;
39
40  /// \ingroup item_io
41  /// \brief Writer class for quoted strings.
42  ///
43  /// Writer class for unformatted strings.
44  /// \author Balazs Dezso
45  class UnformattedWriter {
46  public:
47    typedef std::string Value;
48
49    /// \brief Constructor for the writer.
50    ///
51    /// Constructor for the writer.
52    UnformattedWriter() {}
53
54    /// \brief Writes an unformatted string to the given stream.
55    ///
56    /// Writes an unformatted string to the given stream.
57    void write(std::ostream& os, const std::string& value) const {
58      os << value;
59    }
60
61    bool readable(const std::string& value) const {
62      std::istringstream is(value);
63      char c;
64      while (is.get(c) && !whiteSpace(c)) {
65        if (!processChar(c, is)) return false;
66      }
67      if (is) return false;
68      return true;
69    }
70
71  private:
72
73    bool processChar(char c, std::istream& is) const {
74      switch (c) {
75      case '(':
76        is.putback(c);
77        if (!readableParsed('(', ')', is)) return false;
78        break;
79      case '[':
80        is.putback(c);
81        if (!readableParsed('[', ']', is)) return false;
82        break;
83      case '{':
84        is.putback(c);
85        if (!readableParsed('{', '}', is)) return false;
86        break;
87      case '/':
88        is.putback(c);
89        if (!readableParsed('/', '/', is)) return false;
90        break;
91      case '\"':
92        is.putback(c);
93        if (!readableQuoted('\"', is)) return false;
94        break;
95      case '\'':
96        is.putback(c);
97        if (!readableQuoted('\'', is)) return false;
98        break;
99      default:
100        break;
101      }
102      return true;
103    }
104
105    bool readableParsed(char open, char close, std::istream& is) const {
106      char c;
107      if (!is.get(c) || c != open) return false;
108      while (is.get(c) && c != close) {
109        if (!processChar(c, is)) return false;
110      }
111      if (!is) return false;
112      return true;
113    }
114
115    bool readableQuoted(char quote, std::istream& is) const {
116      char c;
117      bool esc = false;
118      if (!is.get(c) || c != quote) return false;
119      while (is.get(c) && (c != quote || esc)) {
120        if (c == '\\') esc = !esc;
121        else esc = false;
122      }
123      if (!is) return false;
124      return true;
125    }
126
127    static bool whiteSpace(char c) {
128      return c == ' ' || c == '\t' || c == '\v' ||
129        c == '\n' || c == '\r' || c == '\f';
130    }
131
132  };
133
134  /// \ingroup item_io
135  /// \brief Writer class for quoted strings.
136  ///
137  /// Writer class for quoted strings. It can process the escape
138  /// sequences in the string.
139  /// \author Balazs Dezso
140  class QuotedStringWriter {
141    friend class QuotedCharWriter;
142  public:
143    typedef std::string Value;
144
145    /// \brief Constructor for the writer.
146    ///
147    /// Constructor for the writer. If the given parameter is true
148    /// the writer creates escape sequences from special characters.
149    QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
150
151    /// \brief Writes a quoted string to the given stream.
152    ///
153    /// Writes a quoted string to the given stream.
154    void write(std::ostream& os, const std::string& value) const {
155      os << "\"";
156      if (escaped) {
157        std::ostringstream ls;
158        for (int i = 0; i < (int)value.size(); ++i) {
159          writeEscape(ls, value[i]);
160        }
161        os << ls.str();
162      } else {
163        os << value;
164      }
165      os << "\"";
166    }
167
168  private:
169   
170    static void writeEscape(std::ostream& os, char c) {
171      switch (c) {
172      case '\\':
173        os << "\\\\";
174        return;
175      case '\"':
176        os << "\\\"";
177        return;
178      case '\'':
179        os << "\\\'";
180        return;
181      case '\?':
182        os << "\\\?";
183        return;
184      case '\a':
185        os << "\\a";
186        return;
187      case '\b':
188        os << "\\b";
189        return;
190      case '\f':
191        os << "\\f";
192        return;
193      case '\r':
194        os << "\\r";
195        return;
196      case '\n':
197        os << "\\n";
198        return;
199      case '\t':
200        os << "\\t";
201        return;
202      case '\v':
203        os << "\\v";
204        return;
205      default:
206        if (c < 0x20) {
207          os << '\\' << std::oct << (int)c;
208        } else {
209          os << c;
210        }
211        return;
212      }     
213    }
214  private:
215    bool escaped;
216  };
217
218  /// \ingroup item_io
219  /// \brief Writer class for quoted chars.
220  ///
221  /// Writer class for quoted char. It can process the escape
222  /// sequences in the string.
223  /// \author Balazs Dezso
224  class QuotedCharWriter {
225  public:
226    typedef char Value;
227
228    /// \brief Constructor for the writer.
229    ///
230    /// Constructor for the writer. If the given parameter is true
231    /// the writer creates escape sequences from special characters.
232    QuotedCharWriter(bool _escaped = true) : escaped(_escaped) {}
233
234    /// \brief Writes a quoted char to the given stream.
235    ///
236    /// Writes a quoted char to the given stream.
237    void write(std::ostream& os, const char& value) const {
238      os << "\'";
239      if (escaped) {
240        std::ostringstream ls;
241        QuotedStringWriter::writeEscape(ls, value);
242        os << ls.str();
243      } else {
244        os << value;
245      }
246      os << "\'";
247    }
248
249  private:
250    bool escaped;
251  };
252
253  /// \ingroup item_io
254  /// \brief Writer class for quoted char array.
255  ///
256  /// Writer class for quoted char array. It can process the escape
257  /// sequences in the char array.
258  /// \author Balazs Dezso
259  class QuotedCharArrayWriter {
260  public:
261    typedef const char* Value;
262
263    /// \brief Constructor for the writer.
264    ///
265    /// Constructor for the writer. If the given parameter is true
266    /// the writer creates escape sequences from special characters.
267    QuotedCharArrayWriter(bool _escaped = true) : escaped(_escaped) {}
268
269    /// \brief Writes a quoted char array to the given stream.
270    ///
271    /// Writes a quoted char array to the given stream.
272    void write(std::ostream& os, const char* value) const {
273      QuotedStringWriter(escaped).write(os, std::string(value));
274    }
275
276  private:   
277    bool escaped;
278  };
279
280
281  /// \ingroup item_io
282  ///
283  /// \brief Writer for standard containers.
284  ///
285  /// Writer for each iterable standard containers. The representation
286  /// of the container is the values enumerated between an open and a
287  /// close parse.
288  ///
289  /// \author Balazs Dezso
290  template <
291    typename _Container,
292    typename _ItemWriter = DefaultWriter<typename _Container::value_type>
293  >
294  class IterableWriter {
295  public:
296    typedef _Container Value;
297    typedef _ItemWriter ItemWriter;
298
299  private:
300
301    ItemWriter item_writer;
302
303  public:
304
305    IterableWriter(const ItemWriter& _item_writer = ItemWriter())
306      : item_writer(_item_writer) {}
307
308    /// \brief Writes the values of the container to the given stream.
309    ///
310    /// Writes the values of the container to the given stream.
311    void write(std::ostream& os, const Value& value) const {
312      typename Value::const_iterator it;
313      os << '(';
314      for (it = value.begin(); it != value.end(); ++it) {
315        item_writer.write(os, *it);
316        os << ' ';
317      }
318      os << ')';
319    }
320
321  };
322
323  /// \ingroup item_io
324  ///
325  /// \brief Writer for standard pairs.
326  ///
327  /// Writer for standard pairs. The representation of a pair is
328  ///\code ( first_value => second_value ) \endcode.
329  /// \author Balazs Dezso
330  template <typename _Pair,
331            typename _FirstWriter =
332            DefaultWriter<typename _Pair::first_type>,
333            typename _SecondWriter =
334            DefaultWriter<typename _Pair::second_type> >
335  class PairWriter {
336  public:
337
338    typedef _Pair Value;
339
340    typedef _FirstWriter FirstWriter;
341    typedef _SecondWriter SecondWriter;
342
343  private:
344
345    FirstWriter first_writer;
346    SecondWriter second_writer;
347
348  public:
349   
350    /// \brief Constructor.
351    ///
352    /// Constructor for the PairWriter.
353    PairWriter(const FirstWriter& _first_writer = FirstWriter(),
354               const SecondWriter& _second_writer = SecondWriter())
355      : first_writer(_first_writer), second_writer(_second_writer) {}
356   
357    /// \brief Writes the pair from the given stream.
358    ///
359    /// Writes the pair from the given stream.
360    void write(std::ostream& os, const Value& value) const {
361      os << "( ";
362      first_writer.write(os, value.first);
363      os << " => ";
364      second_writer.write(os, value.second);
365      os << " )";
366    }
367
368  };
369
370  /// \ingroup item_io
371  ///
372  /// \brief The default item writer template class.
373  ///
374  /// The default item writer template class. If some section writer
375  /// needs to write a value to the stream it will give the default way for it.
376  ///
377  /// \author Balazs Dezso
378  template <typename _Value>
379  class DefaultWriter {
380  public:
381    /// The value type.
382    typedef _Value Value;
383    /// \brief Writes the value to the given stream.
384    ///
385    /// Writes the value to the given stream.
386    void write(std::ostream& os, const Value& value) const {
387      os << value;
388    }
389  };
390
391  template <>
392  class DefaultWriter<std::string> {
393  public:
394    typedef std::string Value;
395   
396    void write(std::ostream& os, const Value& value) const {
397      if (UnformattedWriter().readable(value)) {
398        UnformattedWriter().write(os, value);
399      } else {
400        QuotedStringWriter().write(os, value);
401      }
402    }
403     
404  };
405
406  template <>
407  class DefaultWriter<char>
408    : public QuotedCharWriter {};
409
410  template <>
411  class DefaultWriter<bool> {
412  public:
413    typedef bool Value;
414   
415    void write(std::ostream& os, const Value& value) const {
416      os << (value ? "1" : "0");
417    }
418     
419  };
420
421  template <int length>
422  class DefaultWriter<char[length]>
423    : public QuotedCharArrayWriter {};
424
425  template <int length>
426  class DefaultWriter<const char[length]>
427    : public QuotedCharArrayWriter {};
428
429  template <>
430  class DefaultWriter<char*>
431    : public QuotedCharArrayWriter {};
432
433  template <>
434  class DefaultWriter<const char*>
435    : public QuotedCharArrayWriter {};
436
437  template <typename Item>
438  class DefaultWriter<std::vector<Item> >
439    : public IterableWriter<std::vector<Item> > {};
440
441  template <typename Item>
442  class DefaultWriter<std::deque<Item> >
443    : public IterableWriter<std::deque<Item> > {};
444
445  template <typename Item>
446  class DefaultWriter<std::list<Item> >
447    : public IterableWriter<std::list<Item> > {};
448 
449  template <typename Item>
450  class DefaultWriter<std::set<Item> >
451    : public IterableWriter<std::set<Item> > {};
452
453  template <typename Key, typename Value>
454  class DefaultWriter<std::map<Key, Value> >
455    : public IterableWriter<std::map<Key, Value> > {};
456
457  template <typename Item>
458  class DefaultWriter<std::multiset<Item> >
459    : public IterableWriter<std::multiset<Item> > {};
460
461  template <typename Key, typename Value>
462  class DefaultWriter<std::multimap<Key, Value> >
463    : public IterableWriter<std::multimap<Key, Value> > {};
464
465  template <typename First, typename Second>
466  class DefaultWriter<std::pair<First, Second> >
467    : public PairWriter<std::pair<First, Second> > {};
468
469  /// \ingroup item_io
470  /// \brief Standard WriterTraits for the section writers.
471  ///
472  /// Standard WriterTraits for the section writers.
473  /// It defines standard writing method for all type of value.
474  /// \author Balazs Dezso
475  struct DefaultWriterTraits {
476
477    template <typename _Value>
478    struct Writer : DefaultWriter<_Value> {
479      typedef DefaultWriter<_Value> Parent;
480    };
481
482  };
483
484}
485
486#endif
Note: See TracBrowser for help on using the repository browser.