[libgee] Add Traversable.chop function



commit 563e82d22cfb98840faaef069abe5786af78ec8b
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date:   Wed Aug 17 21:45:44 2011 +0100

    Add Traversable.chop function

 gee/abstractcollection.vala |    4 +++
 gee/abstractmap.vala        |   12 ++++++++-
 gee/abstractmultiset.vala   |    4 +++
 gee/arraylist.vala          |    4 +++
 gee/hashmap.vala            |   12 ++++++++
 gee/hashset.vala            |    4 +++
 gee/linkedlist.vala         |    4 +++
 gee/priorityqueue.vala      |    4 +++
 gee/readonlycollection.vala |   14 ++++++++++
 gee/readonlymap.vala        |    6 +++-
 gee/traversable.vala        |   61 ++++++++++++++++++++++++++++++++++++++++++-
 gee/treemap.vala            |   24 +++++++++++++++++
 gee/treeset.vala            |    8 +++++
 gee/unfolditerator.vala     |    4 +++
 tests/testcollection.vala   |   22 +++++++++++++++
 15 files changed, 184 insertions(+), 3 deletions(-)
---
diff --git a/gee/abstractcollection.vala b/gee/abstractcollection.vala
index f335c1b..b114be1 100644
--- a/gee/abstractcollection.vala
+++ b/gee/abstractcollection.vala
@@ -286,6 +286,10 @@ public abstract class Gee.AbstractCollection<G> : Object, Traversable<G>, Iterab
 		return Traversable.filter_impl<G> (this, (owned) f);
 	}
 
+	public virtual Iterator<G> chop (int offset, int length = -1) {
+		return Traversable.chop_impl<G> (this, offset, length);
+	}
+
 	private weak Collection<G> _read_only_view;
 
 	/**
diff --git a/gee/abstractmap.vala b/gee/abstractmap.vala
index e8dee90..ea6982d 100644
--- a/gee/abstractmap.vala
+++ b/gee/abstractmap.vala
@@ -222,7 +222,17 @@ public abstract class Gee.AbstractMap<K,V> : Object, Traversable<Map.Entry<K,V>>
 		return iterator ().stream<A> ((owned) f);
 	}
 
-	public Gee.Iterator<Map.Entry<K,V>> filter (owned Predicate<Map.Entry<K,V>> f) {
+	/**
+	 * { inheritDoc}
+	 */
+	public virtual Iterator<Map.Entry<K,V>> filter (owned Predicate<Map.Entry<K,V>> f) {
 		return Traversable.filter_impl<Map.Entry<K,V>> (this, (owned)f);
 	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public virtual Iterator<Map.Entry<K,V>> chop (int offset, int length = -1) {
+		return Traversable.chop_impl<Map.Entry<K,V>> (this, offset, length);
+	}
 }
diff --git a/gee/abstractmultiset.vala b/gee/abstractmultiset.vala
index 3beec43..fc9fe7d 100644
--- a/gee/abstractmultiset.vala
+++ b/gee/abstractmultiset.vala
@@ -169,5 +169,9 @@ public abstract class Gee.AbstractMultiSet<G> : AbstractCollection<G>, MultiSet<
 		public Gee.Iterator<G> filter (owned Predicate<G> f) {
 			return Traversable.filter_impl<G> (this, (owned)f);
 		}
+
+		public Gee.Iterator<G> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<G> (this, offset, length);
+		}
 	}
 }
diff --git a/gee/arraylist.vala b/gee/arraylist.vala
index 0b38068..69472bf 100644
--- a/gee/arraylist.vala
+++ b/gee/arraylist.vala
@@ -399,6 +399,10 @@ public class Gee.ArrayList<G> : AbstractList<G> {
 		public Gee.Iterator<G> filter (owned Predicate<G> f) {
 			return Traversable.filter_impl<G> (this, (owned)f);
 		}
+
+		public Gee.Iterator<G> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<G> (this, offset, length);
+		}
 	}
 }
 
diff --git a/gee/hashmap.vala b/gee/hashmap.vala
index fa47b17..aeb5c96 100644
--- a/gee/hashmap.vala
+++ b/gee/hashmap.vala
@@ -565,6 +565,10 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> {
 		public Gee.Iterator<K> filter (owned Predicate<K> f) {
 			return Traversable.filter_impl<K> (this, (owned)f);
 		}
+
+		public Gee.Iterator<K> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<K> (this, offset, length);
+		}
 	}
 
 	private class MapIterator<K,V> : NodeIterator<K,V>, Gee.MapIterator<K,V> {
@@ -654,6 +658,10 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> {
 		public Gee.Iterator<V> filter (owned Predicate<V> f) {
 			return Traversable.filter_impl<V> (this, (owned)f);
 		}
+
+		public Gee.Iterator<V> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<V> (this, offset, length);
+		}
 	}
 
 	private class EntryIterator<K,V> : NodeIterator<K,V>, Traversable<Map.Entry<K,V>>, Iterator<Map.Entry<K,V>> {
@@ -697,6 +705,10 @@ public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> {
 		public Gee.Iterator<Map.Entry<K,V>> filter (owned Predicate<Map.Entry<K,V>> f) {
 			return Traversable.filter_impl<Map.Entry<K,V>> (this, (owned)f);
 		}
+
+		public Iterator<Map.Entry<K,V>> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<Map.Entry<K,V>> (this, offset, length);
+		}
 	}
 }
 
diff --git a/gee/hashset.vala b/gee/hashset.vala
index fa11f0f..85152f5 100644
--- a/gee/hashset.vala
+++ b/gee/hashset.vala
@@ -302,6 +302,10 @@ public class Gee.HashSet<G> : AbstractSet<G> {
 		public Gee.Iterator<G> filter (owned Predicate<G> f) {
 			return Traversable.filter_impl<G> (this, (owned)f);
 		}
+
+		public Gee.Iterator<G> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<G> (this, offset, length);
+		}
 	}
 }
 
diff --git a/gee/linkedlist.vala b/gee/linkedlist.vala
index c8901b0..56c24cf 100644
--- a/gee/linkedlist.vala
+++ b/gee/linkedlist.vala
@@ -620,6 +620,10 @@ public class Gee.LinkedList<G> : AbstractList<G>, Queue<G>, Deque<G> {
 		public Gee.Iterator<G> filter (owned Predicate<G> f) {
 			return Traversable.filter_impl<G> (this, (owned)f);
 		}
+
+		public Gee.Iterator<G> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<G> (this, offset, length);
+		}
 	}
 
 	private unowned Node<G>? _get_node_at (int index) {
diff --git a/gee/priorityqueue.vala b/gee/priorityqueue.vala
index 1da8dcc..c2275ff 100644
--- a/gee/priorityqueue.vala
+++ b/gee/priorityqueue.vala
@@ -1041,5 +1041,9 @@ public class Gee.PriorityQueue<G> : Gee.AbstractQueue<G> {
 		public Gee.Iterator<G> filter (owned Predicate<G> f) {
 			return Traversable.filter_impl<G> (this, (owned)f);
 		}
+
+		public Gee.Iterator<G> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<G> (this, offset, length);
+		}
 	}
 }
diff --git a/gee/readonlycollection.vala b/gee/readonlycollection.vala
index dc75b88..df5d986 100644
--- a/gee/readonlycollection.vala
+++ b/gee/readonlycollection.vala
@@ -80,6 +80,9 @@ internal class Gee.ReadOnlyCollection<G> : Object, Traversable<G>, Iterable<G>,
 		return _collection.stream<A> ((owned)f);
 	}
 
+	/**
+	 * { inheritDoc}
+	 */
 	public Gee.Iterator<G> filter (owned Predicate<G> f) {
 		return _collection.filter ((owned)f);
 	}
@@ -87,6 +90,13 @@ internal class Gee.ReadOnlyCollection<G> : Object, Traversable<G>, Iterable<G>,
 	/**
 	 * { inheritDoc}
 	 */
+	public Gee.Iterator<G> chop (int offset, int length = -1) {
+		return _collection.chop (offset, length);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
 	public Type element_type {
 		get { return typeof (G); }
 	}
@@ -207,6 +217,10 @@ internal class Gee.ReadOnlyCollection<G> : Object, Traversable<G>, Iterable<G>,
 		public Gee.Iterator<G> filter (owned Predicate<G> f) {
 			return _iter.filter ((owned)f);
 		}
+
+		public Gee.Iterator<G> chop (int offset, int length = -1) {
+			return _iter.chop ( offset, length);
+		}
 	}
 
 	public virtual Collection<G> read_only_view {
diff --git a/gee/readonlymap.vala b/gee/readonlymap.vala
index 8cfe0f6..8921244 100644
--- a/gee/readonlymap.vala
+++ b/gee/readonlymap.vala
@@ -237,7 +237,11 @@ internal class Gee.ReadOnlyMap<K,V> : Object, Traversable<Map.Entry<K,V>>, Itera
 	}
 
 	public Iterator<Map.Entry<K, V>> filter (owned Predicate<Map.Entry<K, V>> f) {
-		return Traversable.filter_impl<Map.Entry<K, V>> (this, (owned)f);
+		return _map.filter ((owned)f);
+	}
+
+	public Iterator<Map.Entry<K, V>> chop (int offset, int length = -1) {
+		return _map.chop (offset, length);
 	}
 
 	protected class MapIterator<K,V> : Object, Gee.MapIterator<K,V> {
diff --git a/gee/traversable.vala b/gee/traversable.vala
index 7ea0e1b..a9ade84 100644
--- a/gee/traversable.vala
+++ b/gee/traversable.vala
@@ -209,7 +209,7 @@ public interface Gee.Traversable<G> : Object
 	 *
 	 * ''Note:'' There is implementation { link filter_impl}.
 	 *
-	 * ''{ link Iterator} implementation:'' Resulting iterator is valid  Using the parent
+	 * ''{ link Iterator} implementation:'' Resulting iterator is valid. Using the parent
 	 * iterator is not allowed befor the inner iterator { link Iterator.next
 	 * next} return false and then it points on its last element.
 	 *
@@ -220,6 +220,27 @@ public interface Gee.Traversable<G> : Object
 	public abstract Iterator<G> filter (owned Predicate<G> f);
 
 	/**
+	 * Creates a new iterator which contains elements from iterable. The
+	 * first argument states the offset i.e. number of elements the iterator
+	 * skips by default.
+	 *
+	 * ''Note:'' There is implementation { link chop_impl}.
+	 *
+	 * ''{ link Iterator} implementation:'' Resulting iterator is valid when
+	 * parent iterator is valid and the offset is 0. Using the parent
+	 * iterator is not allowed befor the inner iterator { link Iterator.next
+	 * next} return false and then it points on its last element.
+	 *
+	 * ''{ link Iterable} implementation:'' Resurling iterator is invalid.
+	 *
+	 * @param offset the offset to first element the iterator is pointing to
+	 * @param length maximum number of elements iterator may return. Negative
+	 *        value means that the number is unbounded
+	 */
+	public abstract Iterator<G> chop (int offset, int length = -1);
+
+
+	/**
 	 * Implementation based on { link stream} for { link filter}.
 	 *
 	 * @param input The current Traversable
@@ -249,6 +270,44 @@ public interface Gee.Traversable<G> : Object
 		});
 	}
 
+	/**
+	 * Implementation based on { link stream} for { link filter}.
+	 *
+	 * @param input The current Traversable
+	 * @param offset The offset
+	 * @param length The length
+	 */
+	public static Iterator<G> chop_impl<G> (Traversable<G> input, int offset, int length) {
+		assert (offset >= 0);
+		return input.stream<G> ((state, item, out val) => {
+			switch (state) {
+			case Stream.YIELD:
+				if (offset > 0) {
+					return Stream.CONTINUE;
+				} else if (length > 0) {
+					length--;
+					return length != 0 ? Stream.CONTINUE : Stream.END;
+				} else if (length == 0) {
+					return Stream.END;
+				} else {
+					return Stream.CONTINUE;
+				}
+			case Stream.CONTINUE:
+				if (offset == 0) {
+					val = item;
+					return Stream.YIELD;
+				} else {
+					offset--;
+					return Stream.CONTINUE;
+				}
+			case Stream.END:
+				return Stream.END;
+			default:
+				assert_not_reached ();
+			};
+		});
+	}
+
 	public enum Stream {
 		YIELD,
 		CONTINUE,
diff --git a/gee/treemap.vala b/gee/treemap.vala
index 355c5b0..9da2b8e 100644
--- a/gee/treemap.vala
+++ b/gee/treemap.vala
@@ -1674,6 +1674,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
 		public Gee.Iterator<K> filter (owned Predicate<K> f) {
 			return Traversable.filter_impl<K> (this, (owned)f);
 		}
+
+		public Gee.Iterator<K> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<K> (this, offset, length);
+		}
 	}
 
 	private class SubKeyIterator<K,V> : SubNodeIterator<K,V>, Traversable<K>, Gee.Iterator<K>, BidirIterator<K> {
@@ -1704,6 +1708,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
 		public Gee.Iterator<K> filter (owned Predicate<K> f) {
 			return Traversable.filter_impl<K> (this, (owned)f);
 		}
+
+		public Gee.Iterator<K> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<K> (this, offset, length);
+		}
 	}
 
 	private class ValueIterator<K,V> : NodeIterator<K,V>, Traversable<V>, Gee.Iterator<V>, Gee.BidirIterator<V> {
@@ -1746,6 +1754,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
 		public Gee.Iterator<V> filter (owned Predicate<V> f) {
 			return Traversable.filter_impl<V> (this, (owned)f);
 		}
+
+		public Gee.Iterator<V> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<V> (this, offset, length);
+		}
 	}
 
 	private class SubValueIterator<K,V> : SubNodeIterator<K,V>, Traversable<V>, Gee.Iterator<V>, BidirIterator<V> {
@@ -1776,6 +1788,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
 		public Gee.Iterator<V> filter (owned Predicate<V> f) {
 			return Traversable.filter_impl<V> (this, (owned)f);
 		}
+
+		public Gee.Iterator<V> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<V> (this, offset, length);
+		}
 	}
 
 	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>> {
@@ -1822,6 +1838,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
 		public Gee.Iterator<Map.Entry<K, V>> filter (owned Predicate<Map.Entry<K, V>> f) {
 			return Traversable.filter_impl<Map.Entry<K, V>> (this, (owned)f);
 		}
+
+		public Gee.Iterator<Map.Entry<K, V>> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<Map.Entry<K, V>> (this, offset, length);
+		}
 	}
 
 	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>> {
@@ -1856,6 +1876,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
 		public Gee.Iterator<Map.Entry<K, V>> filter (owned Predicate<Map.Entry<K, V>> f) {
 			return Traversable.filter_impl<Map.Entry<K, V>> (this, (owned)f);
 		}
+
+		public Gee.Iterator<Map.Entry<K, V>> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<Map.Entry<K, V>> (this, offset, length);
+		}
 	}
 	
 	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 0060345..55be728 100644
--- a/gee/treeset.vala
+++ b/gee/treeset.vala
@@ -741,6 +741,10 @@ public class Gee.TreeSet<G> : AbstractSortedSet<G> {
 			return Traversable.filter_impl<G> (this, (owned)f);
 		}
 
+		public Gee.Iterator<G> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<G> (this, offset, length);
+		}
+
 		private weak Node<G>? current = null;
 		private weak Node<G>? _next = null;
 		private weak Node<G>? _prev = null;
@@ -1140,6 +1144,10 @@ public class Gee.TreeSet<G> : AbstractSortedSet<G> {
 			return Traversable.filter_impl<G> (this, (owned)f);
 		}
 
+		public Gee.Iterator<G> chop (int offset, int length = -1) {
+			return Traversable.chop_impl<G> (this, offset, length);
+		}
+
 		private new TreeSet<G> set;
 		private Range<G> range;
 		private Iterator<G>? iterator = null;
diff --git a/gee/unfolditerator.vala b/gee/unfolditerator.vala
index 442451c..aa4a794 100644
--- a/gee/unfolditerator.vala
+++ b/gee/unfolditerator.vala
@@ -94,6 +94,10 @@ internal class Gee.UnfoldIterator<G> : Object, Traversable<G>, Iterator<G> {
 		return Traversable.filter_impl<G> (this, (owned)f);
 	}
 
+	public Iterator<G> chop (int offset, int length = -1) {
+		return Traversable.chop_impl<G> (this, offset, length);
+	}
+
 	private UnfoldFunc<G> _func;
 	private Lazy<G>? _current;
 	private Lazy<G>? _next;
diff --git a/tests/testcollection.vala b/tests/testcollection.vala
index fa5304d..fbf4343 100644
--- a/tests/testcollection.vala
+++ b/tests/testcollection.vala
@@ -50,6 +50,7 @@ public abstract class CollectionTests : Gee.TestCase {
 		add_test ("[Collection] map", test_map);
 		add_test ("[Collection] scan", test_scan);
 		add_test ("[Collection] filter", test_filter);
+		add_test ("[Collection] chop", test_chop);
 	}
 
 	protected Collection<string> test_collection;
@@ -900,5 +901,26 @@ public abstract class CollectionTests : Gee.TestCase {
 		assert (two);
 		assert (three);
 	}
+
+	public void test_chop () {
+		assert (test_collection.add ("one"));
+		assert (test_collection.add ("two"));
+		assert (test_collection.add ("three"));
+
+		bool one = false;
+		bool two = false;
+		bool three = false;
+
+		var iter = test_collection.iterator().chop (1, 1);
+		assert (!iter.valid);
+		var iter2 = test_collection.iterator();
+
+		assert (iter2.next ());
+		assert (iter2.next ());
+		assert (iter.next ());
+		assert (iter2.get () == iter.get ());
+		assert (!iter.next ());
+		assert (iter2.next ());
+	}
 }
 



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