COIN-OR::LEMON - Graph Library

Ticket #131: 8fada33fc60a.patch

File 8fada33fc60a.patch, 7.3 KB (added by Balazs Dezso, 16 years ago)
  • lemon/lgf_writer.h

    # HG changeset patch
    # User Balazs Dezso <deba@inf.elte.hu>
    # Date 1218973144 -7200
    # Node ID 8fada33fc60afac1e9ce8d5d77ede52bb6ba1afd
    # Parent  f1158744a1127caf5d637cab2c043d01c9604c32
    Section writer class
    
    diff -r f1158744a112 -r 8fada33fc60a lemon/lgf_writer.h
    a b  
    3636#include <lemon/assert.h>
    3737#include <lemon/core.h>
    3838#include <lemon/maps.h>
     39
     40#include <lemon/concept_check.h>
     41#include <lemon/concepts/maps.h>
    3942
    4043namespace lemon {
    4144
     
    303306      }
    304307      return os;
    305308    }
     309
     310    class Section {
     311    public:
     312      virtual ~Section() {}
     313      virtual void process(std::ostream& os) = 0;
     314    };
     315
     316    template <typename Functor>
     317    class LineSection : public Section {
     318    private:
     319
     320      Functor _functor;
     321
     322    public:
     323
     324      LineSection(const Functor& functor) : _functor(functor) {}
     325      virtual ~LineSection() {}
     326
     327      virtual void process(std::ostream& os) {
     328        std::string line;
     329        while (!(line = _functor()).empty()) os << line << std::endl;
     330      }
     331    };
     332
     333    template <typename Functor>
     334    class StreamSection : public Section {
     335    private:
     336
     337      Functor _functor;
     338
     339    public:
     340
     341      StreamSection(const Functor& functor) : _functor(functor) {}
     342      virtual ~StreamSection() {}
     343
     344      virtual void process(std::ostream& os) {
     345        _functor(os);
     346      }
     347    };
    306348
    307349  }
    308350
     
    14921534    GraphWriter<Graph> tmp(fn, graph);
    14931535    return tmp;
    14941536  }
     1537
     1538  class SectionWriter;
     1539
     1540  SectionWriter sectionWriter(std::istream& is);
     1541  SectionWriter sectionWriter(const std::string& fn);
     1542  SectionWriter sectionWriter(const char* fn);
     1543
     1544  /// \ingroup lemon_io
     1545  ///
     1546  /// \brief Section writer class
     1547  ///
     1548  /// In the \ref lgf-format "LGF" file extra sections can be placed,
     1549  /// which contain any data in arbitrary format. Such sections can be
     1550  /// written with this class. A writing rule can be added to the
     1551  /// class with two different functions. With the \c sectionLines()
     1552  /// function a generator can write the section line-by-line, while
     1553  /// with the \c sectionStream() member the section can be written to
     1554  /// an output stream.
     1555  class SectionWriter {
     1556  private:
     1557
     1558    std::ostream* _os;
     1559    bool local_os;
     1560
     1561    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
     1562    Sections;
     1563
     1564    Sections _sections;
     1565
     1566  public:
     1567
     1568    /// \brief Constructor
     1569    ///
     1570    /// Construct a section writer, which writes to the given output
     1571    /// stream.
     1572    SectionWriter(std::ostream& os)
     1573      : _os(&os), local_os(false) {}
     1574
     1575    /// \brief Constructor
     1576    ///
     1577    /// Construct a section writer, which writes into the given file.
     1578    SectionWriter(const std::string& fn)
     1579      : _os(new std::ofstream(fn.c_str())), local_os(true) {}
     1580
     1581    /// \brief Constructor
     1582    ///
     1583    /// Construct a section writer, which writes into the given file.
     1584    SectionWriter(const char* fn)
     1585      : _os(new std::ofstream(fn)), local_os(true) {}
     1586
     1587    /// \brief Destructor
     1588    ~SectionWriter() {
     1589      for (Sections::iterator it = _sections.begin();
     1590           it != _sections.end(); ++it) {
     1591        delete it->second;
     1592      }
     1593
     1594      if (local_os) {
     1595        delete _os;
     1596      }
     1597
     1598    }
     1599
     1600  private:
     1601
     1602    friend SectionWriter sectionWriter(std::ostream& os);
     1603    friend SectionWriter sectionWriter(const std::string& fn);
     1604    friend SectionWriter sectionWriter(const char* fn);
     1605
     1606    SectionWriter(SectionWriter& other)
     1607      : _os(other._os), local_os(other.local_os) {
     1608
     1609      other._os = 0;
     1610      other.local_os = false;
     1611
     1612      _sections.swap(other._sections);
     1613    }
     1614
     1615    SectionWriter& operator=(const SectionWriter&);
     1616
     1617  public:
     1618
     1619    /// \name Section writers
     1620    /// @{
     1621
     1622    /// \brief Add a section writer with line oriented writing
     1623    ///
     1624    /// The first parameter is the type descriptor of the section, the
     1625    /// second is a generator with std::string values. At the writing
     1626    /// process, the returned \c std::string will be written into the
     1627    /// output file until it is an empty string.
     1628    ///
     1629    /// For example, an integer vector is written into a section.
     1630    ///\code
     1631    ///  @numbers
     1632    ///  12 45 23 78
     1633    ///  4 28 38 28
     1634    ///  23 6 16
     1635    ///\endcode
     1636    ///
     1637    /// The generator is implemented as a struct.
     1638    ///\code
     1639    ///  struct NumberSection {
     1640    ///    std::vector<int>::const_iterator _it, _end;
     1641    ///    NumberSection(const std::vector<int>& data)
     1642    ///      : _it(data.begin()), _end(data.end()) {}
     1643    ///    std::string operator()() {
     1644    ///      int rem_in_line = 4;
     1645    ///      std::ostringstream ls;
     1646    ///      while (rem_in_line > 0 && _it != _end) {
     1647    ///        ls << *(_it++) << ' ';
     1648    ///        --rem_in_line;
     1649    ///      }
     1650    ///      return ls.str();
     1651    ///    }
     1652    ///  };
     1653    ///
     1654    ///  // ...
     1655    ///
     1656    ///  writer.sectionLines("numbers", NumberSection(vec));
     1657    ///\endcode
     1658    template <typename Functor>
     1659    SectionWriter& sectionLines(const std::string& type, Functor functor) {
     1660      LEMON_ASSERT(!type.empty(), "Type is empty.");
     1661      _sections.push_back(std::make_pair(type,
     1662        new _writer_bits::LineSection<Functor>(functor)));
     1663      return *this;
     1664    }
     1665
     1666
     1667    /// \brief Add a section writer with stream oriented writing
     1668    ///
     1669    /// The first parameter is the type of the section, the second is
     1670    /// a functor, which takes a \c std::ostream& parameter. The
     1671    /// functor writes the section to the output stream.
     1672    /// \warning The last line must be closed with end-line character.
     1673    template <typename Functor>
     1674    SectionWriter& sectionStream(const std::string& type, Functor functor) {
     1675      LEMON_ASSERT(!type.empty(), "Type is empty.");
     1676      _sections.push_back(std::make_pair(type,
     1677         new _writer_bits::StreamSection<Functor>(functor)));
     1678      return *this;
     1679    }
     1680
     1681    /// @}
     1682
     1683  public:
     1684
     1685
     1686    /// \name Execution of the writer
     1687    /// @{
     1688
     1689    /// \brief Start the batch processing
     1690    ///
     1691    /// This function starts the batch processing.
     1692    void run() {
     1693
     1694      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
     1695
     1696      for (Sections::iterator it = _sections.begin();
     1697           it != _sections.end(); ++it) {
     1698        (*_os) << '@' << it->first << std::endl;
     1699        it->second->process(*_os);
     1700      }
     1701    }
     1702
     1703    /// \brief Give back the stream of the writer
     1704    ///
     1705    /// Returns the stream of the writer
     1706    std::ostream& ostream() {
     1707      return *_os;
     1708    }
     1709
     1710    /// @}
     1711
     1712  };
     1713
     1714  /// \brief Return a \ref SectionWriter class
     1715  ///
     1716  /// This function just returns a \ref SectionWriter class.
     1717  /// \relates SectionWriter
     1718  inline SectionWriter sectionWriter(std::ostream& os) {
     1719    SectionWriter tmp(os);
     1720    return tmp;
     1721  }
     1722
     1723  /// \brief Return a \ref SectionWriter class
     1724  ///
     1725  /// This function just returns a \ref SectionWriter class.
     1726  /// \relates SectionWriter
     1727  inline SectionWriter sectionWriter(const std::string& fn) {
     1728    SectionWriter tmp(fn);
     1729    return tmp;
     1730  }
     1731
     1732  /// \brief Return a \ref SectionWriter class
     1733  ///
     1734  /// This function just returns a \ref SectionWriter class.
     1735  /// \relates SectionWriter
     1736  inline SectionWriter sectionWriter(const char* fn) {
     1737    SectionWriter tmp(fn);
     1738    return tmp;
     1739  }
    14951740}
    14961741
    14971742#endif