3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
21 /// \brief Item writer bits for lemon output.
23 #ifndef LEMON_BITS_ITEM_WRITER_H
24 #define LEMON_BITS_ITEM_WRITER_H
36 #include <lemon/error.h>
40 template <typename Value>
44 /// \brief Writer class for quoted strings.
46 /// Writer class for unformatted strings.
47 /// \author Balazs Dezso
48 class UnformattedWriter {
50 typedef std::string Value;
52 /// \brief Constructor for the writer.
54 /// Constructor for the writer.
55 UnformattedWriter() {}
57 /// \brief Writes an unformatted string to the given stream.
59 /// Writes an unformatted string to the given stream.
60 void write(std::ostream& os, const std::string& value) const {
64 bool readable(const std::string& value) const {
65 std::istringstream is(value);
67 while (is.get(c) && !whiteSpace(c)) {
68 if (!processChar(c, is)) return false;
76 bool processChar(char c, std::istream& is) const {
80 if (!readableParsed('(', ')', is)) return false;
84 if (!readableParsed('[', ']', is)) return false;
88 if (!readableParsed('{', '}', is)) return false;
92 if (!readableParsed('/', '/', is)) return false;
96 if (!readableQuoted('\"', is)) return false;
100 if (!readableQuoted('\'', is)) return false;
108 bool readableParsed(char open, char close, std::istream& is) const {
110 if (!is.get(c) || c != open) return false;
111 while (is.get(c) && c != close) {
112 if (!processChar(c, is)) return false;
114 if (!is) return false;
118 bool readableQuoted(char quote, std::istream& is) const {
121 if (!is.get(c) || c != quote) return false;
122 while (is.get(c) && (c != quote || esc)) {
123 if (c == '\\') esc = !esc;
126 if (!is) return false;
130 static bool whiteSpace(char c) {
131 return c == ' ' || c == '\t' || c == '\v' ||
132 c == '\n' || c == '\r' || c == '\f';
138 /// \brief Writer class for quoted strings.
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;
146 typedef std::string Value;
148 /// \brief Constructor for the writer.
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) {}
155 /// \brief Writes a quoted string to the given stream.
157 /// Writes a quoted string to the given stream.
158 void write(std::ostream& os, const std::string& value) const {
161 std::ostringstream ls;
162 for (int i = 0; i < int(value.size()); ++i) {
163 writeEscape(ls, value[i]);
174 static void writeEscape(std::ostream& os, char c) {
211 os << '\\' << std::oct << static_cast<int>(c);
224 /// \brief Writer class for quoted chars.
226 /// Writer class for quoted char. It can process the escape
227 /// sequences in the string.
228 /// \author Balazs Dezso
229 class QuotedCharWriter {
233 /// \brief Constructor for the writer.
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) {}
239 /// \brief Writes a quoted char to the given stream.
241 /// Writes a quoted char to the given stream.
242 void write(std::ostream& os, const char& value) const {
245 std::ostringstream ls;
246 QuotedStringWriter::writeEscape(ls, value);
259 /// \brief Writer class for quoted char array.
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 {
266 typedef const char* Value;
268 /// \brief Constructor for the writer.
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) {}
274 /// \brief Writes a quoted char array to the given stream.
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));
288 /// \brief Writer for standard containers.
290 /// Writer for each iterable standard containers. The representation
291 /// of the container is the values enumerated between an open and a
294 /// \author Balazs Dezso
297 typename _ItemWriter = DefaultWriter<typename _Container::value_type>
299 class IterableWriter {
301 typedef _Container Value;
302 typedef _ItemWriter ItemWriter;
306 ItemWriter item_writer;
310 IterableWriter(const ItemWriter& _item_writer = ItemWriter())
311 : item_writer(_item_writer) {}
313 /// \brief Writes the values of the container to the given stream.
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;
319 for (it = value.begin(); it != value.end(); ++it) {
320 item_writer.write(os, *it);
330 /// \brief Writer for standard pairs.
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> >
345 typedef _FirstWriter FirstWriter;
346 typedef _SecondWriter SecondWriter;
350 FirstWriter first_writer;
351 SecondWriter second_writer;
355 /// \brief Constructor.
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) {}
362 /// \brief Writes the pair from the given stream.
364 /// Writes the pair from the given stream.
365 void write(std::ostream& os, const Value& value) const {
367 first_writer.write(os, value.first);
369 second_writer.write(os, value.second);
377 /// \brief The default item writer template class.
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.
382 /// \author Balazs Dezso
383 template <typename _Value>
384 class DefaultWriter {
387 typedef _Value Value;
388 /// \brief Writes the value to the given stream.
390 /// Writes the value to the given stream.
391 void write(std::ostream& os, const Value& value) const {
397 class DefaultWriter<std::string> {
399 typedef std::string Value;
401 void write(std::ostream& os, const Value& value) const {
402 if (UnformattedWriter().readable(value)) {
403 UnformattedWriter().write(os, value);
405 QuotedStringWriter().write(os, value);
412 class DefaultWriter<char>
413 : public QuotedCharWriter {};
416 class DefaultWriter<bool> {
420 void write(std::ostream& os, const Value& value) const {
421 os << (value ? "1" : "0");
426 template <int length>
427 class DefaultWriter<char[length]>
428 : public QuotedCharArrayWriter {};
430 template <int length>
431 class DefaultWriter<const char[length]>
432 : public QuotedCharArrayWriter {};
435 class DefaultWriter<char*>
436 : public QuotedCharArrayWriter {};
439 class DefaultWriter<const char*>
440 : public QuotedCharArrayWriter {};
442 template <typename Item>
443 class DefaultWriter<std::vector<Item> >
444 : public IterableWriter<std::vector<Item> > {};
446 template <typename Item>
447 class DefaultWriter<std::deque<Item> >
448 : public IterableWriter<std::deque<Item> > {};
450 template <typename Item>
451 class DefaultWriter<std::list<Item> >
452 : public IterableWriter<std::list<Item> > {};
454 template <typename Item>
455 class DefaultWriter<std::set<Item> >
456 : public IterableWriter<std::set<Item> > {};
458 template <typename Key, typename Value>
459 class DefaultWriter<std::map<Key, Value> >
460 : public IterableWriter<std::map<Key, Value> > {};
462 template <typename Item>
463 class DefaultWriter<std::multiset<Item> >
464 : public IterableWriter<std::multiset<Item> > {};
466 template <typename Key, typename Value>
467 class DefaultWriter<std::multimap<Key, Value> >
468 : public IterableWriter<std::multimap<Key, Value> > {};
470 template <typename First, typename Second>
471 class DefaultWriter<std::pair<First, Second> >
472 : public PairWriter<std::pair<First, Second> > {};
475 /// \brief Standard WriterTraits for the section writers.
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 {
482 template <typename _Value>
483 struct Writer : DefaultWriter<_Value> {
484 typedef DefaultWriter<_Value> Parent;