[Lemon-commits] Balazs Dezso: Section writer class

Lemon HG hg at lemon.cs.elte.hu
Mon Aug 18 20:35:24 CEST 2008


details:   http://lemon.cs.elte.hu/hg/lemon/rev/8fada33fc60a
changeset: 248:8fada33fc60a
user:      Balazs Dezso <deba [at] inf.elte.hu>
date:      Sun Aug 17 13:39:04 2008 +0200
description:
	Section writer class

diffstat:

1 file changed, 245 insertions(+)
lemon/lgf_writer.h |  245 ++++++++++++++++++++++++++++++++++++++++++++++++++++

diffs (269 lines):

diff -r f1158744a112 -r 8fada33fc60a lemon/lgf_writer.h
--- a/lemon/lgf_writer.h	Mon Aug 04 22:00:36 2008 +0200
+++ b/lemon/lgf_writer.h	Sun Aug 17 13:39:04 2008 +0200
@@ -36,6 +36,9 @@
 #include <lemon/assert.h>
 #include <lemon/core.h>
 #include <lemon/maps.h>
+
+#include <lemon/concept_check.h>
+#include <lemon/concepts/maps.h>
 
 namespace lemon {
 
@@ -303,6 +306,45 @@
       }
       return os;
     }
+
+    class Section {
+    public:
+      virtual ~Section() {}
+      virtual void process(std::ostream& os) = 0;
+    };
+
+    template <typename Functor>
+    class LineSection : public Section {
+    private:
+
+      Functor _functor;
+
+    public:
+
+      LineSection(const Functor& functor) : _functor(functor) {}
+      virtual ~LineSection() {}
+
+      virtual void process(std::ostream& os) {
+        std::string line;
+        while (!(line = _functor()).empty()) os << line << std::endl;
+      }
+    };
+
+    template <typename Functor>
+    class StreamSection : public Section {
+    private:
+
+      Functor _functor;
+
+    public:
+
+      StreamSection(const Functor& functor) : _functor(functor) {}
+      virtual ~StreamSection() {}
+
+      virtual void process(std::ostream& os) {
+        _functor(os);
+      }
+    };
 
   }
 
@@ -1492,6 +1534,209 @@
     GraphWriter<Graph> tmp(fn, graph);
     return tmp;
   }
+
+  class SectionWriter;
+
+  SectionWriter sectionWriter(std::istream& is);
+  SectionWriter sectionWriter(const std::string& fn);
+  SectionWriter sectionWriter(const char* fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief Section writer class
+  ///
+  /// In the \ref lgf-format "LGF" file extra sections can be placed,
+  /// which contain any data in arbitrary format. Such sections can be
+  /// written with this class. A writing rule can be added to the
+  /// class with two different functions. With the \c sectionLines()
+  /// function a generator can write the section line-by-line, while
+  /// with the \c sectionStream() member the section can be written to
+  /// an output stream.
+  class SectionWriter {
+  private:
+
+    std::ostream* _os;
+    bool local_os;
+
+    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
+    Sections;
+
+    Sections _sections;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct a section writer, which writes to the given output
+    /// stream.
+    SectionWriter(std::ostream& os)
+      : _os(&os), local_os(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a section writer, which writes into the given file.
+    SectionWriter(const std::string& fn)
+      : _os(new std::ofstream(fn.c_str())), local_os(true) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct a section writer, which writes into the given file.
+    SectionWriter(const char* fn)
+      : _os(new std::ofstream(fn)), local_os(true) {}
+
+    /// \brief Destructor
+    ~SectionWriter() {
+      for (Sections::iterator it = _sections.begin();
+           it != _sections.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_os) {
+        delete _os;
+      }
+
+    }
+
+  private:
+
+    friend SectionWriter sectionWriter(std::ostream& os);
+    friend SectionWriter sectionWriter(const std::string& fn);
+    friend SectionWriter sectionWriter(const char* fn);
+
+    SectionWriter(SectionWriter& other)
+      : _os(other._os), local_os(other.local_os) {
+
+      other._os = 0;
+      other.local_os = false;
+
+      _sections.swap(other._sections);
+    }
+
+    SectionWriter& operator=(const SectionWriter&);
+
+  public:
+
+    /// \name Section writers
+    /// @{
+
+    /// \brief Add a section writer with line oriented writing
+    ///
+    /// The first parameter is the type descriptor of the section, the
+    /// second is a generator with std::string values. At the writing
+    /// process, the returned \c std::string will be written into the
+    /// output file until it is an empty string.
+    ///
+    /// For example, an integer vector is written into a section.
+    ///\code
+    ///  @numbers
+    ///  12 45 23 78
+    ///  4 28 38 28
+    ///  23 6 16
+    ///\endcode
+    ///
+    /// The generator is implemented as a struct.
+    ///\code
+    ///  struct NumberSection {
+    ///    std::vector<int>::const_iterator _it, _end;
+    ///    NumberSection(const std::vector<int>& data)
+    ///      : _it(data.begin()), _end(data.end()) {}
+    ///    std::string operator()() {
+    ///      int rem_in_line = 4;
+    ///      std::ostringstream ls;
+    ///      while (rem_in_line > 0 && _it != _end) {
+    ///        ls << *(_it++) << ' ';
+    ///        --rem_in_line;
+    ///      }
+    ///      return ls.str();
+    ///    }
+    ///  };
+    ///
+    ///  // ...
+    ///
+    ///  writer.sectionLines("numbers", NumberSection(vec));
+    ///\endcode
+    template <typename Functor>
+    SectionWriter& sectionLines(const std::string& type, Functor functor) {
+      LEMON_ASSERT(!type.empty(), "Type is empty.");
+      _sections.push_back(std::make_pair(type,
+        new _writer_bits::LineSection<Functor>(functor)));
+      return *this;
+    }
+
+
+    /// \brief Add a section writer with stream oriented writing
+    ///
+    /// The first parameter is the type of the section, the second is
+    /// a functor, which takes a \c std::ostream& parameter. The
+    /// functor writes the section to the output stream.
+    /// \warning The last line must be closed with end-line character.
+    template <typename Functor>
+    SectionWriter& sectionStream(const std::string& type, Functor functor) {
+      LEMON_ASSERT(!type.empty(), "Type is empty.");
+      _sections.push_back(std::make_pair(type,
+         new _writer_bits::StreamSection<Functor>(functor)));
+      return *this;
+    }
+
+    /// @}
+
+  public:
+
+
+    /// \name Execution of the writer
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing.
+    void run() {
+
+      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
+
+      for (Sections::iterator it = _sections.begin();
+           it != _sections.end(); ++it) {
+        (*_os) << '@' << it->first << std::endl;
+        it->second->process(*_os);
+      }
+    }
+
+    /// \brief Give back the stream of the writer
+    ///
+    /// Returns the stream of the writer
+    std::ostream& ostream() {
+      return *_os;
+    }
+
+    /// @}
+
+  };
+
+  /// \brief Return a \ref SectionWriter class
+  ///
+  /// This function just returns a \ref SectionWriter class.
+  /// \relates SectionWriter
+  inline SectionWriter sectionWriter(std::ostream& os) {
+    SectionWriter tmp(os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref SectionWriter class
+  ///
+  /// This function just returns a \ref SectionWriter class.
+  /// \relates SectionWriter
+  inline SectionWriter sectionWriter(const std::string& fn) {
+    SectionWriter tmp(fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref SectionWriter class
+  ///
+  /// This function just returns a \ref SectionWriter class.
+  /// \relates SectionWriter
+  inline SectionWriter sectionWriter(const char* fn) {
+    SectionWriter tmp(fn);
+    return tmp;
+  }
 }
 
 #endif



More information about the Lemon-commits mailing list