Add highier-order functions to MapIterator
authorMaciej Piechotka <uzytkownik2@gmail.com>
Tue, 4 Jan 2011 14:23:14 +0000 (15:23 +0100)
committerMaciej Piechotka <uzytkownik2@gmail.com>
Tue, 4 Jan 2011 14:23:14 +0000 (15:23 +0100)
gee/mapiterator.vala
tests/testmap.vala

index 30df860..5479e0c 100644 (file)
  *     Didier 'Ptitjes Villevalois <ptitjes@free.fr>
  */
 
+namespace Gee {
+       public delegate A FoldMapFunc<A, K, V> (K k, V v, owned A a);
+       public delegate void ForallMapFunc<K, V> (K k, V v);
+}
+
 /**
  * An iterator over a map.
  *
@@ -97,5 +102,36 @@ public interface Gee.MapIterator<K,V> : Object {
         * of iterator may cache it.
         */
        public abstract bool read_only { get; }
+       
+       /**
+        * Standard aggragation function.
+        *
+        * It takes a function, seed and first element, returns the new seed and
+        * progress to next element when the operation repeats.
+        *
+        * Operation moves the iterator to last element in iteration. If iterator
+        * points at some element it will be included in iteration.
+        */
+       public virtual A fold<A> (FoldMapFunc<A, K, V> f, owned A seed)
+       {
+               if (valid)
+                       seed = f (get_key (), get_value (), (owned) seed);
+               while (next ())
+                       seed = f (get_key (), get_value (), (owned) seed);
+               return (owned) seed;
+       }
+       
+       /**
+        * Apply function to each element returned by iterator. 
+        *
+        * Operation moves the iterator to last element in iteration. If iterator
+        * points at some element it will be included in iteration.
+        */
+       public new virtual void foreach (ForallMapFunc<K, V> f) {
+               if (valid)
+                       f (get_key (), get_value ());
+               while (next ())
+                       f (get_key (), get_value ());
+       }
 }
 
index df7aa54..8ae85a2 100644 (file)
@@ -39,6 +39,8 @@ public abstract class MapTests : Gee.TestCase {
                add_test ("[Map] unset all", test_unset_all);
                add_test ("[Map] has all", test_has_all);
                add_test ("[Map] GObject properties", test_gobject_properties);
+               add_test ("[Map] fold", test_fold);
+               add_test ("[Map] foreach", test_foreach);
        }
 
        protected Map<string, string> test_map;
@@ -527,6 +529,38 @@ public abstract class MapTests : Gee.TestCase {
                assert (value.get_int () == test_map.size);
                value.unset ();
        }
+       
+       public void test_fold () {
+               test_map.set ("one", "one");
+               test_map.set ("two", "two");
+               test_map.set ("three", "three");
+               
+               int count;
+               
+               count = test_map.map_iterator ().fold<int> ((x, y, z) => {return z + 1;}, 0);
+               assert (count == 3);
+               
+               var iter = test_map.map_iterator ();
+               assert (iter.next ());
+               count = iter.fold<int> ((x, y, z) => {return z + 1;}, 0);
+               assert (count == 3);
+       }
+       
+       public void test_foreach () {
+               test_map.set ("one", "one");
+               test_map.set ("two", "two");
+               test_map.set ("three", "three");
+               
+               int count = 0;
+               
+               test_map.map_iterator ().foreach ((x, y) => {count++;});
+               assert (count == 3);
+               
+               var iter = test_map.map_iterator ();
+               assert (iter.next ());
+               iter.foreach ((x, y) => {count++;});
+               assert (count == 6);
+       }