| ... | ... | 
		@@ -37,6 +37,9 @@  | 
| 37 | 37 | 
		#include <lemon/core.h>  | 
| 38 | 38 | 
		#include <lemon/maps.h>  | 
| 39 | 39 | 
		 | 
| 40 | 
		#include <lemon/concept_check.h>  | 
|
| 41 | 
		#include <lemon/concepts/maps.h>  | 
|
| 42 | 
		 | 
|
| 40 | 43 | 
		namespace lemon {
	 | 
| 41 | 44 | 
		 | 
| 42 | 45 | 
		  namespace _writer_bits {
	 | 
| ... | ... | 
		@@ -304,6 +307,45 @@  | 
| 304 | 307 | 
		return os;  | 
| 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 | 
		 | 
| 309 | 351 | 
		template <typename Digraph>  | 
| ... | ... | 
		@@ -1492,6 +1534,209 @@  | 
| 1492 | 1534 | 
		GraphWriter<Graph> tmp(fn, graph);  | 
| 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 | 
		 | 
| 1497 | 1742 | 
		#endif  | 
0 comments (0 inline)