| deba@1409 |      1 | /* -*- C++ -*-
 | 
| deba@1409 |      2 |  *
 | 
| alpar@1956 |      3 |  * This file is a part of LEMON, a generic C++ optimization library
 | 
| alpar@1956 |      4 |  *
 | 
| alpar@1956 |      5 |  * Copyright (C) 2003-2006
 | 
| alpar@1956 |      6 |  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 | 
| alpar@1956 |      7 |  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 | 
| deba@1409 |      8 |  *
 | 
| deba@1409 |      9 |  * Permission to use, modify and distribute this software is granted
 | 
| deba@1409 |     10 |  * provided that this copyright notice appears in all copies. For
 | 
| deba@1409 |     11 |  * precise terms see the accompanying LICENSE file.
 | 
| deba@1409 |     12 |  *
 | 
| deba@1409 |     13 |  * This software is provided "AS IS" with no warranty of any kind,
 | 
| deba@1409 |     14 |  * express or implied, and with no claim as to its suitability for any
 | 
| deba@1409 |     15 |  * purpose.
 | 
| deba@1409 |     16 |  *
 | 
| deba@1409 |     17 |  */
 | 
| deba@1409 |     18 | 
 | 
| alpar@1946 |     19 | /// \ingroup item_io
 | 
| deba@1409 |     20 | /// \file
 | 
| deba@1409 |     21 | /// \brief Item writer bits for lemon output.
 | 
| deba@1409 |     22 | 
 | 
| deba@1409 |     23 | #ifndef LEMON_BITS_ITEM_WRITER_H
 | 
| deba@1409 |     24 | #define LEMON_BITS_ITEM_WRITER_H
 | 
| deba@1409 |     25 | 
 | 
| deba@1409 |     26 | #include <iostream>
 | 
| deba@1409 |     27 | #include <string>
 | 
| deba@1409 |     28 | 
 | 
| deba@1409 |     29 | #include <vector>
 | 
| deba@1409 |     30 | #include <deque>
 | 
| deba@1409 |     31 | #include <list>
 | 
| deba@1409 |     32 | #include <set>
 | 
| deba@1409 |     33 | 
 | 
| deba@1409 |     34 | namespace lemon {
 | 
| deba@1409 |     35 |   
 | 
| deba@1409 |     36 |   template <typename Value>
 | 
| deba@1409 |     37 |   class DefaultWriter;
 | 
| deba@1409 |     38 | 
 | 
| alpar@1946 |     39 |   /// \ingroup item_io
 | 
| deba@1409 |     40 |   /// \brief Writer class for quoted strings.
 | 
| deba@1409 |     41 |   ///
 | 
| deba@1409 |     42 |   /// Writer class for quoted strings. It can process the escape
 | 
| deba@1409 |     43 |   /// sequences in the string.
 | 
| deba@1409 |     44 |   /// \author Balazs Dezso
 | 
| deba@1409 |     45 |   class QuotedStringWriter {
 | 
| deba@1409 |     46 |   public:
 | 
| deba@1409 |     47 |     typedef std::string Value;
 | 
| deba@1409 |     48 | 
 | 
| deba@1409 |     49 |     /// \brief Constructor for the writer.
 | 
| deba@1409 |     50 |     ///
 | 
| deba@1409 |     51 |     /// Constructor for the writer. If the given parameter is true
 | 
| deba@1409 |     52 |     /// the writer creates escape sequences from special characters.
 | 
| deba@1409 |     53 |     QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
 | 
| deba@1409 |     54 | 
 | 
| deba@1409 |     55 |     /// \brief Writes a quoted string to the given stream.
 | 
| deba@1409 |     56 |     ///
 | 
| deba@1409 |     57 |     /// Writes a quoted string to the given stream.
 | 
| deba@1852 |     58 |     void write(std::ostream& os, const std::string& value) const {
 | 
| deba@1409 |     59 |       os << "\"";
 | 
| deba@1409 |     60 |       if (escaped) {
 | 
| klao@1535 |     61 | 	std::ostringstream ls;
 | 
| deba@1409 |     62 | 	for (int i = 0; i < (int)value.size(); ++i) {
 | 
| deba@1409 |     63 | 	  writeEscape(ls, value[i]);
 | 
| deba@1409 |     64 | 	}
 | 
| deba@1409 |     65 | 	os << ls.str();
 | 
| deba@1409 |     66 |       } else {
 | 
| deba@1409 |     67 | 	os << value;
 | 
| deba@1409 |     68 |       }
 | 
| deba@1409 |     69 |       os << "\"";
 | 
| deba@1409 |     70 |     }
 | 
| deba@1409 |     71 | 
 | 
| deba@1409 |     72 |   private:
 | 
| deba@1409 |     73 |     
 | 
| deba@1409 |     74 |     static void writeEscape(std::ostream& os, char c) {
 | 
| deba@1409 |     75 |       switch (c) {
 | 
| deba@1409 |     76 |       case '\\':
 | 
| deba@1409 |     77 | 	os << "\\\\";
 | 
| deba@1409 |     78 | 	return;
 | 
| deba@1409 |     79 |       case '\"':
 | 
| deba@1409 |     80 | 	os << "\\\"";
 | 
| deba@1409 |     81 | 	return;
 | 
| deba@1409 |     82 |       case '\'':
 | 
| deba@1409 |     83 | 	os << "\\\'";
 | 
| deba@1409 |     84 | 	return;
 | 
| deba@1409 |     85 |       case '\?':
 | 
| deba@1409 |     86 | 	os << "\\\?";
 | 
| deba@1409 |     87 | 	return;
 | 
| deba@1409 |     88 |       case '\a':
 | 
| deba@1409 |     89 | 	os << "\\a";
 | 
| deba@1409 |     90 | 	return;
 | 
| deba@1409 |     91 |       case '\b':
 | 
| deba@1409 |     92 | 	os << "\\b";
 | 
| deba@1409 |     93 | 	return;
 | 
| deba@1409 |     94 |       case '\f':
 | 
| deba@1409 |     95 | 	os << "\\f";
 | 
| deba@1409 |     96 | 	return;
 | 
| deba@1409 |     97 |       case '\r':
 | 
| deba@1409 |     98 | 	os << "\\r";
 | 
| deba@1409 |     99 | 	return;
 | 
| deba@1409 |    100 |       case '\n':
 | 
| deba@1409 |    101 | 	os << "\\n";
 | 
| deba@1409 |    102 | 	return;
 | 
| deba@1409 |    103 |       case '\t':
 | 
| deba@1409 |    104 | 	os << "\\t";
 | 
| deba@1409 |    105 | 	return;
 | 
| deba@1409 |    106 |       case '\v':
 | 
| deba@1409 |    107 | 	os << "\\v";
 | 
| deba@1409 |    108 | 	return;
 | 
| deba@1409 |    109 |       default:
 | 
| deba@1409 |    110 | 	if (c < 0x20) {
 | 
| deba@1409 |    111 | 	  os << '\\' << std::oct << (int)c;
 | 
| deba@1409 |    112 | 	} else {
 | 
| deba@1409 |    113 | 	  os << c;
 | 
| deba@1409 |    114 | 	}
 | 
| deba@1409 |    115 | 	return;
 | 
| deba@1409 |    116 |       }     
 | 
| deba@1409 |    117 |     }
 | 
| deba@1409 |    118 |   private:
 | 
| deba@1409 |    119 |     bool escaped;
 | 
| deba@1409 |    120 |   };
 | 
| deba@1409 |    121 | 
 | 
| alpar@1946 |    122 |   /// \ingroup item_io
 | 
| deba@1533 |    123 |   /// \brief Writer class for quoted char array.
 | 
| deba@1533 |    124 |   ///
 | 
| deba@1533 |    125 |   /// Writer class for quoted char array. It can process the escape
 | 
| deba@1533 |    126 |   /// sequences in the char array.
 | 
| deba@1533 |    127 |   /// \author Balazs Dezso
 | 
| deba@1533 |    128 |   class QuotedCharArrayWriter {
 | 
| deba@1533 |    129 |   public:
 | 
| deba@1533 |    130 |     typedef const char* Value;
 | 
| deba@1533 |    131 | 
 | 
| deba@1533 |    132 |     /// \brief Constructor for the writer.
 | 
| deba@1533 |    133 |     ///
 | 
| deba@1533 |    134 |     /// Constructor for the writer. If the given parameter is true
 | 
| deba@1533 |    135 |     /// the writer creates escape sequences from special characters.
 | 
| deba@1533 |    136 |     QuotedCharArrayWriter(bool _escaped = true) : escaped(_escaped) {}
 | 
| deba@1533 |    137 | 
 | 
| deba@1533 |    138 |     /// \brief Writes a quoted char array to the given stream.
 | 
| deba@1533 |    139 |     ///
 | 
| deba@1533 |    140 |     /// Writes a quoted char array to the given stream.
 | 
| deba@1852 |    141 |     void write(std::ostream& os, const char* value) const {
 | 
| deba@1533 |    142 |       QuotedStringWriter(escaped).write(os, std::string(value));
 | 
| deba@1533 |    143 |     }
 | 
| deba@1533 |    144 | 
 | 
| deba@1533 |    145 |   private:    
 | 
| deba@1533 |    146 |     bool escaped;
 | 
| deba@1533 |    147 |   };
 | 
| deba@1533 |    148 | 
 | 
| deba@1533 |    149 | 
 | 
| alpar@1946 |    150 |   /// \ingroup item_io
 | 
| deba@1409 |    151 |   ///
 | 
| deba@1409 |    152 |   /// \brief Writer for standard containers.
 | 
| deba@1409 |    153 |   ///
 | 
| deba@1409 |    154 |   /// Writer for each iterable standard containers. The representation
 | 
| deba@1409 |    155 |   /// of the container is the values enumerated between an open and a
 | 
| deba@1409 |    156 |   /// close parse. 
 | 
| deba@1409 |    157 |   ///
 | 
| deba@1409 |    158 |   /// \author Balazs Dezso
 | 
| deba@1409 |    159 |   template <
 | 
| deba@1409 |    160 |     typename _Container, 
 | 
| deba@1409 |    161 |     typename _ItemWriter = DefaultWriter<typename _Container::value_type> 
 | 
| deba@1409 |    162 |   >
 | 
| deba@1409 |    163 |   class IterableWriter {
 | 
| deba@1409 |    164 |   public:
 | 
| deba@1409 |    165 |     typedef _Container Value;
 | 
| deba@1409 |    166 |     typedef _ItemWriter ItemWriter;
 | 
| deba@1409 |    167 | 
 | 
| deba@1409 |    168 |   private:
 | 
| deba@1409 |    169 | 
 | 
| deba@1409 |    170 |     ItemWriter item_writer;
 | 
| deba@1409 |    171 | 
 | 
| deba@1409 |    172 |   public:
 | 
| deba@1409 |    173 | 
 | 
| deba@1852 |    174 |     IterableWriter(const ItemWriter& _item_writer = ItemWriter())
 | 
| deba@1852 |    175 |       : item_writer(_item_writer) {}
 | 
| deba@1852 |    176 | 
 | 
| deba@1409 |    177 |     /// \brief Writes the values of the container to the given stream.
 | 
| deba@1409 |    178 |     ///
 | 
| deba@1409 |    179 |     /// Writes the values of the container to the given stream.
 | 
| deba@1409 |    180 |     void write(std::ostream& os, const Value& value) const {
 | 
| deba@1409 |    181 |       typename Value::const_iterator it;
 | 
| deba@1409 |    182 |       os << '(';
 | 
| deba@1409 |    183 |       for (it = value.begin(); it != value.end(); ++it) {
 | 
| deba@1409 |    184 | 	item_writer.write(os, *it);
 | 
| deba@1409 |    185 | 	os << ' ';
 | 
| deba@1409 |    186 |       }
 | 
| deba@1409 |    187 |       os << ')';
 | 
| deba@1409 |    188 |     }
 | 
| deba@1409 |    189 | 
 | 
| deba@1409 |    190 |   };
 | 
| deba@1409 |    191 | 
 | 
| alpar@1946 |    192 |   /// \ingroup item_io
 | 
| deba@1852 |    193 |   ///
 | 
| deba@1852 |    194 |   /// \brief Writer for standard pairs.
 | 
| deba@1852 |    195 |   ///
 | 
| deba@1852 |    196 |   /// Writer for standard pairs. The representation of a pair is
 | 
| alpar@1946 |    197 |   ///\code ( first_value => second_value ) \endcode.
 | 
| deba@1852 |    198 |   /// \author Balazs Dezso
 | 
| deba@1852 |    199 |   template <typename _Pair, 
 | 
| deba@1852 |    200 | 	    typename _FirstWriter = 
 | 
| deba@1852 |    201 | 	    DefaultWriter<typename _Pair::first_type>,
 | 
| deba@1852 |    202 | 	    typename _SecondWriter = 
 | 
| deba@1852 |    203 | 	    DefaultWriter<typename _Pair::second_type> >
 | 
| deba@1852 |    204 |   class PairWriter {
 | 
| deba@1852 |    205 |   public:
 | 
| deba@1852 |    206 | 
 | 
| deba@1852 |    207 |     typedef _Pair Value;
 | 
| deba@1852 |    208 | 
 | 
| deba@1852 |    209 |     typedef _FirstWriter FirstWriter;
 | 
| deba@1852 |    210 |     typedef _SecondWriter SecondWriter;
 | 
| deba@1852 |    211 | 
 | 
| deba@1852 |    212 |   private:
 | 
| deba@1852 |    213 | 
 | 
| deba@1852 |    214 |     FirstWriter first_writer;
 | 
| deba@1852 |    215 |     SecondWriter second_writer;
 | 
| deba@1852 |    216 | 
 | 
| deba@1852 |    217 |   public:
 | 
| deba@1852 |    218 |     
 | 
| deba@1852 |    219 |     /// \brief Constructor.
 | 
| deba@1852 |    220 |     ///
 | 
| deba@1852 |    221 |     /// Constructor for the PairWriter.
 | 
| deba@1852 |    222 |     PairWriter(const FirstWriter& _first_writer = FirstWriter(), 
 | 
| deba@1852 |    223 | 	       const SecondWriter& _second_writer = SecondWriter()) 
 | 
| deba@1852 |    224 |       : first_writer(_first_writer), second_writer(_second_writer) {}
 | 
| deba@1852 |    225 |     
 | 
| deba@1852 |    226 |     /// \brief Writes the pair from the given stream.
 | 
| deba@1852 |    227 |     ///
 | 
| deba@1852 |    228 |     /// Writes the pair from the given stream.
 | 
| deba@1852 |    229 |     void write(std::ostream& os, const Value& value) const {
 | 
| deba@1852 |    230 |       os << "( ";
 | 
| deba@1852 |    231 |       first_writer.write(os, value.first);
 | 
| deba@1852 |    232 |       os << " => ";
 | 
| deba@1852 |    233 |       second_writer.write(os, value.second);
 | 
| deba@1852 |    234 |       os << " )";
 | 
| deba@1852 |    235 |     }
 | 
| deba@1852 |    236 | 
 | 
| deba@1852 |    237 |   };
 | 
| deba@1852 |    238 | 
 | 
| alpar@1946 |    239 |   /// \ingroup item_io
 | 
| deba@1409 |    240 |   /// 
 | 
| deba@1409 |    241 |   /// \brief The default item writer template class.
 | 
| deba@1409 |    242 |   ///
 | 
| deba@1409 |    243 |   /// The default item writer template class. If some section writer
 | 
| deba@1409 |    244 |   /// needs to write a value to the stream it will give the default way for it.
 | 
| deba@1409 |    245 |   ///
 | 
| deba@1409 |    246 |   /// \author Balazs Dezso
 | 
| deba@1409 |    247 |   template <typename _Value>
 | 
| deba@1409 |    248 |   class DefaultWriter {
 | 
| deba@1409 |    249 |   public:
 | 
| deba@1409 |    250 |     /// The value type.
 | 
| deba@1409 |    251 |     typedef _Value Value;
 | 
| deba@1409 |    252 |     /// \brief Writes the value to the given stream.
 | 
| deba@1409 |    253 |     ///
 | 
| deba@1409 |    254 |     /// Writes the value to the given stream.
 | 
| deba@1409 |    255 |     void write(std::ostream& os, const Value& value) const {
 | 
| deba@1409 |    256 |       os << value;
 | 
| deba@1409 |    257 |     }
 | 
| deba@1409 |    258 |   };
 | 
| deba@1409 |    259 | 
 | 
| deba@1429 |    260 |   template <>
 | 
| deba@1429 |    261 |   class DefaultWriter<std::string> 
 | 
| ladanyi@1434 |    262 |     : public QuotedStringWriter {};
 | 
| deba@1429 |    263 | 
 | 
| deba@1533 |    264 |   template <int length>
 | 
| deba@1533 |    265 |   class DefaultWriter<char[length]> 
 | 
| deba@1533 |    266 |     : public QuotedCharArrayWriter {};
 | 
| deba@1533 |    267 | 
 | 
| deba@1533 |    268 |   template <int length>
 | 
| deba@1533 |    269 |   class DefaultWriter<const char[length]> 
 | 
| deba@1533 |    270 |     : public QuotedCharArrayWriter {};
 | 
| deba@1533 |    271 | 
 | 
| deba@1852 |    272 |   template <>
 | 
| deba@1852 |    273 |   class DefaultWriter<char*> 
 | 
| deba@1852 |    274 |     : public QuotedCharArrayWriter {};
 | 
| deba@1852 |    275 | 
 | 
| deba@1852 |    276 |   template <>
 | 
| deba@1852 |    277 |   class DefaultWriter<const char*> 
 | 
| deba@1852 |    278 |     : public QuotedCharArrayWriter {};
 | 
| deba@1852 |    279 | 
 | 
| deba@1409 |    280 |   template <typename Item>
 | 
| deba@1409 |    281 |   class DefaultWriter<std::vector<Item> > 
 | 
| deba@1409 |    282 |     : public IterableWriter<std::vector<Item> > {};
 | 
| deba@1409 |    283 | 
 | 
| deba@1409 |    284 |   template <typename Item>
 | 
| deba@1409 |    285 |   class DefaultWriter<std::deque<Item> > 
 | 
| deba@1409 |    286 |     : public IterableWriter<std::deque<Item> > {};
 | 
| deba@1409 |    287 | 
 | 
| deba@1409 |    288 |   template <typename Item>
 | 
| deba@1409 |    289 |   class DefaultWriter<std::list<Item> > 
 | 
| deba@1409 |    290 |     : public IterableWriter<std::list<Item> > {};
 | 
| deba@1409 |    291 |   
 | 
| deba@1409 |    292 |   template <typename Item>
 | 
| deba@1409 |    293 |   class DefaultWriter<std::set<Item> > 
 | 
| deba@1409 |    294 |     : public IterableWriter<std::set<Item> > {};
 | 
| deba@1409 |    295 | 
 | 
| deba@1852 |    296 |   template <typename Key, typename Value>
 | 
| deba@1852 |    297 |   class DefaultWriter<std::map<Key, Value> > 
 | 
| deba@1852 |    298 |     : public IterableWriter<std::map<Key, Value> > {};
 | 
| deba@1852 |    299 | 
 | 
| deba@1409 |    300 |   template <typename Item>
 | 
| deba@1409 |    301 |   class DefaultWriter<std::multiset<Item> > 
 | 
| deba@1409 |    302 |     : public IterableWriter<std::multiset<Item> > {};
 | 
| deba@1409 |    303 | 
 | 
| deba@1852 |    304 |   template <typename Key, typename Value>
 | 
| deba@1852 |    305 |   class DefaultWriter<std::multimap<Key, Value> > 
 | 
| deba@1852 |    306 |     : public IterableWriter<std::multimap<Key, Value> > {};
 | 
| deba@1852 |    307 | 
 | 
| deba@1852 |    308 |   template <typename First, typename Second>
 | 
| deba@1852 |    309 |   class DefaultWriter<std::pair<First, Second> > 
 | 
| deba@1852 |    310 |     : public PairWriter<std::pair<First, Second> > {};
 | 
| deba@1852 |    311 | 
 | 
| alpar@1946 |    312 |   /// \ingroup item_io
 | 
| deba@1409 |    313 |   /// \brief Standard WriterTraits for the section writers.
 | 
| deba@1409 |    314 |   ///
 | 
| deba@1409 |    315 |   /// Standard WriterTraits for the section writers.
 | 
| deba@1409 |    316 |   /// It defines standard writing method for all type of value. 
 | 
| deba@1409 |    317 |   /// \author Balazs Dezso
 | 
| deba@1409 |    318 |   struct DefaultWriterTraits {
 | 
| deba@1409 |    319 | 
 | 
| deba@1409 |    320 |     template <typename _Value>
 | 
| deba@1533 |    321 |     struct Writer : DefaultWriter<_Value> {
 | 
| deba@1533 |    322 |       typedef DefaultWriter<_Value> Parent;
 | 
| deba@1533 |    323 |     };
 | 
| deba@1409 |    324 | 
 | 
| deba@1409 |    325 |   };
 | 
| deba@1409 |    326 | 
 | 
| deba@1409 |    327 | }
 | 
| deba@1409 |    328 | 
 | 
| deba@1409 |    329 | #endif
 |