diff options
author | Maciej Piechotka <uzytkownik2@gmail.com> | 2014-08-02 21:30:08 +0200 |
---|---|---|
committer | Maciej Piechotka <uzytkownik2@gmail.com> | 2014-08-16 16:50:57 +0200 |
commit | c34ec562b4618229d4eabf3a466903358d132b4c (patch) | |
tree | 003f8a48f25716594824b3e8a33341c2d23d09b3 | |
parent | 7c723b1193424fbf160f025d4161cb8cb21e169e (diff) | |
download | libgee-c34ec562b4618229d4eabf3a466903358d132b4c.tar.gz |
Add explicit implementation of tee to all iterators
-rw-r--r-- | gee/arraylist.vala | 35 | ||||
-rw-r--r-- | gee/arrayqueue.vala | 29 | ||||
-rw-r--r-- | gee/concurrentlist.vala | 30 | ||||
-rw-r--r-- | gee/concurrentset.vala | 59 | ||||
-rw-r--r-- | gee/hashmap.vala | 78 | ||||
-rw-r--r-- | gee/hashset.vala | 37 | ||||
-rw-r--r-- | gee/linkedlist.vala | 33 | ||||
-rw-r--r-- | gee/priorityqueue.vala | 33 | ||||
-rw-r--r-- | gee/readonlycollection.vala | 19 | ||||
-rw-r--r-- | gee/teeiterator.vala | 13 | ||||
-rw-r--r-- | gee/treemap.vala | 121 | ||||
-rw-r--r-- | gee/treeset.vala | 68 | ||||
-rw-r--r-- | gee/unrolledlinkedlist.vala | 22 |
13 files changed, 502 insertions, 75 deletions
diff --git a/gee/arraylist.vala b/gee/arraylist.vala index 0cbad76..c672639 100644 --- a/gee/arraylist.vala +++ b/gee/arraylist.vala @@ -4,6 +4,7 @@ * Copyright (C) 2005 David Waite * Copyright (C) 2007-2008 Jürg Billeter * Copyright (C) 2009 Didier Villevalois + * Copyright (C) 2010-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -319,18 +320,18 @@ public class Gee.ArrayList<G> : AbstractBidirList<G> { } private class Iterator<G> : Object, Traversable<G>, Gee.Iterator<G>, BidirIterator<G>, ListIterator<G>, BidirListIterator<G> { - private ArrayList<G> _list; - private int _index = -1; - private bool _removed = false; - - // concurrent modification protection - private int _stamp = 0; - - public Iterator (ArrayList list) { + public Iterator (ArrayList<G> list) { _list = list; _stamp = _list._stamp; } + public Iterator.from_iterator (Iterator<G> iter) { + _list = iter._list; + _index = iter._index; + _removed = iter._removed; + _stamp = iter._stamp; + } + public bool next () { assert (_stamp == _list._stamp); if (_index + 1 < _list._size) { @@ -480,6 +481,24 @@ public class Gee.ArrayList<G> : AbstractBidirList<G> { _index = _list._size - 1; return true; } + + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + + protected ArrayList<G> _list; + protected int _index = -1; + protected bool _removed = false; + protected int _stamp = 0; } private static G[] do_wrap<G> (owned G[] data) { diff --git a/gee/arrayqueue.vala b/gee/arrayqueue.vala index f8d17d7..d332af7 100644 --- a/gee/arrayqueue.vala +++ b/gee/arrayqueue.vala @@ -1,6 +1,6 @@ /* arrayqueue.vala * - * Copyright (C) 2012 Maciej Piechotka + * Copyright (C) 2012-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -294,6 +294,12 @@ public class Gee.ArrayQueue<G> : Gee.AbstractQueue<G>, Deque<G> { _queue = queue; _stamp = _queue._stamp; } + public Iterator.from_iterator (Iterator<G> iter) { + _queue = iter._queue; + _stamp = iter._stamp; + _offset = iter._offset; + _removed = iter._removed; + } public bool next () { assert (_queue._stamp == _stamp); @@ -345,10 +351,23 @@ public class Gee.ArrayQueue<G> : Gee.AbstractQueue<G>, Deque<G> { return true; } - private ArrayQueue _queue; - private int _stamp; - private int _offset = -1; - private bool _removed = false; + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + + protected ArrayQueue _queue; + protected int _stamp; + protected int _offset = -1; + protected bool _removed = false; } private G[] _items; diff --git a/gee/concurrentlist.vala b/gee/concurrentlist.vala index 7863fa8..58bc022 100644 --- a/gee/concurrentlist.vala +++ b/gee/concurrentlist.vala @@ -1,6 +1,6 @@ /* concurrentlist.vala * - * Copyright (C) 2011 Maciej Piechotka + * Copyright (C) 2011-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -292,6 +292,13 @@ public class Gee.ConcurrentList<G> : AbstractList<G> { _curr = head; } + public Iterator.from_iterator (Iterator<G> iter) { + _removed = iter._removed; + _index = iter._index; + _prev = iter._prev; + _curr = iter._curr; + } + public bool next () { HazardPointer.Context ctx = new HazardPointer.Context (); Utils.Misc.unused (ctx); @@ -393,10 +400,23 @@ public class Gee.ConcurrentList<G> : AbstractList<G> { return true; } - private bool _removed; - private int _index; - private Node<G>? _prev; - private Node<G> _curr; + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + + protected bool _removed; + protected int _index; + protected Node<G>? _prev; + protected Node<G> _curr; } private class Node<G> { diff --git a/gee/concurrentset.vala b/gee/concurrentset.vala index 217c73a..5a642ae 100644 --- a/gee/concurrentset.vala +++ b/gee/concurrentset.vala @@ -1,6 +1,6 @@ /* concurrentset.vala * - * Copyright (C) 2012 Maciej Piechotka + * Copyright (C) 2012-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -268,6 +268,13 @@ public class Gee.ConcurrentSet<G> : AbstractSortedSet<G> { assert (_curr != null); } + public Iterator.from_iterator (Iterator<G> iter) { + _curr = iter._curr; + _set = iter._set; + _prev = iter._prev; + _removed = iter._removed; + } + public new bool foreach (ForallFunc<G> f) { assert (_curr != null); HazardPointer.Context ctx = new HazardPointer.Context (); @@ -301,6 +308,19 @@ public class Gee.ConcurrentSet<G> : AbstractSortedSet<G> { return true; } + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + public bool next () { HazardPointer.Context ctx = new HazardPointer.Context (); Utils.Misc.unused (ctx); @@ -350,10 +370,10 @@ public class Gee.ConcurrentSet<G> : AbstractSortedSet<G> { public bool read_only { get { return true; } } - private bool _removed = false; - private ConcurrentSet<G> _set; - private TowerIter<G> _prev; - private Tower<G> _curr; + protected bool _removed = false; + protected ConcurrentSet<G> _set; + protected TowerIter<G> _prev; + protected Tower<G> _curr; } private class SubSet<G> : AbstractSortedSet<G> { @@ -649,6 +669,14 @@ public class Gee.ConcurrentSet<G> : AbstractSortedSet<G> { _curr = curr; } + public SubIterator.from_iterator (SubIterator<G> iter) { + Range.improve_bookmark<G> (iter._range); + _range = iter._range; + _prev = iter._prev; + _curr = iter._curr; + _removed = iter._removed; + } + public new bool foreach (ForallFunc<G> f) { assert (_curr != null); HazardPointer.Context ctx = new HazardPointer.Context (); @@ -685,6 +713,19 @@ public class Gee.ConcurrentSet<G> : AbstractSortedSet<G> { return true; } + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new SubIterator<G>.from_iterator (this); + } + return result; + } + } + public bool next () { HazardPointer.Context ctx = new HazardPointer.Context (); Utils.Misc.unused (ctx); @@ -766,10 +807,10 @@ public class Gee.ConcurrentSet<G> : AbstractSortedSet<G> { return _curr != null; } - private Range<G> _range; - private TowerIter<G> _prev; - private Tower<G>? _curr = null; - private bool _removed = false; + protected Range<G> _range; + protected TowerIter<G> _prev; + protected Tower<G>? _curr = null; + protected bool _removed = false; } private class Range<G> { diff --git a/gee/hashmap.vala b/gee/hashmap.vala index b66a2f4..eb3db89 100644 --- a/gee/hashmap.vala +++ b/gee/hashmap.vala @@ -3,6 +3,7 @@ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * Copyright (C) 1997-2000 GLib Team and others * Copyright (C) 2007-2009 Jürg Billeter + * Copyright (C) 2009-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -484,19 +485,19 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> { } private abstract class NodeIterator<K,V> : Object { - protected HashMap<K,V> _map; - protected int _index = -1; - protected weak Node<K,V> _node; - protected weak Node<K,V> _next; - - // concurrent modification protection - protected int _stamp; - public NodeIterator (HashMap map) { _map = map; _stamp = _map._stamp; } + public NodeIterator.from_iterator (NodeIterator<K,V> iter) { + _map = iter._map; + _index = iter._index; + _node = iter._node; + _next = iter._next; + _stamp = iter._stamp; + } + public bool next () { assert (_stamp == _map._stamp); if (!has_next ()) { @@ -533,6 +534,12 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> { return _node != null; } } + + protected HashMap<K,V> _map; + protected int _index = -1; + protected weak Node<K,V> _node; + protected weak Node<K,V> _next; + protected int _stamp; } private class KeyIterator<K,V> : NodeIterator<K,V>, Traversable<K>, Iterator<K> { @@ -540,6 +547,10 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> { base (map); } + public KeyIterator.from_iterator (KeyIterator<K,V> iter) { + base.from_iterator (iter); + } + public new K get () { assert (_stamp == _map._stamp); assert (_node != null); @@ -574,6 +585,19 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> { } } while(true); } + + public Gee.Iterator<K>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<K>[0]; + } else { + Gee.Iterator<K>[] result = new Gee.Iterator<K>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new KeyIterator<K,V>.from_iterator (this); + } + return result; + } + } } private class MapIterator<K,V> : NodeIterator<K,V>, Gee.MapIterator<K,V> { @@ -623,10 +647,14 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> { } private class ValueIterator<K,V> : NodeIterator<K,V>, Traversable<V>, Iterator<V> { - public ValueIterator (HashMap map) { + public ValueIterator (HashMap<K,V> map) { base (map); } + public ValueIterator.from_iterator (ValueIterator<K,V> iter) { + base.from_iterator (iter); + } + public new V get () { assert (_stamp == _map._stamp); assert (_node != null); @@ -661,13 +689,30 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> { } } while(true); } + + public Gee.Iterator<K>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<K>[0]; + } else { + Gee.Iterator<K>[] result = new Gee.Iterator<K>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new ValueIterator<K,V>.from_iterator (this); + } + return result; + } + } } private class EntryIterator<K,V> : NodeIterator<K,V>, Traversable<Map.Entry<K,V>>, Iterator<Map.Entry<K,V>> { - public EntryIterator (HashMap map) { + public EntryIterator (HashMap<K,V> map) { base (map); } + public EntryIterator.from_iterator (EntryIterator<K,V> iter) { + base.from_iterator (iter); + } + public new Map.Entry<K,V> get () { assert (_stamp == _map._stamp); assert (_node != null); @@ -702,6 +747,19 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> { } } while(true); } + + public Iterator<Map.Entry<K,V>>[] tee (uint forks) { + if (forks == 0) { + return new Iterator<Map.Entry<K,V>>[0]; + } else { + Iterator<Map.Entry<K,V>>[] result = new Iterator<Map.Entry<K,V>>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new EntryIterator<K,V>.from_iterator (this); + } + return result; + } + } } } diff --git a/gee/hashset.vala b/gee/hashset.vala index a01089a..2736554 100644 --- a/gee/hashset.vala +++ b/gee/hashset.vala @@ -3,6 +3,7 @@ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * Copyright (C) 1997-2000 GLib Team and others * Copyright (C) 2007-2009 Jürg Billeter + * Copyright (C) 2009-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -256,19 +257,18 @@ public class Gee.HashSet<G> : AbstractSet<G> { } private class Iterator<G> : Object, Traversable<G>, Gee.Iterator<G> { - private HashSet<G> _set; - private int _index = -1; - private weak Node<G> _node; - private weak Node<G> _next; - - // concurrent modification protection - private int _stamp = 0; - - public Iterator (HashSet set) { + public Iterator (HashSet<G> set) { _set = set; _stamp = _set._stamp; } + public Iterator.from_iterator (Iterator<G> iter) { + _set = iter._set; + _index = iter._index; + _node = iter._node; + _next = iter._next; + } + public bool next () { assert (_stamp == _set._stamp); if (!has_next ()) { @@ -359,6 +359,25 @@ public class Gee.HashSet<G> : AbstractSet<G> { _next = null; return true; } + + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[0] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + + protected HashSet<G> _set; + protected int _index = -1; + protected weak Node<G> _node; + protected weak Node<G> _next; + protected int _stamp = 0; } } diff --git a/gee/linkedlist.vala b/gee/linkedlist.vala index c9d3248..136e35b 100644 --- a/gee/linkedlist.vala +++ b/gee/linkedlist.vala @@ -447,12 +447,6 @@ public class Gee.LinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G> { } private class Iterator<G> : Object, Traversable<G>, Gee.Iterator<G>, BidirIterator<G>, ListIterator<G>, BidirListIterator<G> { - private bool _removed = false; - private unowned Node<G>? _position; - private int _stamp; - private LinkedList<G> _list; - private int _index; - public Iterator (LinkedList<G> list) { this._list = list; this._position = null; @@ -460,6 +454,14 @@ public class Gee.LinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G> { this._stamp = list._stamp; } + public Iterator.from_iterator (Iterator<G> iter) { + _removed = iter._removed; + _position = iter._position; + _stamp = iter._stamp; + _list = iter._list; + _index = iter._index; + } + public bool next () { assert (this._stamp == this._list._stamp); @@ -700,6 +702,25 @@ public class Gee.LinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G> { _position = _list._tail; return true; } + + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + + protected bool _removed = false; + protected unowned Node<G>? _position; + protected int _stamp; + protected LinkedList<G> _list; + protected int _index; } private unowned Node<G>? _get_node_at (int index) { diff --git a/gee/priorityqueue.vala b/gee/priorityqueue.vala index 309d36f..43a60c4 100644 --- a/gee/priorityqueue.vala +++ b/gee/priorityqueue.vala @@ -1,7 +1,7 @@ /* priorityqueue.vala * * Copyright (C) 2009 Didier Villevalois - * Copyright (C) 2012 Maciej Piechotka + * Copyright (C) 2012-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1141,11 +1141,6 @@ public class Gee.PriorityQueue<G> : Gee.AbstractQueue<G> { } private class Iterator<G> : Object, Traversable<G>, Gee.Iterator<G> { - private PriorityQueue<G> queue; - private unowned Node<G>? position; - private unowned Node<G>? previous; - private int stamp; - public Iterator (PriorityQueue<G> queue) { this.queue = queue; this.position = null; @@ -1153,6 +1148,13 @@ public class Gee.PriorityQueue<G> : Gee.AbstractQueue<G> { this.stamp = queue._stamp; } + public Iterator.from_iterator (Iterator<G> iter) { + queue = iter.queue; + position = iter.position; + previous = iter.previous; + stamp = iter.stamp; + } + public bool next () { unowned Node<G>? next = _get_next_node (); if (next != null) { @@ -1230,5 +1232,24 @@ public class Gee.PriorityQueue<G> : Gee.AbstractQueue<G> { } return true; } + + + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + + protected PriorityQueue<G> queue; + protected unowned Node<G>? position; + protected unowned Node<G>? previous; + protected int stamp; } } diff --git a/gee/readonlycollection.vala b/gee/readonlycollection.vala index 9f5823f..0702bf7 100644 --- a/gee/readonlycollection.vala +++ b/gee/readonlycollection.vala @@ -1,6 +1,7 @@ /* readonlycollection.vala * * Copyright (C) 2007-2008 Jürg Billeter + * Copyright (C) 2010-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -225,6 +226,24 @@ internal class Gee.ReadOnlyCollection<G> : Object, Traversable<G>, Iterable<G>, public Gee.Iterator<G> chop (int offset, int length = -1) { return _iter.chop ( offset, length); } + + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] iters = _iter.tee (forks); + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + if (iters[0] == _iter) { + result[0] = this; + } else { + result[0] = new Iterator<G> (iters[0]); + } + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G> (iters[i]); + } + return result; + } + } } public virtual Collection<G> read_only_view { diff --git a/gee/teeiterator.vala b/gee/teeiterator.vala index 47884e4..4d11750 100644 --- a/gee/teeiterator.vala +++ b/gee/teeiterator.vala @@ -49,6 +49,19 @@ internal class Gee.TeeIterator<G> : Object, Traversable<G>, Iterator<G> { return true; } + public Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Iterator<G>[0]; + } else { + Iterator<G>[] result = new Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new TeeIterator<G> (_head, _valid); + } + return result; + } + } + public bool next () { unowned Node<G>? next = _head._next.value; if (next != null) { diff --git a/gee/treemap.vala b/gee/treemap.vala index bd67adb..3b08c12 100644 --- a/gee/treemap.vala +++ b/gee/treemap.vala @@ -1,6 +1,6 @@ /* treemap.vala * - * Copyright (C) 2009-2011 Maciej Piechotka + * Copyright (C) 2009-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1436,6 +1436,15 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { this.current = current; } + public NodeIterator.from_iterator (NodeIterator<K, V> iter) { + _map = iter._map; + stamp = iter.stamp; + started = iter.started; + current = iter.current; + _next = iter._next; + _prev = iter._prev; + } + public bool next () { assert (stamp == _map.stamp); if (current != null) { @@ -1560,6 +1569,12 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { this.iterator = new NodeIterator<K,V>.pointing (_map, node); } + public SubNodeIterator.from_iterator (SubNodeIterator<K,V> iter) { + _map = iter._map; + range = iter.range; + iterator = new NodeIterator<K,V>.from_iterator (iter.iterator); + } + public bool next () { if (iterator != null) { weak Node<K,V>? node= iterator.safe_next_get (); @@ -1627,7 +1642,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { assert (valid); iterator.unset (); } - + public virtual bool read_only { get { return true; @@ -1658,6 +1673,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { base.pointing (map, current); } + public KeyIterator.from_iterator (KeyIterator<K, V> iterator) { + base.from_iterator (iterator); + } + public new K get () { assert (stamp == _map.stamp); assert (current != null); @@ -1687,6 +1706,19 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { } return true; } + + public Gee.Iterator<K>[] tee (uint forks) { + if (forks == 0) { + return new Iterator<K>[0]; + } else { + Gee.Iterator<K>[] result = new Gee.Iterator<K>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new KeyIterator<K,V>.from_iterator (this); + } + return result; + } + } } private class SubKeyIterator<K,V> : SubNodeIterator<K,V>, Traversable<K>, Gee.Iterator<K>, BidirIterator<K> { @@ -1698,6 +1730,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { base.pointing (map, range, node); } + public SubKeyIterator.from_iterator (SubKeyIterator<K, V> iterator) { + base.from_iterator (iterator); + } + public new K get () { assert (valid); return iterator.current.key; @@ -1716,6 +1752,19 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { } return true; } + + public Gee.Iterator<K>[] tee (uint forks) { + if (forks == 0) { + return new Iterator<K>[0]; + } else { + Gee.Iterator<K>[] result = new Gee.Iterator<K>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new SubKeyIterator<K,V>.from_iterator(this); + } + return result; + } + } } private class ValueIterator<K,V> : NodeIterator<K,V>, Traversable<V>, Gee.Iterator<V>, Gee.BidirIterator<V> { @@ -1727,6 +1776,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { base.pointing (map, current); } + public ValueIterator.from_iterator (ValueIterator<K,V> iterator) { + base.from_iterator (iterator); + } + public new V get () { assert (stamp == _map.stamp); assert (valid); @@ -1756,6 +1809,19 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { } return true; } + + public Gee.Iterator<V>[] tee (uint forks) { + if (forks == 0) { + return new Iterator<V>[0]; + } else { + Gee.Iterator<V>[] result = new Gee.Iterator<V>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new ValueIterator<K,V>.from_iterator (this); + } + return result; + } + } } private class SubValueIterator<K,V> : SubNodeIterator<K,V>, Traversable<V>, Gee.Iterator<V>, BidirIterator<V> { @@ -1767,6 +1833,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { base.pointing (map, range, node); } + public SubValueIterator.from_iterator (SubValueIterator<K,V> iterator) { + base.from_iterator (iterator); + } + public new V get () { assert (valid); return iterator.current.value; @@ -1785,6 +1855,19 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { } return true; } + + public Gee.Iterator<V>[] tee (uint forks) { + if (forks == 0) { + return new Iterator<V>[0]; + } else { + Gee.Iterator<V>[] result = new Gee.Iterator<V>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new SubValueIterator<K,V>.from_iterator (this); + } + return result; + } + } } private class EntryIterator<K,V> : NodeIterator<K,V>, Traversable<Map.Entry<K, V>>, Gee.Iterator<Map.Entry<K,V>>, Gee.BidirIterator<Map.Entry<K,V>> { @@ -1796,6 +1879,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { base.pointing (map, node); } + public EntryIterator.from_iterator (EntryIterator<K,V> iterator) { + base.from_iterator (iterator); + } + public new Map.Entry<K,V> get () { assert (stamp == _map.stamp); assert (valid); @@ -1829,6 +1916,19 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { } return true; } + + public Gee.Iterator<Entry<K,V>>[] tee (uint forks) { + if (forks == 0) { + return new Iterator<Entry<K,V>>[0]; + } else { + Gee.Iterator<Entry<K,V>>[] result = new Gee.Iterator<Entry<K,V>>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new EntryIterator<K,V>.from_iterator (this); + } + return result; + } + } } private class SubEntryIterator<K,V> : SubNodeIterator<K,V>, Traversable<Map.Entry<K, V>>, Gee.Iterator<Map.Entry<K,V>>, Gee.BidirIterator<Map.Entry<K,V>> { @@ -1840,6 +1940,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { base.pointing (map, range, node); } + public SubEntryIterator.from_iterator (SubEntryIterator<K,V> iterator) { + base.from_iterator (iterator); + } + public new Map.Entry<K,V> get () { assert (iterator != null); return Entry.entry_for<K,V> (iterator.current); @@ -1862,6 +1966,19 @@ public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { } return true; } + + public Gee.Iterator<Entry<K,V>>[] tee (uint forks) { + if (forks == 0) { + return new Iterator<Entry<K,V>>[0]; + } else { + Gee.Iterator<Entry<K,V>>[] result = new Gee.Iterator<Entry<K,V>>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new SubEntryIterator<K,V>.from_iterator (this); + } + return result; + } + } } private class MapIterator<K,V> : NodeIterator<K,V>, Gee.MapIterator<K,V>, BidirMapIterator<K,V> { diff --git a/gee/treeset.vala b/gee/treeset.vala index 7d87df9..61320a6 100644 --- a/gee/treeset.vala +++ b/gee/treeset.vala @@ -1,6 +1,6 @@ /* treeset.vala * - * Copyright (C) 2009-2011 Maciej Piechotka + * Copyright (C) 2009-2014 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -599,11 +599,6 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> { } private class Iterator<G> : Object, Traversable<G>, Gee.Iterator<G>, BidirIterator<G> { - private TreeSet<G> _set; - - // concurrent modification protection - private int stamp; - public Iterator (TreeSet<G> set) { _set = set; stamp = _set.stamp; @@ -616,6 +611,15 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> { this.started = true; } + public Iterator.from_iterator (Iterator<G> iter) { + _set = iter._set; + stamp = iter.stamp; + _current = iter._current; + _next = iter._next; + _prev = iter._prev; + started = iter.started; + } + public bool next () { assert (stamp == _set.stamp); if (_current != null) { @@ -773,10 +777,25 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> { return true; } - private weak Node<G>? _current = null; - private weak Node<G>? _next = null; - private weak Node<G>? _prev = null; - private bool started = false; + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + + protected TreeSet<G> _set; + protected int stamp; + protected weak Node<G>? _current = null; + protected weak Node<G>? _next = null; + protected weak Node<G>? _prev = null; + protected bool started = false; } private inline G min (G a, G b) { @@ -1061,8 +1080,8 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> { return h != null && range.in_range (h) ? h : null; } - private new TreeSet<G> set; - private Range<G> range; + protected new TreeSet<G> set; + protected Range<G> range; } private class SubIterator<G> : Object, Traversable<G>, Gee.Iterator<G>, BidirIterator<G> { @@ -1077,6 +1096,12 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> { this.iterator = new Iterator<G>.pointing (set, node); } + public SubIterator.from_iterator (SubIterator<G> iter) { + set = iter.set; + range = iter.range; + iterator = new Iterator<G>.from_iterator (iter.iterator); + } + public bool next () { if (iterator != null) { G next; @@ -1171,9 +1196,22 @@ public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> { return true; } - private new TreeSet<G> set; - private Range<G> range; - private Iterator<G>? iterator = null; + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new SubIterator<G>.from_iterator (this); + } + return result; + } + } + + protected new TreeSet<G> set; + protected Range<G> range; + protected Iterator<G>? iterator = null; } private Node<G>? root = null; diff --git a/gee/unrolledlinkedlist.vala b/gee/unrolledlinkedlist.vala index 3b6ec17..c6aac66 100644 --- a/gee/unrolledlinkedlist.vala +++ b/gee/unrolledlinkedlist.vala @@ -730,6 +730,15 @@ public class Gee.UnrolledLinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G this._stamp = list._stamp; } + public Iterator.from_iterator (Iterator<G> iter) { + _list = iter._list; + _stamp = iter._stamp; + _current = iter._current; + _pos = iter._pos; + _deleted = iter._deleted; + _index = iter._index; + } + public new bool foreach (ForallFunc<G> f) { #if DUMP stdout.printf ("FOREACH BEGIN [%p -> %p %d]\n", this, _current, _pos); @@ -803,6 +812,19 @@ public class Gee.UnrolledLinkedList<G> : AbstractBidirList<G>, Queue<G>, Deque<G #endif } + public Gee.Iterator<G>[] tee (uint forks) { + if (forks == 0) { + return new Gee.Iterator<G>[0]; + } else { + Gee.Iterator<G>[] result = new Gee.Iterator<G>[forks]; + result[0] = this; + for (uint i = 1; i < forks; i++) { + result[i] = new Iterator<G>.from_iterator (this); + } + return result; + } + } + public bool next () { #if DUMP stdout.printf ("NEXT BEGIN [%p -> %p %d]\n", this, _current, _pos); |