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
 
    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;