[libgee] Fix various memory leaks in gee by re-implementing GClosure



commit 95c6a736eccbdd3fe5b6387453f6638e59ca38ea
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date:   Mon Dec 16 00:26:38 2013 +0100

    Fix various memory leaks in gee by re-implementing GClosure

 gee/arraylist.vala      |   20 +++++++++++++++---
 gee/arrayqueue.vala     |    9 ++++++-
 gee/concurrentlist.vala |   21 ++++++++++++++++---
 gee/concurrentset.vala  |    2 +-
 gee/functions.vala      |   33 ++++++++++++++++++++++++++++++++
 gee/hashmap.vala        |   48 +++++++++++++++++++++++++++++++++++++++++-----
 gee/hashmultimap.vala   |   29 ++++++++++++++++++++-------
 gee/hashmultiset.vala   |   26 ++++++++++++++++++++++++-
 gee/hashset.vala        |   27 ++++++++++++++++++++++---
 gee/lightmapfuture.vala |    4 +-
 gee/linkedlist.vala     |   16 ++++++++++++--
 gee/priorityqueue.vala  |   10 +++++++-
 gee/streamiterator.vala |    2 +-
 gee/task.vala           |    6 ++--
 gee/timsort.vala        |    2 +-
 gee/treemap.vala        |   29 ++++++++++++++++++++++++---
 gee/treemultimap.vala   |   17 +++++++++++----
 gee/treemultiset.vala   |    6 ++++-
 gee/treeset.vala        |   14 +++++++++++-
 19 files changed, 267 insertions(+), 54 deletions(-)
---
diff --git a/gee/arraylist.vala b/gee/arraylist.vala
index 2c58717..83c7e72 100644
--- a/gee/arraylist.vala
+++ b/gee/arraylist.vala
@@ -56,10 +56,16 @@ public class Gee.ArrayList<G> : AbstractBidirList<G> {
         * The elements' equality testing function.
         */
        [CCode (notify = false)]
-       public EqualDataFunc<G> equal_func { private set; get; }
+       public EqualDataFunc<G> equal_func {
+               private set {}
+               get {
+                       return _equal_func.func;
+               }
+       }
 
        internal G[] _items;
        internal int _size;
+       private Functions.EqualDataFuncClosure<G> _equal_func;
 
        // concurrent modification protection
        private int _stamp = 0;
@@ -76,7 +82,7 @@ public class Gee.ArrayList<G> : AbstractBidirList<G> {
                if (equal_func == null) {
                        equal_func = Functions.get_equal_func_for (typeof (G));
                }
-               this.equal_func = equal_func;
+               _equal_func = new Functions.EqualDataFuncClosure<G>((owned)equal_func);
                _items = new G[4];
                _size = 0;
        }
@@ -94,11 +100,17 @@ public class Gee.ArrayList<G> : AbstractBidirList<G> {
                if (equal_func == null) {
                        equal_func = Functions.get_equal_func_for (typeof (G));
                }
-               this.equal_func = equal_func;
+               _equal_func = new Functions.EqualDataFuncClosure<G>((owned)equal_func);
                _size = items.length;
                _items = do_wrap<G> ((owned)items);
        }
 
+       internal ArrayList.with_closure (owned Functions.EqualDataFuncClosure<G> equal_func) {
+               _equal_func = equal_func;
+               _items = new G[4];
+               _size = 0;
+       }
+
        /**
         * { inheritDoc}
         */
@@ -246,7 +258,7 @@ public class Gee.ArrayList<G> : AbstractBidirList<G> {
                return_val_if_fail (start >= 0, null);
                return_val_if_fail (stop <= _size, null);
 
-               var slice = new ArrayList<G> (this.equal_func);
+               var slice = new ArrayList<G>.with_closure (_equal_func);
                for (int i = start; i < stop; i++) {
                        slice.add (this[i]);
                }
diff --git a/gee/arrayqueue.vala b/gee/arrayqueue.vala
index ea1a806..f8d17d7 100644
--- a/gee/arrayqueue.vala
+++ b/gee/arrayqueue.vala
@@ -44,12 +44,17 @@ public class Gee.ArrayQueue<G> : Gee.AbstractQueue<G>, Deque<G> {
                if (equal_func == null) {
                        equal_func = Functions.get_equal_func_for (typeof (G));
                }
-               this.equal_func = equal_func;
+               _equal_func = (owned)equal_func;
                this._items = new G[10];
        }
 
        [CCode (notify = false)]
-       public EqualDataFunc<G> equal_func { private set; get; }
+       public EqualDataFunc<G> equal_func {
+               private set {}
+               get { return _equal_func; }
+       }
+
+       private EqualDataFunc<G> _equal_func;
 
        /**
         * { inheritDoc}
diff --git a/gee/concurrentlist.vala b/gee/concurrentlist.vala
index d645b68..c3137df 100644
--- a/gee/concurrentlist.vala
+++ b/gee/concurrentlist.vala
@@ -33,7 +33,12 @@ public class Gee.ConcurrentList<G> : AbstractList<G> {
         * The elements' equality testing function.
         */
        [CCode (notify = false)]
-       public Gee.EqualDataFunc<G> equal_func { private set; get; }
+       public Gee.EqualDataFunc<G> equal_func {
+               private set {}
+               get {
+                       return _equal_func.func;
+               }
+       }
 
        /**
         * Construct new, empty single linked list
@@ -44,9 +49,16 @@ public class Gee.ConcurrentList<G> : AbstractList<G> {
         * @param equal_func an optional element equality testing function
         */
        public ConcurrentList (owned Gee.EqualDataFunc<G>? equal_func = null) {
-               if (equal_func == null)
+               if (equal_func == null) {
                        equal_func = Gee.Functions.get_equal_func_for (typeof (G));
-               this.equal_func = (owned)equal_func;
+               }
+               _equal_func = new Functions.EqualDataFuncClosure<G>((owned)equal_func);
+               _head = new Node<G>.head ();
+               HazardPointer.set_pointer<Node<G>> (&_tail, _head);
+       }
+
+       internal ConcurrentList.with_closure (owned Functions.EqualDataFuncClosure<G> equal_func) {
+               _equal_func = (owned)equal_func;
                _head = new Node<G>.head ();
                HazardPointer.set_pointer<Node<G>> (&_tail, _head);
        }
@@ -232,7 +244,7 @@ public class Gee.ConcurrentList<G> : AbstractList<G> {
                HazardPointer.Context ctx = new HazardPointer.Context ();
                assert (0 <= start);
                assert (start <= end);
-               var list = new ConcurrentList<G> (equal_func);
+               var list = new ConcurrentList<G>.with_closure (_equal_func);
                var iterator = iterator ();
                int idx = 0;
                for (; iterator.next (); idx++)
@@ -258,6 +270,7 @@ public class Gee.ConcurrentList<G> : AbstractList<G> {
 
        private Node<G> _head;
        private Node<G> *_tail;
+       private Functions.EqualDataFuncClosure<G> _equal_func;
 
        private class Iterator<G> : Object, Gee.Traversable<G>, Gee.Iterator<G>, ListIterator<G> {
                public Iterator (Node<G> head) {
diff --git a/gee/concurrentset.vala b/gee/concurrentset.vala
index c0d3d75..747e579 100644
--- a/gee/concurrentset.vala
+++ b/gee/concurrentset.vala
@@ -33,7 +33,7 @@ public class Gee.ConcurrentSet<G> : AbstractSortedSet<G> {
                if (compare_func == null) {
                        compare_func = Functions.get_compare_func_for (typeof (G));
                }
-               _cmp = compare_func;
+               _cmp = (owned)compare_func;
        }
 
        ~ConcurrentSet () {
diff --git a/gee/functions.vala b/gee/functions.vala
index 0a72832..dcd1c56 100644
--- a/gee/functions.vala
+++ b/gee/functions.vala
@@ -148,5 +148,38 @@ namespace Gee {
                                };
                        }
                }
+
+               [CCode (simple_generics = true)]
+               internal class EqualDataFuncClosure<G> {
+                       public EqualDataFuncClosure(owned EqualDataFunc<G> func) {
+                               this.func = (owned)func;
+                       }
+                       public EqualDataFunc<G> func;
+                       public EqualDataFunc<G> clone_func () {
+                               return (a, b) => {return func (a, b);};
+                       }
+               }
+
+               [CCode (simple_generics = true)]
+               internal class HashDataFuncClosure<G> {
+                       public HashDataFuncClosure(owned HashDataFunc<G> func) {
+                               this.func = (owned)func;
+                       }
+                       public HashDataFunc<G> func;
+                       public HashDataFunc<G> clone_func () {
+                               return (a) => {return func (a);};
+                       }
+               }
+
+               [CCode (simple_generics = true)]
+               internal class CompareDataFuncClosure<G> {
+                       public CompareDataFuncClosure(owned CompareDataFunc<G> func) {
+                               this.func = (owned)func;
+                       }
+                       public CompareDataFunc<G> func;
+                       public CompareDataFunc<G> clone_func () {
+                               return (a, b) => {return func (a, b);};
+                       }
+               }
        }
 }
diff --git a/gee/hashmap.vala b/gee/hashmap.vala
index da06f72..805d075 100644
--- a/gee/hashmap.vala
+++ b/gee/hashmap.vala
@@ -97,23 +97,42 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> {
         * The keys' hash function.
         */
        [CCode (notify = false)]
-       public HashDataFunc<K> key_hash_func { private set; get; }
+       public HashDataFunc<K> key_hash_func {
+               private set {}
+               get {
+                       return _key_hash_func.func;
+               }
+       }
 
        /**
         * The keys' equality testing function.
         */
        [CCode (notify = false)]
-       public EqualDataFunc<K> key_equal_func { private set; get; }
+       public EqualDataFunc<K> key_equal_func {
+               private set {}
+               get {
+                       return _key_equal_func.func;
+               }
+       }
 
        /**
         * The values' equality testing function.
         */
        [CCode (notify = false)]
-       public EqualDataFunc<V> value_equal_func { private set; get; }
+       public EqualDataFunc<V> value_equal_func {
+               private set {}
+               get {
+                       return _value_equal_func.func;
+               }
+       }
 
        private int _array_size;
        private int _nnodes;
        private Node<K,V>[] _nodes;
+       private Functions.HashDataFuncClosure<K> _key_hash_func;
+       private Functions.EqualDataFuncClosure<K> _key_equal_func;
+       private Functions.EqualDataFuncClosure<V> _value_equal_func;
+
 
        private weak Set<K> _keys;
        private weak Collection<V> _values;
@@ -145,9 +164,18 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> {
                if (value_equal_func == null) {
                        value_equal_func = Functions.get_equal_func_for (typeof (V));
                }
-               this.key_hash_func = key_hash_func;
-               this.key_equal_func = key_equal_func;
-               this.value_equal_func = value_equal_func;
+               _key_hash_func = new Functions.HashDataFuncClosure<K> ((owned)key_hash_func);
+               _key_equal_func = new Functions.EqualDataFuncClosure<K> ((owned)key_equal_func);
+               _value_equal_func = new Functions.EqualDataFuncClosure<V> ((owned)value_equal_func);
+
+               _array_size = MIN_SIZE;
+               _nodes = new Node<K,V>[_array_size];
+       }
+
+       internal HashMap.with_closures (owned Functions.HashDataFuncClosure<K> key_hash_func, owned 
Functions.EqualDataFuncClosure<K> key_equal_func, owned Functions.EqualDataFuncClosure<V> value_equal_func) {
+               _key_hash_func = key_hash_func;
+               _key_equal_func = key_equal_func;
+               _value_equal_func = value_equal_func;
 
                _array_size = MIN_SIZE;
                _nodes = new Node<K,V>[_array_size];
@@ -241,6 +269,14 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> {
                return new MapIterator<K,V> (this);
        }
 
+       internal Functions.HashDataFuncClosure<K> get_key_hash_func_closure () {
+               return _key_hash_func;
+       }
+
+       internal Functions.EqualDataFuncClosure<K> get_key_equal_func_closure () {
+               return _key_equal_func;
+       }
+
        private inline bool unset_helper (K key, out V? value = null) {
                Node<K,V>** node = lookup_node (key);
                if (*node != null) {
diff --git a/gee/hashmultimap.vala b/gee/hashmultimap.vala
index d3a2144..44c29a9 100644
--- a/gee/hashmultimap.vala
+++ b/gee/hashmultimap.vala
@@ -33,10 +33,20 @@ public class Gee.HashMultiMap<K,V> : AbstractMultiMap<K,V> {
        }
 
        [CCode (notify = false)]
-       public HashDataFunc<V> value_hash_func { private set; get; }
+       public HashDataFunc<V> value_hash_func {
+               private set {}
+               get {
+                       return _value_hash_func.func;
+               }
+       }
 
        [CCode (notify = false)]
-       public EqualDataFunc<V> value_equal_func { private set; get; }
+       public EqualDataFunc<V> value_equal_func {
+               private set {}
+               get {
+                       return _value_equal_func.func;
+               }
+       }
 
        /**
         * Constructs a new, empty hash multimap.
@@ -51,26 +61,29 @@ public class Gee.HashMultiMap<K,V> : AbstractMultiMap<K,V> {
         */
        public HashMultiMap (owned HashDataFunc<K>? key_hash_func = null, owned EqualDataFunc<K>? 
key_equal_func = null,
                             owned HashDataFunc<V>? value_hash_func = null, owned EqualDataFunc<V>? 
value_equal_func = null) {
-               base (new HashMap<K, Set<V>> (key_hash_func, key_equal_func, Functions.get_equal_func_for 
(typeof (Set))));
+               base (new HashMap<K, Set<V>> ((owned)key_hash_func, (owned)key_equal_func, 
Functions.get_equal_func_for (typeof (Set))));
                if (value_hash_func == null) {
                        value_hash_func = Functions.get_hash_func_for (typeof (V));
                }
                if (value_equal_func == null) {
                        value_equal_func = Functions.get_equal_func_for (typeof (V));
                }
-               this.value_hash_func = value_hash_func;
-               this.value_equal_func = value_equal_func;
+               _value_hash_func = new Functions.HashDataFuncClosure<V> ((owned)value_hash_func);
+               _value_equal_func = new Functions.EqualDataFuncClosure<V> ((owned)value_equal_func);
        }
 
        protected override Collection<V> create_value_storage () {
-               return new HashSet<V> (_value_hash_func, _value_equal_func);
+               return new HashSet<V>.with_closures (_value_hash_func, _value_equal_func);
        }
 
        protected override MultiSet<K> create_multi_key_set () {
-               return new HashMultiSet<K> (key_hash_func, key_equal_func);
+               return new HashMultiSet<K>.with_closures (((HashMap<K, Set<V>>) 
_storage_map).get_key_hash_func_closure (), ((HashMap<K, Set<V>>) _storage_map).get_key_equal_func_closure 
());
        }
 
        protected override EqualDataFunc<V> get_value_equal_func () {
-               return _value_equal_func;
+               return _value_equal_func.clone_func ();
        }
+
+       private Functions.HashDataFuncClosure<V> _value_hash_func;
+       private Functions.EqualDataFuncClosure<V> _value_equal_func;
 }
diff --git a/gee/hashmultiset.vala b/gee/hashmultiset.vala
index 2e59c07..e7b7c1b 100644
--- a/gee/hashmultiset.vala
+++ b/gee/hashmultiset.vala
@@ -41,7 +41,31 @@ public class Gee.HashMultiSet<G> : AbstractMultiSet<G> {
         * @param hash_func an optional element hash function
         * @param equal_func an optional element equality testing function
         */
-       public HashMultiSet (HashDataFunc<G>? hash_func = null, EqualDataFunc<G>? equal_func = null) {
+       [CCode (cname = "gee_hash_multi_set_new_fixed")]
+       public HashMultiSet (owned HashDataFunc<G>? hash_func = null, owned EqualDataFunc<G>? equal_func = 
null) {
+               base (new HashMap<G, int> ((owned)hash_func, (owned)equal_func));
+       }
+
+       /**
+        * Constructs a new, empty hash multi set.
+        *
+        * If not provided, the functions parameters are requested to the
+        * { link Functions} function factory methods.
+        *
+        * Note: this function is only for backward ABI compatibility.
+        *   It contains memory leak and SHOULD NOT BE USED.
+        * 
+        *
+        * @param hash_func an optional element hash function
+        * @param equal_func an optional element equality testing function
+        */
+       [Deprecated (since = "0.13.3", replacement = "gee_hash_multi_set_new_fixed")]
+       [CCode (cname = "gee_hash_multi_set_new")]
+       public HashMultiSet.broken (owned HashDataFunc<G>? hash_func = null, owned EqualDataFunc<G>? 
equal_func = null) {
                base (new HashMap<G, int> (hash_func, equal_func));
        }
+
+       internal HashMultiSet.with_closures (owned Functions.HashDataFuncClosure<G> hash_func, owned 
Functions.EqualDataFuncClosure<G> equal_func) {
+               base (new HashMap<G, int>.with_closures ((owned)hash_func, (owned)equal_func, new 
Functions.EqualDataFuncClosure<int> (Functions.get_equal_func_for (typeof (int)))));
+       }
 }
diff --git a/gee/hashset.vala b/gee/hashset.vala
index b196c58..a01089a 100644
--- a/gee/hashset.vala
+++ b/gee/hashset.vala
@@ -57,17 +57,29 @@ public class Gee.HashSet<G> : AbstractSet<G> {
         * The elements' hash function.
         */
        [CCode (notify = false)]
-       public HashDataFunc<G> hash_func { private set; get; }
+       public HashDataFunc<G> hash_func {
+               private set {}
+               get {
+                       return _hash_func.func;
+               }
+       }
 
        /**
         * The elements' equality testing function.
         */
        [CCode (notify = false)]
-       public EqualDataFunc<G> equal_func { private set; get; }
+       public EqualDataFunc<G> equal_func {
+               private set {}
+               get {
+                       return _equal_func.func;
+               }
+       }
 
        private int _array_size;
        private int _nnodes;
        private Node<G>[] _nodes;
+       private Functions.HashDataFuncClosure<G> _hash_func;
+       private Functions.EqualDataFuncClosure<G> _equal_func;
 
        // concurrent modification protection
        private int _stamp = 0;
@@ -91,8 +103,15 @@ public class Gee.HashSet<G> : AbstractSet<G> {
                if (equal_func == null) {
                        equal_func = Functions.get_equal_func_for (typeof (G));
                }
-               this.hash_func = hash_func;
-               this.equal_func = equal_func;
+               _hash_func = new Functions.HashDataFuncClosure<G> ((owned)hash_func);
+               _equal_func = new Functions.EqualDataFuncClosure<G> ((owned)equal_func);
+               _array_size = MIN_SIZE;
+               _nodes = new Node<G>[_array_size];
+       }
+
+       internal HashSet.with_closures (owned Functions.HashDataFuncClosure<G> hash_func, owned 
Functions.EqualDataFuncClosure<G> equal_func) {
+               _hash_func = hash_func;
+               _equal_func = equal_func;
                _array_size = MIN_SIZE;
                _nodes = new Node<G>[_array_size];
        }
diff --git a/gee/lightmapfuture.vala b/gee/lightmapfuture.vala
index a5adaed..60c888b 100644
--- a/gee/lightmapfuture.vala
+++ b/gee/lightmapfuture.vala
@@ -20,9 +20,9 @@
  *     Maciej Piechotka <uzytkownik2 gmail com>
  */
 internal class Gee.LightMapFuture<A, G> : Object, Future<A> {
-       public LightMapFuture (Future<G> base_future, Future.LightMapFunc<A, G> func) {
+       public LightMapFuture (Future<G> base_future, owned Future.LightMapFunc<A, G> func) {
                _base = base_future;
-               _func = func;
+               _func = (owned)func;
        }
 
        public bool ready {
diff --git a/gee/linkedlist.vala b/gee/linkedlist.vala
index 54e7cf8..40251ba 100644
--- a/gee/linkedlist.vala
+++ b/gee/linkedlist.vala
@@ -37,12 +37,18 @@ public class Gee.LinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G> {
        private int _stamp = 0;
        private Node<G>? _head = null;
        private weak Node<G>? _tail = null;
+       private Functions.EqualDataFuncClosure<G> _equal_func;
 
        /**
         * The elements' equality testing function.
         */
        [CCode (notify = false)]
-       public EqualDataFunc<G> equal_func { private set; get; }
+       public EqualDataFunc<G> equal_func {
+               private set {}
+               get {
+                       return _equal_func.func;
+               }
+       }
 
        /**
         * Constructs a new, empty linked list.
@@ -56,7 +62,11 @@ public class Gee.LinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G> {
                if (equal_func == null) {
                        equal_func = Functions.get_equal_func_for (typeof (G));
                }
-               this.equal_func = equal_func;
+               _equal_func = new Functions.EqualDataFuncClosure<G> ((owned)equal_func);
+       }
+
+       private LinkedList.with_closures (owned Functions.EqualDataFuncClosure<G> equal_func) {
+               _equal_func = equal_func;
        }
        
        ~LinkedList () {
@@ -257,7 +267,7 @@ public class Gee.LinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G> {
                return_val_if_fail (start >= 0, null);
                return_val_if_fail (stop <= this._size, null);
 
-               List<G> slice = new LinkedList<G> (this.equal_func);
+               List<G> slice = new LinkedList<G>.with_closures (_equal_func);
                weak Node<G> n = this._get_node_at (start);
                for (int i = start; i < stop; i++) {
                        slice.add (n.data);
diff --git a/gee/priorityqueue.vala b/gee/priorityqueue.vala
index 9b2cbdc..309d36f 100644
--- a/gee/priorityqueue.vala
+++ b/gee/priorityqueue.vala
@@ -46,7 +46,12 @@ public class Gee.PriorityQueue<G> : Gee.AbstractQueue<G> {
         * The elements' comparator function.
         */
        [CCode (notify = false)]
-       public CompareDataFunc<G> compare_func { private set; get; }
+       public CompareDataFunc<G> compare_func {
+               private set {}
+               get {
+                       return _compare_func;
+               }
+       }
 
        private int _size = 0;
        private int _stamp = 0;
@@ -67,6 +72,7 @@ public class Gee.PriorityQueue<G> : Gee.AbstractQueue<G> {
        private Type1Node<G>? _ll_tail = null;
        private unowned Node<G> _iter_head = null;
        private unowned Node<G> _iter_tail = null;
+       private CompareDataFunc<G> _compare_func;
 
        /**
         * Constructs a new, empty priority queue.
@@ -80,7 +86,7 @@ public class Gee.PriorityQueue<G> : Gee.AbstractQueue<G> {
                if (compare_func == null) {
                        compare_func = Functions.get_compare_func_for (typeof (G));
                }
-               this.compare_func = compare_func;
+               _compare_func = (owned)compare_func;
        }
 
        /**
diff --git a/gee/streamiterator.vala b/gee/streamiterator.vala
index ac21138..ae78b30 100644
--- a/gee/streamiterator.vala
+++ b/gee/streamiterator.vala
@@ -74,7 +74,7 @@ internal class Gee.StreamIterator<A, G> : GLib.Object, Traversable<A>, Iterator<
                        return true;
                }
                unowned Iterator<G> outer = _outer;
-               StreamFunc<A, G> func = _func;
+               unowned StreamFunc<A, G> func = _func;
                Traversable.Stream state = _state;
                bool need_next = _need_next;
                bool result = true;
diff --git a/gee/task.vala b/gee/task.vala
index 9c914a5..9e398bf 100644
--- a/gee/task.vala
+++ b/gee/task.vala
@@ -20,6 +20,7 @@
  *     Maciej Piechotka <uzytkownik2 gmail com>
  */
 namespace Gee {
+       [CCode (scope = "async")]
        public delegate G Task<G>();
 
        /**
@@ -36,9 +37,9 @@ namespace Gee {
         *   block inside the taks. If necessary it is possible to create a new one
         *   by anyther call.
         */
-       public Future<G> task<G>(Task<G> task) throws GLib.ThreadError {
+       public Future<G> task<G>(owned Task<G> task) throws GLib.ThreadError {
                TaskData<G> tdata = new TaskData<G>();
-               tdata.function = task;
+               tdata.function = (owned)task;
                tdata.promise = new Promise<G>();
                Future<G> result = tdata.promise.future;
                TaskData.get_async_pool ().add ((owned)tdata);
@@ -63,7 +64,6 @@ namespace Gee {
 
        [Compact]
        internal class TaskData<G> {
-               [CCode (scope = "async")]
                public Task<G> function;
                public Promise<G> promise;
                public void run() {
diff --git a/gee/timsort.vala b/gee/timsort.vala
index a5b9778..ad1e52e 100644
--- a/gee/timsort.vala
+++ b/gee/timsort.vala
@@ -94,7 +94,7 @@ internal class Gee.TimSort<G> : Object {
        private int size;
        private Slice<G>[] pending;
        private int minimum_gallop;
-       private CompareDataFunc<G> compare;
+       private unowned CompareDataFunc<G> compare;
 
        private void do_sort () {
                if (size < 2) {
diff --git a/gee/treemap.vala b/gee/treemap.vala
index b957aff..c3ef896 100644
--- a/gee/treemap.vala
+++ b/gee/treemap.vala
@@ -92,19 +92,31 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> {
         * The keys' comparator function.
         */
        [CCode (notify = false)]
-       public CompareDataFunc<K> key_compare_func { private set; get; }
+       public CompareDataFunc<K> key_compare_func {
+               private set {}
+               get {
+                       return _key_compare_func.func;
+               }
+       }
 
        /**
         * The values' equality testing function.
         */
        [CCode (notify = false)]
-       public EqualDataFunc<V> value_equal_func { private set; get; }
+       public EqualDataFunc<V> value_equal_func {
+               private set {}
+               get {
+                       return _value_equal_func.func;
+               }
+       }
 
        private int _size = 0;
 
        private weak SortedSet<K> _keys;
        private weak Collection<V> _values;
        private weak SortedSet<Map.Entry<K,V>> _entries;
+       private Functions.CompareDataFuncClosure<K> _key_compare_func;
+       private Functions.EqualDataFuncClosure<V> _value_equal_func;
 
        /**
         * Constructs a new, empty tree map sorted according to the specified
@@ -123,8 +135,13 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> {
                if (value_equal_func == null) {
                        value_equal_func = Functions.get_equal_func_for (typeof (V));
                }
-               this.key_compare_func = key_compare_func;
-               this.value_equal_func = value_equal_func;
+               _key_compare_func = new Functions.CompareDataFuncClosure<K> ((owned)key_compare_func);
+               _value_equal_func = new Functions.EqualDataFuncClosure<V> ((owned)value_equal_func);
+       }
+
+       internal TreeMap.with_closures (owned Functions.CompareDataFuncClosure<K> key_compare_func, owned 
Functions.EqualDataFuncClosure<V> value_equal_func) {
+               _key_compare_func = key_compare_func;
+               _value_equal_func = value_equal_func;
        }
 
        ~TreeMap () {
@@ -457,6 +474,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> {
                return new MapIterator<K,V> (this);
        }
 
+       internal Functions.CompareDataFuncClosure<K> get_key_compare_func_closure () {
+               return _key_compare_func;
+       }
+
        [Compact]
        private class Node<K, V> {
                public enum Color {
diff --git a/gee/treemultimap.vala b/gee/treemultimap.vala
index eb7c245..ec16bfe 100644
--- a/gee/treemultimap.vala
+++ b/gee/treemultimap.vala
@@ -30,7 +30,12 @@ public class Gee.TreeMultiMap<K,V> : AbstractMultiMap<K,V> {
        }
 
        [CCode (notify = false)]
-       public CompareDataFunc<V> value_compare_func { private set; get; }
+       public CompareDataFunc<V> value_compare_func {
+               private set {}
+               get {
+                       return _value_compare_func.func;
+               }
+       }
 
        /**
         * Constructs a new, empty tree multimap.
@@ -42,22 +47,24 @@ public class Gee.TreeMultiMap<K,V> : AbstractMultiMap<K,V> {
         * @param value_compare_func an optional value comparator function
         */
        public TreeMultiMap (owned CompareDataFunc<K>? key_compare_func = null, owned CompareDataFunc<V>? 
value_compare_func = null) {
-               base (new TreeMap<K, Set<V>> (key_compare_func, Functions.get_equal_func_for (typeof (Set))));
+               base (new TreeMap<K, Set<V>> ((owned)key_compare_func, Functions.get_equal_func_for (typeof 
(Set))));
                if (value_compare_func == null) {
                        value_compare_func = Functions.get_compare_func_for (typeof (V));
                }
-               this.value_compare_func = value_compare_func;
+               _value_compare_func = new Functions.CompareDataFuncClosure<V> ((owned)value_compare_func);
        }
 
        protected override Collection<V> create_value_storage () {
-               return new TreeSet<V> (_value_compare_func);
+               return new TreeSet<V>.with_closures (_value_compare_func);
        }
 
        protected override MultiSet<K> create_multi_key_set () {
-               return new TreeMultiSet<K> (key_compare_func);
+               return new TreeMultiSet<K>.with_closures (((TreeMap<K, Set<V>>) 
_storage_map).get_key_compare_func_closure ());
        }
 
        protected override EqualDataFunc<V> get_value_equal_func () {
                return Functions.get_equal_func_for (typeof (V));
        }
+
+       private Functions.CompareDataFuncClosure<V> _value_compare_func;
 }
diff --git a/gee/treemultiset.vala b/gee/treemultiset.vala
index 39d0640..c38c1f9 100644
--- a/gee/treemultiset.vala
+++ b/gee/treemultiset.vala
@@ -38,6 +38,10 @@ public class Gee.TreeMultiSet<G> : AbstractMultiSet<G> {
         * @param compare_func an optional element comparator function
         */
        public TreeMultiSet (owned CompareDataFunc<G>? compare_func = null) {
-               base (new TreeMap<G, int> (compare_func));
+               base (new TreeMap<G, int> ((owned)compare_func));
+       }
+
+       internal TreeMultiSet.with_closures (owned Functions.CompareDataFuncClosure<G> compare_func) {
+               base (new TreeMap<G, int>.with_closures ((owned)compare_func, new 
Functions.EqualDataFuncClosure<int> (Functions.get_equal_func_for (typeof (int)))));
        }
 }
diff --git a/gee/treeset.vala b/gee/treeset.vala
index c4212df..7d87df9 100644
--- a/gee/treeset.vala
+++ b/gee/treeset.vala
@@ -51,7 +51,12 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> {
         * The elements' comparator function.
         */
        [CCode (notify = false)]
-       public CompareDataFunc<G> compare_func { private set; get; }
+       public CompareDataFunc<G> compare_func {
+               private set {}
+               get {
+                       return _compare_func.func;
+               }
+       }
 
        private int _size = 0;
 
@@ -68,7 +73,11 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> {
                if (compare_func == null) {
                        compare_func = Functions.get_compare_func_for (typeof (G));
                }
-               this.compare_func = compare_func;
+               _compare_func = new Functions.CompareDataFuncClosure<G> ((owned)compare_func);
+       }
+
+       internal TreeSet.with_closures (owned Functions.CompareDataFuncClosure<G> compare_func) {
+               _compare_func = (owned)compare_func;
        }
 
        ~TreeSet () {
@@ -1171,4 +1180,5 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> {
        private weak Node<G>? _first = null;
        private weak Node<G>? _last = null;
        private int stamp = 0;
+       private Functions.CompareDataFuncClosure<G> _compare_func;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]