[Lemon-commits] [lemon_svn] deba: r2760 - hugo/trunk/lemon
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:55:02 CET 2006
Author: deba
Date: Thu May 18 10:04:00 2006
New Revision: 2760
Modified:
hugo/trunk/lemon/maps.h
Log:
Functor usage for writeable map adaptors
Documentation for writeable map adaptors
Modified: hugo/trunk/lemon/maps.h
==============================================================================
--- hugo/trunk/lemon/maps.h (original)
+++ hugo/trunk/lemon/maps.h Thu May 18 10:04:00 2006
@@ -20,6 +20,7 @@
#define LEMON_MAPS_H
#include <iterator>
+#include <functional>
#include <lemon/bits/utility.h>
#include <lemon/bits/traits.h>
@@ -1008,22 +1009,55 @@
return NotWriteMap<M>(m);
}
+ namespace _maps_bits {
+ template <typename Value>
+ struct Identity {
+ typedef Value argument_type;
+ typedef Value result_type;
+ Value operator()(const Value& val) {
+ return val;
+ }
+ };
+ }
+
+
/// \brief Writable bool map for store each true assigned elements.
///
/// Writable bool map for store each true assigned elements. It will
/// copies all the true setted keys to the given iterator.
///
- /// \note The container of the iterator should contain for each element.
- template <typename _Iterator>
+ /// \note The container of the iterator should contain space
+ /// for each element.
+ ///
+ /// The next example shows how can you write the nodes directly
+ /// to the standard output.
+ ///\code
+ /// typedef IdMap<UGraph, UEdge> UEdgeIdMap;
+ /// UEdgeIdMap uedgeId(ugraph);
+ ///
+ /// typedef MapFunctor<UEdgeIdMap> UEdgeIdFunctor;
+ /// UEdgeIdFunctor uedgeIdFunctor(uedgeId);
+ ///
+ /// StoreBoolMap<ostream_iterator<int>, UEdgeIdFunctor>
+ /// writerMap(ostream_iterator<int>(cout, " "), uedgeIdFunctor);
+ ///
+ /// prim(ugraph, cost, writerMap);
+ ///\endcode
+ template <typename _Iterator,
+ typename _Functor =
+ _maps_bits::Identity<typename std::iterator_traits<_Iterator>::value_type> >
class StoreBoolMap {
public:
typedef _Iterator Iterator;
- typedef typename std::iterator_traits<Iterator>::value_type Key;
+ typedef typename _Functor::argument_type Key;
typedef bool Value;
+ typedef _Functor Functor;
+
/// Constructor
- StoreBoolMap(Iterator it) : _begin(it), _end(it) {}
+ StoreBoolMap(Iterator it, const Functor& functor = Functor())
+ : _begin(it), _end(it), _functor(functor) {}
/// Gives back the given first setted iterator.
Iterator begin() const {
@@ -1038,12 +1072,13 @@
/// Setter function of the map
void set(const Key& key, Value value) {
if (value) {
- *_end++ = key;
+ *_end++ = _functor(key);
}
}
private:
Iterator _begin, _end;
+ Functor _functor;
};
/// \brief Writable bool map for store each true assigned elements in
@@ -1051,25 +1086,43 @@
///
/// Writable bool map for store each true assigned elements in a back
/// insertable container. It will push back all the true setted keys into
- /// the container.
- template <typename Container>
+ /// the container. It can be used to retrieve the items into a standard
+ /// container. The next example shows how can you store the undirected
+ /// edges in a vector with prim algorithm.
+ ///
+ ///\code
+ /// vector<UEdge> span_tree_uedges;
+ /// BackInserterBoolMap<vector<UEdge> > inserter_map(span_tree_uedges);
+ /// prim(ugraph, cost, inserter_map);
+ ///
+ /// for (int i = 0; i < (int)span_tree_uedges.size(); ++i) {
+ /// std::cout << ugraph.id(ugraph.source(span_tree_uedges[i])) << ' '
+ /// << ugraph.id(ugraph.target(span_tree_uedges[i])) << ' '
+ /// << cost[span_tree_uedges[i]] << endl;
+ ///\endcode
+ template <typename Container,
+ typename Functor =
+ _maps_bits::Identity<typename Container::value_type> >
class BackInserterBoolMap {
public:
typedef typename Container::value_type Key;
typedef bool Value;
/// Constructor
- BackInserterBoolMap(Container& _container) : container(_container) {}
+ BackInserterBoolMap(Container& _container,
+ const Functor& _functor = Functor())
+ : container(_container), functor(_functor) {}
/// Setter function of the map
void set(const Key& key, Value value) {
if (value) {
- container.push_back(key);
+ container.push_back(functor(key));
}
}
private:
- Container& container;
+ Container& container;
+ Functor functor;
};
/// \brief Writable bool map for store each true assigned elements in
@@ -1077,15 +1130,19 @@
///
/// Writable bool map for store each true assigned elements in a front
/// insertable container. It will push front all the true setted keys into
- /// the container.
- template <typename Container>
+ /// the container. For example see the BackInserterBoolMap.
+ template <typename Container,
+ typename Functor =
+ _maps_bits::Identity<typename Container::value_type> >
class FrontInserterBoolMap {
public:
typedef typename Container::value_type Key;
typedef bool Value;
/// Constructor
- FrontInserterBoolMap(Container& _container) : container(_container) {}
+ FrontInserterBoolMap(Container& _container,
+ const Functor& _functor = Functor())
+ : container(_container), functor(_functor) {}
/// Setter function of the map
void set(const Key& key, Value value) {
@@ -1096,6 +1153,7 @@
private:
Container& container;
+ Functor functor;
};
/// \brief Writable bool map for store each true assigned elements in
@@ -1103,25 +1161,43 @@
///
/// Writable bool map for store each true assigned elements in an
/// insertable container. It will insert all the true setted keys into
- /// the container.
- template <typename Container>
+ /// the container. If you want to store the cut edges of the strongly
+ /// connected components in a set you can use the next code:
+ ///
+ ///\code
+ /// set<Edge> cut_edges;
+ /// InserterBoolMap<set<Edge> > inserter_map(cut_edges);
+ /// stronglyConnectedCutEdges(graph, cost, inserter_map);
+ ///\endcode
+ template <typename Container,
+ typename Functor =
+ _maps_bits::Identity<typename Container::value_type> >
class InserterBoolMap {
public:
typedef typename Container::value_type Key;
typedef bool Value;
/// Constructor
- InserterBoolMap(Container& _container) : container(_container) {}
+ InserterBoolMap(Container& _container, typename Container::iterator _it,
+ const Functor& _functor = Functor())
+ : container(_container), it(_it), functor(_functor) {}
+
+ /// Constructor
+ InserterBoolMap(Container& _container, const Functor& _functor = Functor())
+ : container(_container), it(_container.end()), functor(_functor) {}
/// Setter function of the map
void set(const Key& key, Value value) {
if (value) {
- container.insert(key);
+ it = container.insert(it, key);
+ ++it;
}
}
private:
- Container& container;
+ Container& container;
+ typename Container::iterator it;
+ Functor functor;
};
/// \brief Fill the true setted elements with a given value.
@@ -1129,6 +1205,27 @@
/// Writable bool map for fill the true setted elements with a given value.
/// The value can be setted
/// the container.
+ ///
+ /// The next code finds the connected components of the undirected graph
+ /// and stores it in the \c comp map:
+ ///\code
+ /// typedef UGraph::NodeMap<int> ComponentMap;
+ /// ComponentMap comp(ugraph);
+ /// typedef FillBoolMap<UGraph::NodeMap<int> > ComponentFillerMap;
+ /// ComponentFillerMap filler(comp, 0);
+ ///
+ /// Dfs<UGraph>::DefProcessedMap<ComponentFillerMap>::Create dfs(ugraph);
+ /// dfs.processedMap(filler);
+ /// dfs.init();
+ /// for (NodeIt it(ugraph); it != INVALID; ++it) {
+ /// if (!dfs.reached(it)) {
+ /// dfs.addSource(it);
+ /// dfs.start();
+ /// ++filler.fillValue();
+ /// }
+ /// }
+ ///\endcode
+
template <typename Map>
class FillBoolMap {
public:
@@ -1144,7 +1241,12 @@
: map(_map), fill() {}
/// Gives back the current fill value
- typename Map::Value fillValue() const {
+ const typename Map::Value& fillValue() const {
+ return fill;
+ }
+
+ /// Gives back the current fill value
+ typename Map::Value& fillValue() {
return fill;
}
@@ -1170,7 +1272,53 @@
/// the setting order number.
///
/// Writable bool map which stores for each true assigned elements
- /// the setting order number.
+ /// the setting order number. It make easy to calculate the leaving
+ /// order of the nodes in the \ref dfs "Dfs" algorithm.
+ ///
+ ///\code
+ /// typedef Graph::NodeMap<int> OrderMap;
+ /// OrderMap order(graph);
+ /// typedef SettingOrderBoolMap<OrderMap> OrderSetterMap;
+ /// OrderSetterMap setter(order);
+ /// Dfs<Graph>::DefProcessedMap<OrderSetterMap>::Create dfs(graph);
+ /// dfs.processedMap(setter);
+ /// dfs.init();
+ /// for (NodeIt it(graph); it != INVALID; ++it) {
+ /// if (!dfs.reached(it)) {
+ /// dfs.addSource(it);
+ /// dfs.start();
+ /// }
+ /// }
+ ///\endcode
+ ///
+ /// The discovering order can be stored a little harder because the
+ /// ReachedMap should be readable in the dfs algorithm but the setting
+ /// order map is not readable. Now we should use the fork map:
+ ///
+ ///\code
+ /// typedef Graph::NodeMap<int> OrderMap;
+ /// OrderMap order(graph);
+ /// typedef SettingOrderBoolMap<OrderMap> OrderSetterMap;
+ /// OrderSetterMap setter(order);
+ /// typedef Graph::NodeMap<bool> StoreMap;
+ /// StoreMap store(graph);
+ ///
+ /// typedef ForkWriteMap<StoreMap, OrderSetterMap> ReachedMap;
+ /// ReachedMap reached(store, setter);
+ ///
+ /// Dfs<Graph>::DefReachedMap<ReachedMap>::Create dfs(graph);
+ /// dfs.reachedMap(reached);
+ /// dfs.init();
+ /// for (NodeIt it(graph); it != INVALID; ++it) {
+ /// if (!dfs.reached(it)) {
+ /// dfs.addSource(it);
+ /// dfs.start();
+ /// }
+ /// }
+ /// for (NodeIt it(graph); it != INVALID; ++it) {
+ /// cout << graph.id(it) << ' ' << order[it] << endl;
+ /// }
+ ///\endcode
template <typename Map>
class SettingOrderBoolMap {
public:
More information about the Lemon-commits
mailing list