[libgee] Add explicit implementation of tee to all iterators



commit c34ec562b4618229d4eabf3a466903358d132b4c
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date:   Sat Aug 2 21:30:08 2014 +0200

    Add explicit implementation of tee to all iterators

 gee/arraylist.vala          |   35 ++++++++++---
 gee/arrayqueue.vala         |   29 +++++++++--
 gee/concurrentlist.vala     |   30 +++++++++--
 gee/concurrentset.vala      |   59 ++++++++++++++++++---
 gee/hashmap.vala            |   78 ++++++++++++++++++++++++----
 gee/hashset.vala            |   37 ++++++++++---
 gee/linkedlist.vala         |   33 ++++++++++--
 gee/priorityqueue.vala      |   33 ++++++++++--
 gee/readonlycollection.vala |   19 +++++++
 gee/teeiterator.vala        |   13 +++++
 gee/treemap.vala            |  121 ++++++++++++++++++++++++++++++++++++++++++-
 gee/treeset.vala            |   68 +++++++++++++++++++-----
 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);


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