diff options
author | Maciej Piechotka <uzytkownik2@gmail.com> | 2013-12-16 00:26:38 +0100 |
---|---|---|
committer | Maciej Piechotka <uzytkownik2@gmail.com> | 2013-12-16 00:26:38 +0100 |
commit | 95c6a736eccbdd3fe5b6387453f6638e59ca38ea (patch) | |
tree | 106be506d8b093d87e35237ed991cbd74210d2b6 | |
parent | 7c8cf016cea73762bcc2020631e7afb34e9cef0c (diff) | |
download | libgee-95c6a736eccbdd3fe5b6387453f6638e59ca38ea.tar.gz |
Fix various memory leaks in gee by re-implementing GClosure
-rw-r--r-- | gee/arraylist.vala | 20 | ||||
-rw-r--r-- | gee/arrayqueue.vala | 9 | ||||
-rw-r--r-- | gee/concurrentlist.vala | 21 | ||||
-rw-r--r-- | gee/concurrentset.vala | 2 | ||||
-rw-r--r-- | gee/functions.vala | 33 | ||||
-rw-r--r-- | gee/hashmap.vala | 48 | ||||
-rw-r--r-- | gee/hashmultimap.vala | 29 | ||||
-rw-r--r-- | gee/hashmultiset.vala | 26 | ||||
-rw-r--r-- | gee/hashset.vala | 27 | ||||
-rw-r--r-- | gee/lightmapfuture.vala | 4 | ||||
-rw-r--r-- | gee/linkedlist.vala | 16 | ||||
-rw-r--r-- | gee/priorityqueue.vala | 10 | ||||
-rw-r--r-- | gee/streamiterator.vala | 2 | ||||
-rw-r--r-- | gee/task.vala | 6 | ||||
-rw-r--r-- | gee/timsort.vala | 2 | ||||
-rw-r--r-- | gee/treemap.vala | 29 | ||||
-rw-r--r-- | gee/treemultimap.vala | 17 | ||||
-rw-r--r-- | gee/treemultiset.vala | 6 | ||||
-rw-r--r-- | 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; } |