Changeset 248:8fada33fc60a in lemon-main
- Timestamp:
- 08/17/08 13:39:04 (16 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_writer.h
r240 r248 37 37 #include <lemon/core.h> 38 38 #include <lemon/maps.h> 39 40 #include <lemon/concept_check.h> 41 #include <lemon/concepts/maps.h> 39 42 40 43 namespace lemon { … … 305 308 } 306 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 }; 348 307 349 } 308 350 … … 1493 1535 return tmp; 1494 1536 } 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 } 1495 1740 } 1496 1741
Note: See TracChangeset
for help on using the changeset viewer.