# HG changeset patch
# User klao
# Date 1095607496 0
# Node ID 5e59c44b6ba2826dd6f7c2a181ecfc67e8b5ae26
# Parent  b06bfaaca48c6397dea820585a868f0857e5dd9c
Kruskal cleanup:
- resolved the NonConstMapWr bug
- docs added for NonConstMapWr and KruskalSequenceOut
diff -r b06bfaaca48c -r 5e59c44b6ba2 src/hugo/kruskal.h
--- a/src/hugo/kruskal.h	Sun Sep 19 13:39:25 2004 +0000
+++ b/src/hugo/kruskal.h	Sun Sep 19 15:24:56 2004 +0000
@@ -81,8 +81,18 @@
 
   /* A work-around for running Kruskal with const-reference bool maps... */
 
-  ///\bug What is this? Or why doesn't it work?
+  /// Helper class for calling kruskal with "constant" output map.
+
+  /// Helper class for calling kruskal with output maps constructed
+  /// on-the-fly.
   ///
+  /// A typical examle is the following call:
+  /// kruskal(G, some_input, makeSequenceOutput(iterator)).
+  /// Here, the third argument is a temporary object (which wraps around an
+  /// iterator with a writable bool map interface), and thus by rules of C++
+  /// is a \c const object. To enable call like this exist this class and
+  /// the prototype of the \ref kruskal() function with const& OUT
+  /// third argument.
   template
   class NonConstMapWr {
     const Map &m;
@@ -97,9 +107,8 @@
 
   template 
   inline
-  typename IN::ValueType
-  kruskal(GR const& G, IN const& edges, 
-	  OUT const& out_map)
+  typename IN::value_type::second_type
+  kruskal(GR const& G, IN const& edges, OUT const& out_map)
   {
     NonConstMapWr map_wr(out_map);
     return kruskal(G, edges, map_wr);
@@ -151,8 +160,7 @@
     KruskalMapInput(GR const& G, Map const& m) {
       typedef typename GR::EdgeIt EdgeIt;
       
-      this->clear();
-      for(EdgeIt e(G);e!=INVALID;++e) push_back(make_pair(e, m[e]));
+      for(EdgeIt e(G);e!=INVALID;++e) push_back(value_type(e, m[e]));
       sort();
     }
   };
@@ -184,24 +192,44 @@
   }
   
   
-  /* ** ** Output-objects: simple writable bool maps** ** */
+
+  /* ** ** Output-objects: simple writable bool maps ** ** */
   
+
+
   /// A writable bool-map that makes a sequence of "true" keys
 
   /// A writable bool-map that creates a sequence out of keys that receives
   /// the value "true".
+  ///
+  /// \sa makeKruskalSequenceOutput()
+  ///
+  /// Very often, when looking for a min cost spanning tree, we want as
+  /// output a container containing the edges of the found tree. For this
+  /// purpose exist this class that wraps around an STL iterator with a
+  /// writable bool map interface. When a key gets value "true" this key
+  /// is added to sequence pointed by the iterator.
+  ///
+  /// A typical usage:
+  /// \code
+  /// std::vector v;
+  /// kruskal(g, input, makeKruskalSequenceOutput(back_inserter(v)));
+  /// \endcode
+  /// 
+  /// For the most common case, when the input is given by a simple edge
+  /// map and the output is a sequence of the tree edges, a special
+  /// wrapper function exists: \ref kruskalEdgeMap_IteratorOut().
+  ///
   /// \warning Not a regular property map, as it doesn't know its KeyType
-  /// \bug Missing documentation.
-  /// \todo This class may be of wider usage, therefore it could move to
-  /// maps.h
+
   template
-  class SequenceOutput {
+  class KruskalSequenceOutput {
     mutable Iterator it;
 
   public:
     typedef bool ValueType;
 
-    SequenceOutput(Iterator const &_it) : it(_it) {}
+    KruskalSequenceOutput(Iterator const &_it) : it(_it) {}
 
     template
     void set(KeyType const& k, bool v) const { if(v) {*it=k; ++it;} }
@@ -209,14 +237,17 @@
 
   template
   inline
-  SequenceOutput
-  makeSequenceOutput(Iterator it) {
-    return SequenceOutput(it);
+  KruskalSequenceOutput
+  makeKruskalSequenceOutput(Iterator it) {
+    return KruskalSequenceOutput(it);
   }
 
+
+
   /* ** ** Wrapper funtions ** ** */
 
 
+
   /// \brief Wrapper function to kruskal().
   /// Input is from an edge map, output is a plain bool map.
   ///
@@ -239,7 +270,6 @@
   ///
   /// \return The cost of the found tree.
 
-
   template 
   inline
   typename IN::ValueType
@@ -284,6 +314,7 @@
   /// \return The cost of the found tree.
   ///
   /// \bug its name does not follow the coding style.
+
   template 
   inline
   typename IN::ValueType
@@ -291,10 +322,8 @@
 			     const IN& in,
 			     RET out)
   {
-    SequenceOutput _out(out);
-    return kruskal(G,
-		   KruskalMapInput(G, in),
-		   _out);
+    KruskalSequenceOutput _out(out);
+    return kruskal(G, KruskalMapInput(G, in), _out);
   }
 
   /// @}
diff -r b06bfaaca48c -r 5e59c44b6ba2 src/test/kruskal_test.cc
--- a/src/test/kruskal_test.cc	Sun Sep 19 13:39:25 2004 +0000
+++ b/src/test/kruskal_test.cc	Sun Sep 19 15:24:56 2004 +0000
@@ -81,6 +81,15 @@
 	==-31,
 	"Total cost should be -31.");
 
+  tree_edge_vec.clear();
+
+  //The above test could also be coded like this:
+  check(kruskal(G,
+		makeKruskalMapInput(G, edge_cost_map),
+		makeKruskalSequenceOutput(back_inserter(tree_edge_vec)))
+	==-31,
+	"Total cost should be -31.");
+
   check(tree_edge_vec.size()==5,"The tree should have 5 edges.");
 
   check(tree_edge_vec[0]==e1 &&