COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/bits/item_writer.h @ 2553:bfced05fa852

Last change on this file since 2553:bfced05fa852 was 2553:bfced05fa852, checked in by Alpar Juttner, 11 years ago

Happy New Year to LEMON (+ better update-copyright-header script)

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