[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