# HG changeset patch
# User Peter Kovacs <kpeter@inf.elte.hu>
# Date 1211758559 -7200
# Node ID c7d30f7810e5aacf3e4576740bc00b4273090dd6
# Parent 500f3cbff9e4ad090ac07241a7e885f70d82d9ab
Change the implementation of StoreBoolMap + improve doc (ticket #36)
diff -r 500f3cbff9e4 -r c7d30f7810e5 lemon/maps.h
a
|
b
|
|
1674 | 1674 | |
1675 | 1675 | namespace _maps_bits { |
1676 | 1676 | |
1677 | | template <typename Value> |
1678 | | struct Identity { |
1679 | | typedef Value argument_type; |
1680 | | typedef Value result_type; |
1681 | | Value operator()(const Value& val) const { |
1682 | | return val; |
1683 | | } |
1684 | | }; |
1685 | | |
1686 | 1677 | template <typename _Iterator, typename Enable = void> |
1687 | 1678 | struct IteratorTraits { |
1688 | 1679 | typedef typename std::iterator_traits<_Iterator>::value_type Value; |
… |
… |
|
1699 | 1690 | |
1700 | 1691 | /// \brief Writable bool map for logging each \c true assigned element |
1701 | 1692 | /// |
1702 | | /// A \ref concepts::ReadWriteMap "read-write" bool map for logging |
| 1693 | /// A \ref concepts::WriteMap "writable" bool map for logging |
1703 | 1694 | /// each \c true assigned element, i.e it copies subsequently each |
1704 | 1695 | /// keys set to \c true to the given iterator. |
| 1696 | /// The most important usage of it is storing certain nodes or arcs |
| 1697 | /// that were marked \c true by an algorithm. |
1705 | 1698 | /// |
1706 | | /// \tparam It the type of the Iterator. |
1707 | | /// \tparam Ke the type of the map's Key. The default value should |
1708 | | /// work in most cases. |
| 1699 | /// There are several algorithms that provide solutions through bool |
| 1700 | /// maps and most of them assign \c true at most once for each key. |
| 1701 | /// In these cases it is a natural request to store each \c true |
| 1702 | /// assigned elements (in order of the assignment), which can be |
| 1703 | /// easily done with StoreBoolMap. |
| 1704 | /// |
| 1705 | /// The simplest way of using this map is through the storeBoolMap() |
| 1706 | /// function. |
| 1707 | /// |
| 1708 | /// \tparam It The type of the iterator. |
| 1709 | /// \tparam Ke The key type of the map. The default value set |
| 1710 | /// according to the iterator type should work in most cases. |
1709 | 1711 | /// |
1710 | 1712 | /// \note The container of the iterator must contain enough space |
1711 | | /// for the elements. (Or it should be an inserter iterator). |
1712 | | /// |
1713 | | /// \todo Revise the name of this class and give an example code. |
| 1713 | /// for the elements or the iterator should be an inserter iterator. |
| 1714 | #ifdef DOXYGEN |
| 1715 | template <typename It, typename Ke> |
| 1716 | #else |
1714 | 1717 | template <typename It, |
1715 | 1718 | typename Ke=typename _maps_bits::IteratorTraits<It>::Value> |
| 1719 | #endif |
1716 | 1720 | class StoreBoolMap { |
1717 | 1721 | public: |
1718 | 1722 | typedef It Iterator; |
… |
… |
|
1735 | 1739 | } |
1736 | 1740 | |
1737 | 1741 | /// The set function of the map |
1738 | | void set(const Key& key, Value value) const { |
| 1742 | void set(const Key& key, Value value) { |
1739 | 1743 | if (value) { |
1740 | 1744 | *_end++ = key; |
1741 | 1745 | } |
… |
… |
|
1743 | 1747 | |
1744 | 1748 | private: |
1745 | 1749 | Iterator _begin; |
1746 | | mutable Iterator _end; |
| 1750 | Iterator _end; |
1747 | 1751 | }; |
| 1752 | |
| 1753 | /// Returns a \ref StoreBoolMap class |
| 1754 | |
| 1755 | /// This function just returns a \ref StoreBoolMap class. |
| 1756 | /// |
| 1757 | /// The most important usage of it is storing certain nodes or arcs |
| 1758 | /// that were marked \c true by an algorithm. |
| 1759 | /// For example it makes easier to store the nodes in the processing |
| 1760 | /// order of Dfs algorithm, as the following examples show. |
| 1761 | /// \code |
| 1762 | /// std::vector<Node> v; |
| 1763 | /// dfs(g,s).processedMap(storeBoolMap(std::back_inserter(v))).run(); |
| 1764 | /// \endcode |
| 1765 | /// \code |
| 1766 | /// std::vector<Node> v(countNodes(g)); |
| 1767 | /// dfs(g,s).processedMap(storeBoolMap(v.begin())).run(); |
| 1768 | /// \endcode |
| 1769 | /// |
| 1770 | /// \note The container of the iterator must contain enough space |
| 1771 | /// for the elements or the iterator should be an inserter iterator. |
| 1772 | /// |
| 1773 | /// \note StoreBoolMap is just \ref concepts::WriteMap "writable", so |
| 1774 | /// it cannot be used when a readable map is needed, for example as |
| 1775 | /// \c ReachedMap for Bfs, Dfs and Dijkstra algorithms. |
| 1776 | /// |
| 1777 | /// \relates StoreBoolMap |
| 1778 | template<typename Iterator> |
| 1779 | inline StoreBoolMap<Iterator> storeBoolMap(Iterator it) { |
| 1780 | return StoreBoolMap<Iterator>(it); |
| 1781 | } |
1748 | 1782 | |
1749 | 1783 | /// @} |
1750 | 1784 | } |
diff -r 500f3cbff9e4 -r c7d30f7810e5 test/maps_test.cc
a
|
b
|
|
304 | 304 | check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3], |
305 | 305 | "Something is wrong with EqualMap"); |
306 | 306 | } |
| 307 | |
| 308 | // StoreBoolMap |
| 309 | { |
| 310 | typedef std::vector<int> vec; |
| 311 | vec v1; |
| 312 | vec v2(10); |
| 313 | StoreBoolMap<std::back_insert_iterator<vec> > map1(std::back_inserter(v1)); |
| 314 | StoreBoolMap<vec::iterator> map2(v2.begin()); |
| 315 | map1.set(10, false); |
| 316 | map1.set(20, true); map2.set(20, true); |
| 317 | map1.set(30, false); map2.set(40, false); |
| 318 | map1.set(50, true); map2.set(50, true); |
| 319 | map1.set(60, true); map2.set(60, true); |
| 320 | check(v1.size() == 3 && v2.size() == 10 && |
| 321 | v1[0]==20 && v1[1]==50 && v1[2]==60 && v2[0]==20 && v2[1]==50 && v2[2]==60, |
| 322 | "Something is wrong with StoreBoolMap"); |
| 323 | |
| 324 | int i = 0; |
| 325 | for ( StoreBoolMap<vec::iterator>::Iterator it = map2.begin(); |
| 326 | it != map2.end(); ++it ) |
| 327 | check(v1[i++] == *it, "Something is wrong with StoreBoolMap"); |
| 328 | } |
307 | 329 | |
308 | 330 | return 0; |
309 | 331 | } |