3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
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
37 template <typename Value>
41 /// \brief Writer class for quoted strings.
43 /// Writer class for unformatted strings.
44 /// \author Balazs Dezso
45 class UnformattedWriter {
47 typedef std::string Value;
49 /// \brief Constructor for the writer.
51 /// Constructor for the writer.
52 UnformattedWriter() {}
54 /// \brief Writes an unformatted string to the given stream.
56 /// Writes an unformatted string to the given stream.
57 void write(std::ostream& os, const std::string& value) const {
61 bool readable(const std::string& value) const {
62 std::istringstream is(value);
64 while (is.get(c) && !whiteSpace(c)) {
65 if (!processChar(c, is)) return false;
73 bool processChar(char c, std::istream& is) const {
77 if (!readableParsed('(', ')', is)) return false;
81 if (!readableParsed('[', ']', is)) return false;
85 if (!readableParsed('{', '}', is)) return false;
89 if (!readableParsed('/', '/', is)) return false;
93 if (!readableQuoted('\"', is)) return false;
97 if (!readableQuoted('\'', is)) return false;
105 bool readableParsed(char open, char close, std::istream& is) const {
107 if (!is.get(c) || c != open) return false;
108 while (is.get(c) && c != close) {
109 if (!processChar(c, is)) return false;
111 if (!is) return false;
115 bool readableQuoted(char quote, std::istream& is) const {
118 if (!is.get(c) || c != quote) return false;
119 while (is.get(c) && (c != quote || esc)) {
120 if (c == '\\') esc = !esc;
123 if (!is) return false;
127 static bool whiteSpace(char c) {
128 return c == ' ' || c == '\t' || c == '\v' ||
129 c == '\n' || c == '\r' || c == '\f';
135 /// \brief Writer class for quoted strings.
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;
143 typedef std::string Value;
145 /// \brief Constructor for the writer.
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) {}
151 /// \brief Writes a quoted string to the given stream.
153 /// Writes a quoted string to the given stream.
154 void write(std::ostream& os, const std::string& value) const {
157 std::ostringstream ls;
158 for (int i = 0; i < int(value.size()); ++i) {
159 writeEscape(ls, value[i]);
170 static void writeEscape(std::ostream& os, char c) {
207 os << '\\' << std::oct << static_cast<int>(c);
219 /// \brief Writer class for quoted chars.
221 /// Writer class for quoted char. It can process the escape
222 /// sequences in the string.
223 /// \author Balazs Dezso
224 class QuotedCharWriter {
228 /// \brief Constructor for the writer.
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) {}
234 /// \brief Writes a quoted char to the given stream.
236 /// Writes a quoted char to the given stream.
237 void write(std::ostream& os, const char& value) const {
240 std::ostringstream ls;
241 QuotedStringWriter::writeEscape(ls, value);
254 /// \brief Writer class for quoted char array.
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 {
261 typedef const char* Value;
263 /// \brief Constructor for the writer.
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) {}
269 /// \brief Writes a quoted char array to the given stream.
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));
283 /// \brief Writer for standard containers.
285 /// Writer for each iterable standard containers. The representation
286 /// of the container is the values enumerated between an open and a
289 /// \author Balazs Dezso
292 typename _ItemWriter = DefaultWriter<typename _Container::value_type>
294 class IterableWriter {
296 typedef _Container Value;
297 typedef _ItemWriter ItemWriter;
301 ItemWriter item_writer;
305 IterableWriter(const ItemWriter& _item_writer = ItemWriter())
306 : item_writer(_item_writer) {}
308 /// \brief Writes the values of the container to the given stream.
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;
314 for (it = value.begin(); it != value.end(); ++it) {
315 item_writer.write(os, *it);
325 /// \brief Writer for standard pairs.
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> >
340 typedef _FirstWriter FirstWriter;
341 typedef _SecondWriter SecondWriter;
345 FirstWriter first_writer;
346 SecondWriter second_writer;
350 /// \brief Constructor.
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) {}
357 /// \brief Writes the pair from the given stream.
359 /// Writes the pair from the given stream.
360 void write(std::ostream& os, const Value& value) const {
362 first_writer.write(os, value.first);
364 second_writer.write(os, value.second);
372 /// \brief The default item writer template class.
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.
377 /// \author Balazs Dezso
378 template <typename _Value>
379 class DefaultWriter {
382 typedef _Value Value;
383 /// \brief Writes the value to the given stream.
385 /// Writes the value to the given stream.
386 void write(std::ostream& os, const Value& value) const {
392 class DefaultWriter<std::string> {
394 typedef std::string Value;
396 void write(std::ostream& os, const Value& value) const {
397 if (UnformattedWriter().readable(value)) {
398 UnformattedWriter().write(os, value);
400 QuotedStringWriter().write(os, value);
407 class DefaultWriter<char>
408 : public QuotedCharWriter {};
411 class DefaultWriter<bool> {
415 void write(std::ostream& os, const Value& value) const {
416 os << (value ? "1" : "0");
421 template <int length>
422 class DefaultWriter<char[length]>
423 : public QuotedCharArrayWriter {};
425 template <int length>
426 class DefaultWriter<const char[length]>
427 : public QuotedCharArrayWriter {};
430 class DefaultWriter<char*>
431 : public QuotedCharArrayWriter {};
434 class DefaultWriter<const char*>
435 : public QuotedCharArrayWriter {};
437 template <typename Item>
438 class DefaultWriter<std::vector<Item> >
439 : public IterableWriter<std::vector<Item> > {};
441 template <typename Item>
442 class DefaultWriter<std::deque<Item> >
443 : public IterableWriter<std::deque<Item> > {};
445 template <typename Item>
446 class DefaultWriter<std::list<Item> >
447 : public IterableWriter<std::list<Item> > {};
449 template <typename Item>
450 class DefaultWriter<std::set<Item> >
451 : public IterableWriter<std::set<Item> > {};
453 template <typename Key, typename Value>
454 class DefaultWriter<std::map<Key, Value> >
455 : public IterableWriter<std::map<Key, Value> > {};
457 template <typename Item>
458 class DefaultWriter<std::multiset<Item> >
459 : public IterableWriter<std::multiset<Item> > {};
461 template <typename Key, typename Value>
462 class DefaultWriter<std::multimap<Key, Value> >
463 : public IterableWriter<std::multimap<Key, Value> > {};
465 template <typename First, typename Second>
466 class DefaultWriter<std::pair<First, Second> >
467 : public PairWriter<std::pair<First, Second> > {};
470 /// \brief Standard WriterTraits for the section writers.
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 {
477 template <typename _Value>
478 struct Writer : DefaultWriter<_Value> {
479 typedef DefaultWriter<_Value> Parent;