summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Piechotka <uzytkownik2@gmail.com>2013-12-16 00:26:38 +0100
committerMaciej Piechotka <uzytkownik2@gmail.com>2013-12-16 00:26:38 +0100
commit95c6a736eccbdd3fe5b6387453f6638e59ca38ea (patch)
tree106be506d8b093d87e35237ed991cbd74210d2b6
parent7c8cf016cea73762bcc2020631e7afb34e9cef0c (diff)
downloadlibgee-95c6a736eccbdd3fe5b6387453f6638e59ca38ea.tar.gz
Fix various memory leaks in gee by re-implementing GClosure
-rw-r--r--gee/arraylist.vala20
-rw-r--r--gee/arrayqueue.vala9
-rw-r--r--gee/concurrentlist.vala21
-rw-r--r--gee/concurrentset.vala2
-rw-r--r--gee/functions.vala33
-rw-r--r--gee/hashmap.vala48
-rw-r--r--gee/hashmultimap.vala29
-rw-r--r--gee/hashmultiset.vala26
-rw-r--r--gee/hashset.vala27
-rw-r--r--gee/lightmapfuture.vala4
-rw-r--r--gee/linkedlist.vala16
-rw-r--r--gee/priorityqueue.vala10
-rw-r--r--gee/streamiterator.vala2
-rw-r--r--gee/task.vala6
-rw-r--r--gee/timsort.vala2
-rw-r--r--gee/treemap.vala29
-rw-r--r--gee/treemultimap.vala17
-rw-r--r--gee/treemultiset.vala6
-rw-r--r--gee/treeset.vala14
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;
}