COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/bits/item_writer.h @ 2254:50cb2b90daa9

Last change on this file since 2254:50cb2b90daa9 was 2254:50cb2b90daa9, checked in by Balazs Dezso, 13 years ago

Some improvements on item readers and writers

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