3  * This file is a part of LEMON, a generic C++ optimization library
 
     5  * Copyright (C) 2003-2006
 
     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 << (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;