Split SortedMap/SortedSet into bi-directional and uni-directional parts
authorMaciej Piechotka <uzytkownik2@gmail.com>
Tue, 27 Mar 2012 22:29:05 +0000 (00:29 +0200)
committerMaciej Piechotka <uzytkownik2@gmail.com>
Wed, 28 Mar 2012 00:14:57 +0000 (02:14 +0200)
21 files changed:
gee/Makefile.am
gee/abstractbidirsortedmap.vala [new file with mode: 0644]
gee/abstractbidirsortedset.vala [new file with mode: 0644]
gee/abstractsortedset.vala
gee/bidirsortedmap.vala [new file with mode: 0644]
gee/bidirsortedset.vala [new file with mode: 0644]
gee/readonlybidirsortedmap.vala [new file with mode: 0644]
gee/readonlybidirsortedset.vala [new file with mode: 0644]
gee/readonlysortedmap.vala
gee/readonlysortedset.vala
gee/sortedmap.vala
gee/sortedset.vala
gee/treemap.vala
gee/treeset.vala
tests/Makefile.am
tests/testbidirsortedmap.vala [new file with mode: 0644]
tests/testbidirsortedset.vala [new file with mode: 0644]
tests/testsortedmap.vala
tests/testsortedset.vala
tests/testtreemap.vala
tests/testtreeset.vala

index 1da2b39..be270bf 100644 (file)
@@ -7,6 +7,8 @@ lib_LTLIBRARIES = \
 libgee_0_8_la_SOURCES = \
        assemblyinfo.vala \
        abstractbidirlist.vala \
+       abstractbidirsortedset.vala \
+       abstractbidirsortedmap.vala \
        abstractcollection.vala \
        abstractlist.vala \
        abstractmap.vala \
@@ -22,6 +24,8 @@ libgee_0_8_la_SOURCES = \
        bidirlist.vala \
        bidirlistiterator.vala \
        bidirmapiterator.vala \
+       bidirsortedset.vala \
+       bidirsortedmap.vala \
        collection.vala \
        comparable.vala \
        concurrentlist.vala \
@@ -46,6 +50,8 @@ libgee_0_8_la_SOURCES = \
        priorityqueue.vala \
        queue.vala \
        readonlybidirlist.vala \
+       readonlybidirsortedset.vala \
+       readonlybidirsortedmap.vala \
        readonlycollection.vala \
        readonlylist.vala \
        readonlymap.vala \
diff --git a/gee/abstractbidirsortedmap.vala b/gee/abstractbidirsortedmap.vala
new file mode 100644 (file)
index 0000000..d399d1a
--- /dev/null
@@ -0,0 +1,53 @@
+/* abstractbidirsortedmap.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Maciej Piechotka <uzytkownik2@gmail.com>
+ */
+
+/**
+ * Skeletal implementation of the {@link BidirSortedSet} interface.
+ *
+ * Contains common code shared by all set implementations.
+ *
+ * @see TreeSet
+ */
+public abstract class Gee.AbstractBidirSortedMap<K,V> : Gee.AbstractSortedMap<K,V>, BidirSortedMap<K,V> {
+       /**
+        * {@inheritDoc}
+        */
+       public abstract BidirMapIterator<K,V> bidir_map_iterator ();
+
+       private weak BidirSortedMap<K,V> _read_only_view;
+
+       /**
+        * {@inheritDoc}
+        */
+       public virtual new BidirSortedMap<K,V> read_only_view {
+               owned get {
+                       BidirSortedMap<K,V> instance = _read_only_view;
+                       if (_read_only_view == null) {
+                               instance = new ReadOnlyBidirSortedMap<K,V> (this);
+                               _read_only_view = instance;
+                               instance.add_weak_pointer ((void**) (&_read_only_view));
+                       }
+                       return instance;
+               }
+       }
+}
+
diff --git a/gee/abstractbidirsortedset.vala b/gee/abstractbidirsortedset.vala
new file mode 100644 (file)
index 0000000..5ea426d
--- /dev/null
@@ -0,0 +1,53 @@
+/* abstractbidirsortedset.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Maciej Piechotka <uzytkownik2@gmail.com>
+ */
+
+/**
+ * Skeletal implementation of the {@link BidirSortedSet} interface.
+ *
+ * Contains common code shared by all set implementations.
+ *
+ * @see TreeSet
+ */
+public abstract class Gee.AbstractBidirSortedSet<G> : Gee.AbstractSortedSet<G>, BidirSortedSet<G> {
+       /**
+        * {@inheritDoc}
+        */
+       public abstract BidirIterator<G> bidir_iterator ();
+
+       private weak BidirSortedSet<G> _read_only_view;
+
+       /**
+        * {@inheritDoc}
+        */
+       public virtual new BidirSortedSet<G> read_only_view {
+               owned get {
+                       BidirSortedSet<G> instance = _read_only_view;
+                       if (_read_only_view == null) {
+                               instance = new ReadOnlyBidirSortedSet<G> (this);
+                               _read_only_view = instance;
+                               instance.add_weak_pointer ((void**) (&_read_only_view));
+                       }
+                       return instance;
+               }
+       }
+}
+
index 7663d72..44c3b89 100644 (file)
@@ -41,12 +41,7 @@ public abstract class Gee.AbstractSortedSet<G> : Gee.AbstractSet<G>, SortedSet<G
        /**
         * {@inheritDoc}
         */
-       public abstract BidirIterator<G> bidir_iterator ();
-
-       /**
-        * {@inheritDoc}
-        */
-       public abstract BidirIterator<G>? iterator_at (G element);
+       public abstract Iterator<G>? iterator_at (G element);
 
        /**
         * {@inheritDoc}
@@ -82,9 +77,9 @@ public abstract class Gee.AbstractSortedSet<G> : Gee.AbstractSet<G>, SortedSet<G
         * {@inheritDoc}
         */
        public abstract SortedSet<G> sub_set (G from, G to);
-       
+
        private weak SortedSet<G> _read_only_view;
-       
+
        /**
         * {@inheritDoc}
         */
diff --git a/gee/bidirsortedmap.vala b/gee/bidirsortedmap.vala
new file mode 100644 (file)
index 0000000..67c1e8f
--- /dev/null
@@ -0,0 +1,45 @@
+/* bidirsortedmap.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Maciej Piechotka <uzytkownik2@gmail.com>
+ */
+
+public interface Gee.BidirSortedMap<K,V> : SortedMap<K,V> {
+       /**
+        * Returns a bi-directional iterator for this map.
+        *
+        * @return a bi-directional map iterator
+        */
+       public abstract BidirMapIterator<K,V> bidir_map_iterator ();
+
+       /**
+        * The read-only view of this set.
+        */
+       public abstract new BidirSortedMap<K,V> read_only_view { owned get; }
+
+       /**
+        * Returns an immutable empty sorted set.
+        *
+        * @return an immutable empty sorted set
+        */
+       public static BidirSortedMap<K,V> empty<K,V> () {
+               return new TreeMap<K,V> ().read_only_view;
+       }
+}
+
diff --git a/gee/bidirsortedset.vala b/gee/bidirsortedset.vala
new file mode 100644 (file)
index 0000000..d068b25
--- /dev/null
@@ -0,0 +1,46 @@
+/* sortedset.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Maciej Piechotka <uzytkownik2@gmail.com>
+ */
+
+public interface Gee.BidirSortedSet<G> : SortedSet<G> {
+       /**
+        * Returns a {@link BidirIterator} that can be used for bi-directional
+        * iteration over this sorted set.
+        *
+        * @return a {@link BidirIterator} over this sorted set
+        */
+       public abstract BidirIterator<G> bidir_iterator ();
+
+       /**
+        * The read-only view of this set.
+        */
+       public abstract new BidirSortedSet<G> read_only_view { owned get; }
+
+       /**
+        * Returns an immutable empty sorted set.
+        *
+        * @return an immutable empty sorted set
+        */
+       public static BidirSortedSet<G> empty<G> () {
+               return new TreeSet<G> ().read_only_view;
+       }
+}
+
diff --git a/gee/readonlybidirsortedmap.vala b/gee/readonlybidirsortedmap.vala
new file mode 100644 (file)
index 0000000..95c0327
--- /dev/null
@@ -0,0 +1,71 @@
+/* readonlybidirsortedmap.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Maciej Piechotka <uzytkownik2@gmail.com>
+ */
+
+/**
+ * Read-only view for {@link BidirSortedMap} collections.
+ *
+ * This class decorates any class which implements the {@link BidirSortedMap}
+ * interface by making it read only. Any method which normally modify data will
+ * throw an error.
+ *
+ * @see BidirSortedMap
+ */
+internal class Gee.ReadOnlyBidirSortedMap<K,V> : ReadOnlySortedMap<K,V>, BidirSortedMap<K,V> {
+       /**
+        * Constructs a read-only map that mirrors the content of the specified map.
+        *
+        * @param set the set to decorate.
+        */
+       public ReadOnlyBidirSortedMap (BidirSortedMap<K,V> map) {
+               base (map);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public Gee.BidirMapIterator<K,V> bidir_map_iterator () {
+               return new BidirMapIterator<K,V> ((_map as BidirSortedMap<K,V>).bidir_map_iterator ());
+       }
+
+       protected class BidirMapIterator<K,V> : Gee.ReadOnlyMap.MapIterator<K,V>, Gee.BidirMapIterator<K,V> {
+               public BidirMapIterator (Gee.BidirMapIterator<K,V> iterator) {
+                       base (iterator);
+               }
+
+               public bool first () {
+                       return (_iter as Gee.BidirMapIterator<K,V>).first ();
+               }
+
+               public bool previous () {
+                       return (_iter as Gee.BidirMapIterator<K,V>).previous ();
+               }
+
+               public bool has_previous () {
+                       return (_iter as Gee.BidirMapIterator<K,V>).has_previous ();
+               }
+
+               public bool last () {
+                       return (_iter as Gee.BidirMapIterator<K,V>).last ();
+               }
+       }
+}
+
diff --git a/gee/readonlybidirsortedset.vala b/gee/readonlybidirsortedset.vala
new file mode 100644 (file)
index 0000000..460ebbe
--- /dev/null
@@ -0,0 +1,71 @@
+/* readonlybidirsortedset.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Maciej Piechotka <uzytkownik2@gmail.com>
+ */
+
+/**
+ * Read-only view for {@link BidirSortedSet} collections.
+ *
+ * This class decorates any class which implements the {@link BidirSortedSet}
+ * interface by making it read only. Any method which normally modify data will
+ * throw an error.
+ *
+ * @see BidirSortedSet
+ */
+internal class Gee.ReadOnlyBidirSortedSet<G> : ReadOnlySortedSet<G>, BidirSortedSet<G> {
+       /**
+        * Constructs a read-only set that mirrors the content of the specified set.
+        *
+        * @param set the set to decorate.
+        */
+       public ReadOnlyBidirSortedSet (BidirSortedSet<G> set) {
+               base (set);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public Gee.BidirIterator<G> bidir_iterator () {
+               return new BidirIterator<G> ((_collection as BidirSortedSet<G>).bidir_iterator ());
+       }
+
+       protected class BidirIterator<G> : Gee.ReadOnlyCollection.Iterator<G>, Gee.BidirIterator<G> {
+               public BidirIterator (Gee.BidirIterator<G> iterator) {
+                       base (iterator);
+               }
+
+               public bool first () {
+                       return (_iter as Gee.BidirIterator<G>).first ();
+               }
+
+               public bool previous () {
+                       return (_iter as Gee.BidirIterator<G>).previous ();
+               }
+
+               public bool has_previous () {
+                       return (_iter as Gee.BidirIterator<G>).has_previous ();
+               }
+
+               public bool last () {
+                       return (_iter as Gee.BidirIterator<G>).last ();
+               }
+       }
+}
+
index bf25da9..56d7fb6 100644 (file)
@@ -77,34 +77,5 @@ internal class Gee.ReadOnlySortedMap<K,V> : ReadOnlyMap<K,V>, SortedMap<K,V> {
                        return (_map as SortedMap<K,V>).ascending_entries.read_only_view;
                }
        }
-
-       /**
-        * {@inheritDoc}
-        */
-       public Gee.BidirMapIterator<K,V> bidir_map_iterator () {
-               return new BidirMapIterator<K,V> ((_map as SortedMap<K,V>).bidir_map_iterator ());
-       }
-
-       protected class BidirMapIterator<K,V> : Gee.ReadOnlyMap.MapIterator<K,V>, Gee.BidirMapIterator<K,V> {
-               public BidirMapIterator (Gee.BidirMapIterator<K,V> iterator) {
-                       base (iterator);
-               }
-
-               public bool first () {
-                       return (_iter as Gee.BidirMapIterator<K,V>).first ();
-               }
-
-               public bool previous () {
-                       return (_iter as Gee.BidirMapIterator<K,V>).previous ();
-               }
-
-               public bool has_previous () {
-                       return (_iter as Gee.BidirMapIterator<K,V>).has_previous ();
-               }
-
-               public bool last () {
-                       return (_iter as Gee.BidirMapIterator<K,V>).last ();
-               }
-       }
 }
 
index 54d1786..de60b4c 100644 (file)
@@ -57,16 +57,9 @@ internal class Gee.ReadOnlySortedSet<G> : ReadOnlySet<G>, SortedSet<G> {
        /**
         * {@inheritDoc}
         */
-       public Gee.BidirIterator<G> bidir_iterator () {
-               return new BidirIterator<G> ((_collection as SortedSet<G>).bidir_iterator ());
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public Gee.BidirIterator<G>? iterator_at (G element) {
+       public Gee.Iterator<G>? iterator_at (G element) {
                var iter = (_collection as SortedSet<G>).iterator_at (element);
-               return (iter != null) ? new BidirIterator<G> (iter) : null;
+               return (iter != null) ? new Iterator<G> (iter) : null;
        }
 
        /**
@@ -126,27 +119,5 @@ internal class Gee.ReadOnlySortedSet<G> : ReadOnlySet<G>, SortedSet<G> {
                        return this;
                }
        }
-
-       protected class BidirIterator<G> : Gee.ReadOnlyCollection.Iterator<G>, Gee.BidirIterator<G> {
-               public BidirIterator (Gee.BidirIterator<G> iterator) {
-                       base (iterator);
-               }
-
-               public bool first () {
-                       return (_iter as Gee.BidirIterator<G>).first ();
-               }
-
-               public bool previous () {
-                       return (_iter as Gee.BidirIterator<G>).previous ();
-               }
-
-               public bool has_previous () {
-                       return (_iter as Gee.BidirIterator<G>).has_previous ();
-               }
-
-               public bool last () {
-                       return (_iter as Gee.BidirIterator<G>).last ();
-               }
-       }
 }
 
index 8693a91..ef5904e 100644 (file)
@@ -25,10 +25,12 @@ public interface Gee.SortedMap<K,V> : Gee.Map<K,V> {
         * Returns map containing pairs with key strictly lower the the argument.
         */
        public abstract SortedMap<K,V> head_map (K before);
+
        /**
         * Returns map containing pairs with key equal or larger then the argument.
         */
        public abstract SortedMap<K,V> tail_map (K after);
+
        /**
         * Returns right-open map (i.e. containing all pair which key is strictly
         * lower then the second argument and equal or bigger then the first one).
@@ -36,21 +38,17 @@ public interface Gee.SortedMap<K,V> : Gee.Map<K,V> {
         * Null as one parameter means that it should include all from this side.
         */
        public abstract SortedMap<K,V> sub_map (K before, K after);
+
        /**
         * Returns the keys in ascending order.
         */
        public abstract SortedSet<K> ascending_keys { owned get; }
+
        /**
         * Returns the entries in ascending order.
         */
        public abstract SortedSet<Map.Entry<K,V>> ascending_entries { owned get; }
-       /**
-        * Returns a bi-directional iterator for this map.
-        *
-        * @return a bi-directional map iterator
-        */
-       public abstract BidirMapIterator<K,V> bidir_map_iterator ();
-       
+
        /**
         * The read-only view this map.
         */
index e5d86af..5acd50d 100644 (file)
@@ -40,14 +40,6 @@ public interface Gee.SortedSet<G> : Gee.Set<G> {
        public abstract G last ();
 
        /**
-        * Returns a {@link BidirIterator} that can be used for bi-directional
-        * iteration over this sorted set.
-        *
-        * @return a {@link BidirIterator} over this sorted set
-        */
-       public abstract BidirIterator<G> bidir_iterator ();
-
-       /**
         * Returns a {@link BidirIterator} initialy pointed at the specified
         * element.
         *
@@ -56,7 +48,7 @@ public interface Gee.SortedSet<G> : Gee.Set<G> {
         * @return        a {@link BidirIterator} over this sorted set, or null if
         *                the specified element is not in this set
         */
-       public abstract BidirIterator<G>? iterator_at (G element);
+       public abstract Iterator<G>? iterator_at (G element);
 
        /**
         * Returns the element which is strictly lower than the specified element.
index 508e8a9..8bc869e 100644 (file)
@@ -31,7 +31,7 @@ using GLib;
  *
  * @see HashMap
  */
-public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
+public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> {
        /**
         * {@inheritDoc}
         */
@@ -745,7 +745,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                BOUNDED
        }
 
-       private class SubMap<K,V> : AbstractSortedMap<K,V> {
+       private class SubMap<K,V> : AbstractBidirSortedMap<K,V> {
                public override int size { get { return keys.size; } }
                public override bool is_empty { get { return keys.is_empty; } }
 
@@ -874,7 +874,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                private Range<K,V> range;
        }
 
-       private class KeySet<K,V> : AbstractSet<K>, SortedSet<K> {
+       private class KeySet<K,V> : AbstractBidirSortedSet<K> {
                private TreeMap<K,V> _map;
 
                public KeySet (TreeMap<K,V> map) {
@@ -909,61 +909,57 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return _map.has_key (key);
                }
 
-               public K first () {
+               public override K first () {
                        assert (_map.first != null);
                        return _map.first.key;
                }
 
-               public K last () {
+               public override K last () {
                        assert (_map.last != null);
                        return _map.last.key;
                }
 
-               public BidirIterator<K> bidir_iterator () {
+               public override BidirIterator<K> bidir_iterator () {
                        return new KeyIterator<K,V> (_map);
                }
 
-               public SortedSet<K> head_set (K before) {
+               public override SortedSet<K> head_set (K before) {
                        return new SubKeySet<K,V> (_map, new Range<K,V>.head (_map, before));
                }
 
-               public SortedSet<K> tail_set (K after) {
+               public override SortedSet<K> tail_set (K after) {
                        return new SubKeySet<K,V> (_map, new Range<K,V>.tail (_map, after));
                }
 
-               public SortedSet<K> sub_set (K after, K before) {
+               public override SortedSet<K> sub_set (K after, K before) {
                        return new SubKeySet<K,V> (_map, new Range<K,V> (_map, after, before));
                }
 
-               public BidirIterator<K>? iterator_at (K item) {
+               public override Iterator<K>? iterator_at (K item) {
                        weak Node<K,V>? node = _map.find_node (item);
                        if (node == null)
                                return null;
                        return new KeyIterator<K,V>.pointing (_map, node);
                }
 
-               public K? lower (K item) {
+               public override K? lower (K item) {
                        return _map.lift_null_key (_map.find_lower (item));
                }
 
-               public K? higher (K item) {
+               public override K? higher (K item) {
                        return _map.lift_null_key (_map.find_higher (item));
                }
 
-               public K? floor (K item) {
+               public override K? floor (K item) {
                        return _map.lift_null_key (_map.find_floor (item));
                }
 
-               public K? ceil (K item) {
+               public override K? ceil (K item) {
                        return _map.lift_null_key (_map.find_ceil (item));
                }
-
-               public new SortedSet<K> read_only_view {
-                       owned get { return this; }
-               }
        }
 
-       private class SubKeySet<K,V> : AbstractSet<K>, SortedSet<K> {
+       private class SubKeySet<K,V> : AbstractBidirSortedSet<K> {
                public TreeMap<K,V> map { private set; get; }
                public Range<K,V> range { private set; get; }
 
@@ -1010,35 +1006,35 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return range.in_range(key) && map.has_key (key);
                }
 
-               public BidirIterator<K> bidir_iterator () {
+               public override BidirIterator<K> bidir_iterator () {
                        return new SubKeyIterator<K,V> (map, range);
                }
 
-               public K first () {
+               public override K first () {
                        weak Node<K,V>? _first = range.first ();
                        assert (_first != null);
                        return _first.key;
                }
 
-               public K last () {
+               public override K last () {
                        weak Node<K,V>? _last = range.last ();
                        assert (_last != null);
                        return _last.key;
                }
 
-               public SortedSet<K> head_set (K before) {
+               public override SortedSet<K> head_set (K before) {
                        return new SubKeySet<K,V> (map, range.cut_tail (before));
                }
 
-               public SortedSet<K> tail_set (K after) {
+               public override SortedSet<K> tail_set (K after) {
                        return new SubKeySet<K,V> (map, range.cut_head (after));
                }
 
-               public SortedSet<K> sub_set (K after, K before) {
+               public override SortedSet<K> sub_set (K after, K before) {
                        return new SubKeySet<K,V> (map, range.cut (after, before));
                }
 
-               public BidirIterator<K>? iterator_at (K key) {
+               public override Iterator<K>? iterator_at (K key) {
                        if (!range.in_range (key))
                                return null;
                        weak Node<K,V>? n = map.find_node (key);
@@ -1047,7 +1043,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return new SubKeyIterator<K,V>.pointing (map, range, n);
                }
 
-               public K? lower (K key) {
+               public override K? lower (K key) {
                        var res = range.compare_range (key);
                        if (res > 0)
                                return last ();
@@ -1055,7 +1051,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return l != null && range.in_range (l) ? l : null;
                }
 
-               public K? higher (K key) {
+               public override K? higher (K key) {
                        var res = range.compare_range (key);
                        if (res < 0)
                                return first ();
@@ -1063,7 +1059,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return h != null && range.in_range (h) ? h : null;
                }
 
-               public K? floor (K key) {
+               public override K? floor (K key) {
                        var res = range.compare_range (key);
                        if (res > 0)
                                return last ();
@@ -1071,17 +1067,13 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return l != null && range.in_range (l) ? l : null;
                }
 
-               public K? ceil (K key) {
+               public override K? ceil (K key) {
                        var res = range.compare_range (key);
                        if (res < 0)
                                return first ();
                        var h = map.lift_null_key (map.find_ceil (key));
                        return h != null && range.in_range (h) ? h : null;
                }
-
-               public new SortedSet<K> read_only_view {
-                       owned get { return this; }
-               }
        }
 
        private class ValueCollection<K,V> : AbstractCollection<V> {
@@ -1180,7 +1172,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                }
        }
 
-       private class EntrySet<K,V> : AbstractSet<Map.Entry<K, V>>, SortedSet<Map.Entry<K, V>> {
+       private class EntrySet<K,V> : AbstractBidirSortedSet<Map.Entry<K, V>> {
                private TreeMap<K,V> _map;
 
                public EntrySet (TreeMap<K,V> map) {
@@ -1215,65 +1207,61 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return _map.has (entry.key, entry.value);
                }
 
-               public Map.Entry<K, V>/*?*/ first () {
+               public override Map.Entry<K, V>/*?*/ first () {
                        assert (_map.first != null);
                        return Entry.entry_for<K,V> (_map.first);
                }
 
-               public Map.Entry<K, V>/*?*/ last () {
+               public override Map.Entry<K, V>/*?*/ last () {
                        assert (_map.last != null);
                        return Entry.entry_for<K,V> (_map.last);
                }
 
-               public BidirIterator<Map.Entry<K, V>> bidir_iterator () {
+               public override BidirIterator<Map.Entry<K, V>> bidir_iterator () {
                        return new EntryIterator<K,V> (_map);
                }
 
-               public SortedSet<Map.Entry<K, V>> head_set (Map.Entry<K, V> before) {
+               public override SortedSet<Map.Entry<K, V>> head_set (Map.Entry<K, V> before) {
                        return new SubEntrySet<K,V> (_map, new Range<K,V>.head (_map, before.key));
                }
 
-               public SortedSet<Map.Entry<K, V>> tail_set (Map.Entry<K, V> after) {
+               public override SortedSet<Map.Entry<K, V>> tail_set (Map.Entry<K, V> after) {
                        return new SubEntrySet<K,V> (_map, new Range<K,V>.tail (_map, after.key));
                }
 
-               public SortedSet<K> sub_set (Map.Entry<K, V> after, Map.Entry<K, V> before) {
+               public override SortedSet<K> sub_set (Map.Entry<K, V> after, Map.Entry<K, V> before) {
                        return new SubEntrySet<K,V> (_map, new Range<K,V> (_map, after.key, before.key));
                }
 
-               public BidirIterator<Map.Entry<K, V>>? iterator_at (Map.Entry<K, V> item) {
+               public override Iterator<Map.Entry<K, V>>? iterator_at (Map.Entry<K, V> item) {
                        weak Node<K,V>? node = _map.find_node (item.key);
                        if (node == null || !_map.value_equal_func (node.value, item.value))
                                return null;
                        return new EntryIterator<K,V>.pointing (_map, node);
                }
 
-               public Map.Entry<K, V>/*?*/ lower (Map.Entry<K, V> item) {
+               public override Map.Entry<K, V>/*?*/ lower (Map.Entry<K, V> item) {
                        weak Node<K,V>? l = _map.find_lower (item.key);
                        return l != null ? Entry.entry_for<K,V> (l) : null;
                }
 
-               public Map.Entry<K, V>/*?*/ higher (Map.Entry<K, V> item) {
+               public override Map.Entry<K, V>/*?*/ higher (Map.Entry<K, V> item) {
                        weak Node<K,V>? l = _map.find_higher (item.key);
                        return l != null ? Entry.entry_for<K,V> (l) : null;
                }
 
-               public Map.Entry<K, V>/*?*/ floor (Map.Entry<K, V> item) {
+               public override Map.Entry<K, V>/*?*/ floor (Map.Entry<K, V> item) {
                        weak Node<K,V>? l = _map.find_floor (item.key);
                        return l != null ? Entry.entry_for<K,V> (l) : null;
                }
 
-               public Map.Entry<K, V>/*?*/ ceil (Map.Entry<K, V> item) {
+               public override Map.Entry<K, V>/*?*/ ceil (Map.Entry<K, V> item) {
                        weak Node<K,V>? l = _map.find_ceil (item.key);
                        return l != null ? Entry.entry_for<K,V> (l) : null;
                }
-
-               public new SortedSet<Map.Entry<K, V>> read_only_view {
-                       owned get { return this; }
-               }
        }
 
-       private class SubEntrySet<K,V> : AbstractSet<Map.Entry<K,V>>, SortedSet<Map.Entry<K,V>> {
+       private class SubEntrySet<K,V> : AbstractBidirSortedSet<Map.Entry<K,V>> {
                public TreeMap<K,V> map { private set; get; }
                public Range<K,V> range { private set; get; }
 
@@ -1320,35 +1308,35 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return range.in_range(entry.key) && map.has (entry.key, entry.value);
                }
 
-               public BidirIterator<K> bidir_iterator () {
+               public override BidirIterator<K> bidir_iterator () {
                        return new SubEntryIterator<K,V> (map, range);
                }
 
-               public Map.Entry<K,V> first () {
+               public override Map.Entry<K,V> first () {
                        weak Node<K,V>? _first = range.first ();
                        assert (_first != null);
                        return Entry.entry_for<K,V> (_first);
                }
 
-               public Map.Entry<K,V> last () {
+               public override Map.Entry<K,V> last () {
                        weak Node<K,V>? _last = range.last ();
                        assert (_last != null);
                        return Entry.entry_for<K,V> (_last);
                }
 
-               public SortedSet<K> head_set (Map.Entry<K,V> before) {
+               public override SortedSet<K> head_set (Map.Entry<K,V> before) {
                        return new SubEntrySet<K,V> (map, range.cut_tail (before.key));
                }
 
-               public SortedSet<K> tail_set (Map.Entry<K,V> after) {
+               public override SortedSet<K> tail_set (Map.Entry<K,V> after) {
                        return new SubEntrySet<K,V> (map, range.cut_head (after.key));
                }
 
-               public SortedSet<K> sub_set (Map.Entry<K,V> after, Map.Entry<K,V> before) {
+               public override SortedSet<K> sub_set (Map.Entry<K,V> after, Map.Entry<K,V> before) {
                        return new SubEntrySet<K,V> (map, range.cut (after.key, before.key));
                }
 
-               public BidirIterator<Map.Entry<K,V>>? iterator_at (Map.Entry<K,V> entry) {
+               public override Iterator<Map.Entry<K,V>>? iterator_at (Map.Entry<K,V> entry) {
                        if (!range.in_range (entry.key))
                                return null;
                        weak Node<K,V>? n = map.find_node (entry.key);
@@ -1357,7 +1345,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return new SubEntryIterator<K,V>.pointing (map, range, n);
                }
 
-               public Map.Entry<K,V>/*?*/ lower (Map.Entry<K,V> entry) {
+               public override Map.Entry<K,V>/*?*/ lower (Map.Entry<K,V> entry) {
                        var res = range.compare_range (entry.key);
                        if (res > 0)
                                return last ();
@@ -1365,7 +1353,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return l != null && range.in_range (l.key) ? Entry.entry_for<K,V> (l) : null;
                }
 
-               public Map.Entry<K,V>/*?*/ higher (Map.Entry<K,V> entry) {
+               public override Map.Entry<K,V>/*?*/ higher (Map.Entry<K,V> entry) {
                        var res = range.compare_range (entry.key);
                        if (res < 0)
                                return first ();
@@ -1373,7 +1361,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return h != null && range.in_range (h.key) ? Entry.entry_for<K,V> (h) : null;
                }
 
-               public Map.Entry<K,V>/*?*/ floor (Map.Entry<K,V> entry) {
+               public override Map.Entry<K,V>/*?*/ floor (Map.Entry<K,V> entry) {
                        var res = range.compare_range (entry.key);
                        if (res > 0)
                                return last ();
@@ -1381,27 +1369,23 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        return l != null && range.in_range (l.key) ? Entry.entry_for<K,V> (l) : null;
                }
 
-               public Map.Entry<K,V>/*?*/ ceil (Map.Entry<K,V> entry) {
+               public override Map.Entry<K,V>/*?*/ ceil (Map.Entry<K,V> entry) {
                        var res = range.compare_range (entry.key);
                        if (res < 0)
                                return first ();
                        weak Node<K,V>? h = map.find_ceil (entry.key);
                        return h != null && range.in_range (h.key) ? Entry.entry_for<K,V> (h) : null;
                }
-
-               public new SortedSet<Map.Entry<K, V>> read_only_view {
-                       owned get { return this; }
-               }
        }
 
        private class NodeIterator<K, V> : Object {
                protected TreeMap<K,V> _map;
-               
+
                // concurrent modification protection
                protected int stamp;
-               
+
                protected bool started = false;
-               
+
                internal weak Node<K, V>? current;
                protected weak Node<K, V>? _next;
                protected weak Node<K, V>? _prev;
@@ -1507,13 +1491,13 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        _map.stamp++;
                        assert (stamp == _map.stamp);
                }
-               
+
                public virtual bool read_only {
                        get {
                                return true;
                        }
                }
-               
+
                public bool valid {
                        get {
                                return current != null;
@@ -1901,7 +1885,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        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> {
                public MapIterator (TreeMap<K,V> map) {
                        base (map);
@@ -1937,7 +1921,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractSortedMap<K,V> {
                        }
                }
        }
-       
+
        private class SubMapIterator<K,V> : SubNodeIterator<K,V>, Gee.MapIterator<K,V>, BidirMapIterator<K,V> {
                public SubMapIterator (TreeMap<K,V> map, Range<K,V> range) {
                        base (map, range);
index 342bc53..8387b1c 100644 (file)
@@ -32,7 +32,7 @@ using GLib;
  *
  * @see HashSet
  */
-public class Gee.TreeSet<G> : AbstractSortedSet<G> {
+public class Gee.TreeSet<G> : AbstractBidirSortedSet<G> {
        /**
         * {@inheritDoc}
         */
@@ -410,7 +410,7 @@ public class Gee.TreeSet<G> : AbstractSortedSet<G> {
        /**
         * {@inheritDoc}
         */
-       public override BidirIterator<G>? iterator_at (G item) {
+       public override Gee.Iterator<G>? iterator_at (G item) {
                weak Node<G>? node = find_node (item);
                return node != null ? new Iterator<G>.pointing (this, node) : null;
        }
@@ -901,7 +901,7 @@ public class Gee.TreeSet<G> : AbstractSortedSet<G> {
                BOUNDED
        }
 
-       private class SubSet<G> : AbstractSortedSet<G> {
+       private class SubSet<G> : AbstractBidirSortedSet<G> {
                public SubSet (TreeSet<G> set, G after, G before) {
                        this.set = set;
                        this.range = new Range<G> (set, after, before);
@@ -993,7 +993,7 @@ public class Gee.TreeSet<G> : AbstractSortedSet<G> {
                        return new SubSet<G>.from_range (set, range.cut (after, before));
                }
 
-               public override BidirIterator<G>? iterator_at (G item) {
+               public override Gee.Iterator<G>? iterator_at (G item) {
                        if (!range.in_range (item))
                                return null;
                        weak Node<G>? n = set.find_node (item);
index 37489ae..105292e 100644 (file)
@@ -8,6 +8,8 @@ tests_SOURCES = \
        testarraylist.vala \
        testarrayqueue.vala \
        testbidirlist.vala \
+       testbidirsortedset.vala \
+       testbidirsortedmap.vala \
        testcase.vala \
        testcollection.vala \
        testconcurrentlist.vala \
diff --git a/tests/testbidirsortedmap.vala b/tests/testbidirsortedmap.vala
new file mode 100644 (file)
index 0000000..385d715
--- /dev/null
@@ -0,0 +1,430 @@
+/* testbidirsortedmap.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Maciej Piechotka <uzytkownik2@gmail.com>
+ */
+using GLib;
+using Gee;
+
+public abstract class BidirSortedMapTests : SortedMapTests {
+       public BidirSortedMapTests(string name) {
+               base (name);
+               add_test ("[SortedMap] bi-directional iterators can go backward",
+                         test_bidir_iterator_can_go_backward);
+               add_test ("[SortedSet] bi-directional iterators can to end",
+                         test_bidir_iterator_last);
+               get_suite ().add_suite (new BidirSubMapTests (this, SortedMapTests.SubMapTests.Type.HEAD).get_suite ());
+               get_suite ().add_suite (new BidirSubMapTests (this, SortedMapTests.SubMapTests.Type.TAIL).get_suite ());
+               get_suite ().add_suite (new BidirSubMapTests (this, SortedMapTests.SubMapTests.Type.SUB).get_suite ());
+               get_suite ().add_suite (new BidirSubMapTests (this, SortedMapTests.SubMapTests.Type.EMPTY).get_suite ());
+       }
+
+       public void test_bidir_iterator_can_go_backward () {
+               var test_sorted_map = test_map as BidirSortedMap<string,string>;
+               var keys = (test_sorted_map.ascending_keys) as BidirSortedSet<string>;
+               var entries = (test_sorted_map.ascending_entries) as BidirSortedSet<Map.Entry<string,string>>;
+
+               var keys_iterator = keys.bidir_iterator ();
+               var entries_iterator = entries.bidir_iterator ();
+               var map_iterator = test_sorted_map.bidir_map_iterator ();
+
+               assert (!keys_iterator.has_previous ());
+               assert (!entries_iterator.has_previous ());
+
+               assert (!map_iterator.has_previous ());
+               assert (!keys_iterator.previous ());
+               assert (!entries_iterator.has_previous ());
+
+               assert (!map_iterator.previous ());
+
+               test_sorted_map.set ("one", "one");
+               test_sorted_map.set ("two", "two");
+               test_sorted_map.set ("three", "three");
+               test_sorted_map.set ("four", "four");
+               test_sorted_map.set ("five", "five");
+               test_sorted_map.set ("six", "six");
+
+               keys_iterator = keys.bidir_iterator ();
+               entries_iterator = entries.bidir_iterator ();
+               map_iterator = test_sorted_map.bidir_map_iterator ();
+
+               assert (keys_iterator.next ());
+               assert (entries_iterator.next ());
+
+               assert (map_iterator.next ());
+               assert (keys_iterator.get () == "five");
+               assert_entry (entries_iterator.get (), "five", "five");
+
+               assert (map_iterator.get_key () == "five");
+               assert (map_iterator.get_value () == "five");
+
+               assert (!keys_iterator.has_previous ());
+               assert (!entries_iterator.has_previous ());
+
+               assert (!map_iterator.has_previous ());
+               assert (keys_iterator.next ());
+               assert (entries_iterator.next ());
+
+               assert (map_iterator.next ());
+               assert (keys_iterator.get () == "four");
+               assert_entry (entries_iterator.get (), "four", "four");
+
+               assert (map_iterator.get_key () == "four");
+               assert (map_iterator.get_value () == "four");
+
+               assert (keys_iterator.has_previous ());
+               assert (entries_iterator.has_previous ());
+
+               assert (map_iterator.has_previous ());
+               assert (keys_iterator.next ());
+               assert (entries_iterator.next ());
+
+               assert (map_iterator.next ());
+               assert (keys_iterator.get () == "one");
+               assert_entry (entries_iterator.get (), "one", "one");
+
+               assert (map_iterator.get_key () == "one");
+               assert (map_iterator.get_value () == "one");
+
+               assert (keys_iterator.has_previous ());
+               assert (entries_iterator.has_previous ());
+
+               assert (map_iterator.has_previous ());
+               assert (keys_iterator.next ());
+               assert (entries_iterator.next ());
+
+               assert (map_iterator.next ());
+               assert (keys_iterator.get () == "six");
+               assert_entry (entries_iterator.get (), "six", "six");
+
+               assert (map_iterator.get_key () == "six");
+               assert (map_iterator.get_value () == "six");
+               assert (keys_iterator.has_previous ());
+
+               assert (entries_iterator.has_previous ());
+               assert (map_iterator.has_previous ());
+               assert (keys_iterator.next ());
+
+               assert (entries_iterator.next ());
+               assert (map_iterator.next ());
+               assert (keys_iterator.get () == "three");
+
+               assert_entry (entries_iterator.get (), "three", "three");
+               assert (map_iterator.get_key () == "three");
+               assert (map_iterator.get_value () == "three");
+
+               assert (keys_iterator.has_previous ());
+               assert (entries_iterator.has_previous ());
+               assert (map_iterator.has_previous ());
+
+               assert (keys_iterator.next ());
+               assert (entries_iterator.next ());
+               assert (map_iterator.next ());
+
+               assert (keys_iterator.get () == "two");
+               assert_entry (entries_iterator.get (), "two", "two");
+               assert (map_iterator.get_key () == "two");
+               assert (map_iterator.get_value () == "two");
+
+               assert (keys_iterator.has_previous ());
+               assert (entries_iterator.has_previous ());
+               assert (map_iterator.has_previous ());
+
+               assert (!keys_iterator.next ());
+               assert (!entries_iterator.next ());
+               assert (!map_iterator.next ());
+
+               assert (keys_iterator.previous ());
+               assert (entries_iterator.previous ());
+               assert (map_iterator.previous ());
+
+               assert (keys_iterator.get () == "three");
+               assert_entry (entries_iterator.get (), "three", "three");
+               assert (map_iterator.get_key () == "three");
+               assert (map_iterator.get_value () == "three");
+
+               assert (keys_iterator.previous ());
+               assert (entries_iterator.previous ());
+               assert (map_iterator.previous ());
+
+               assert (keys_iterator.get () == "six");
+               assert_entry (entries_iterator.get (), "six", "six");
+               assert (map_iterator.get_key () == "six");
+               assert (map_iterator.get_value () == "six");
+
+               assert (keys_iterator.previous ());
+               assert (entries_iterator.previous ());
+               assert (map_iterator.previous ());
+
+               assert (keys_iterator.get () == "one");
+               assert_entry (entries_iterator.get (), "one", "one");
+               assert (map_iterator.get_key () == "one");
+               assert (map_iterator.get_value () == "one");
+
+               assert (keys_iterator.previous ());
+               assert (entries_iterator.previous ());
+               assert (map_iterator.previous ());
+
+               assert (keys_iterator.get () == "four");
+               assert_entry (entries_iterator.get (), "four", "four");
+               assert (map_iterator.get_key () == "four");
+               assert (map_iterator.get_value () == "four");
+
+               assert (keys_iterator.previous ());
+               assert (entries_iterator.previous ());
+               assert (map_iterator.previous ());
+
+               assert (keys_iterator.get () == "five");
+               assert_entry (entries_iterator.get (), "five", "five");
+               assert (map_iterator.get_key () == "five");
+               assert (map_iterator.get_value () == "five");
+
+               assert (!keys_iterator.previous ());
+               assert (!entries_iterator.previous ());
+               assert (!map_iterator.previous ());
+
+               assert (keys_iterator.get () == "five");
+               assert_entry (entries_iterator.get (), "five", "five");
+               assert (map_iterator.get_key () == "five");
+               assert (map_iterator.get_value () == "five");
+       }
+
+       public void test_bidir_iterator_last () {
+               var test_sorted_map = test_map as BidirSortedMap<string,string>;
+               var keys = (test_sorted_map.ascending_keys) as BidirSortedSet<string>;
+               var entries = (test_sorted_map.ascending_entries) as BidirSortedSet<Map.Entry<string,string>>;
+
+               var keys_iterator = keys.bidir_iterator ();
+               var entries_iterator = entries.bidir_iterator ();
+
+               assert (!keys_iterator.last ());
+               assert (!entries_iterator.last ());
+
+               test_sorted_map.set ("one", "one");
+               test_sorted_map.set ("two", "two");
+               test_sorted_map.set ("three", "three");
+               test_sorted_map.set ("four", "four");
+               test_sorted_map.set ("five", "five");
+               test_sorted_map.set ("six", "six");
+
+               keys_iterator = keys.bidir_iterator ();
+               entries_iterator = entries.bidir_iterator ();
+
+               assert (keys_iterator.last ());
+               assert (entries_iterator.last ());
+
+               assert (keys_iterator.get () == "two");
+               assert_entry (entries_iterator.get (), "two", "two");
+       }
+
+
+       public class BidirSubMapTests : Gee.TestCase {
+               private BidirSortedMap<string,string> master;
+               private BidirSortedMap<string,string> submap;
+               private BidirSortedMapTests test;
+               private SortedMapTests.SubMapTests.Type type;
+
+               public BidirSubMapTests (BidirSortedMapTests test, SortedMapTests.SubMapTests.Type type) {
+                       base ("%s Subset".printf (type.to_string ()));
+                       this.test = test;
+                       this.type = type;
+                       add_test ("[BidirSortedSet] bi-directional iterator", test_bidir_iterators);
+               }
+
+               public override void set_up () {
+                       test.set_up ();
+                       master = test.test_map as BidirSortedMap<string,string>;
+                       switch (type) {
+                       case SortedMapTests.SubMapTests.Type.HEAD:
+                               submap = master.head_map ("one") as BidirSortedMap<string,string>; break;
+                       case SortedMapTests.SubMapTests.Type.TAIL:
+                               submap = master.tail_map ("six") as BidirSortedMap<string,string>; break;
+                       case SortedMapTests.SubMapTests.Type.SUB:
+                               submap = master.sub_map ("four", "three") as BidirSortedMap<string,string>; break;
+                       case SortedMapTests.SubMapTests.Type.EMPTY:
+                               submap = master.sub_map ("three", "four") as BidirSortedMap<string,string>; break;
+                       default:
+                               assert_not_reached ();
+                       }
+               }
+
+               public override void tear_down () {
+                       test.tear_down ();
+               }
+
+               protected void set_default_values (out string[] contains = null, out string[] not_contains = null) {
+                       master.set ("one", "one");
+                       master.set ("two", "two");
+                       master.set ("three", "three");
+                       master.set ("four", "four");
+                       master.set ("five", "five");
+                       master.set ("six", "six");
+                       switch (type) {
+                       case SortedMapTests.SubMapTests.Type.HEAD:
+                               contains = {"five", "four"};
+                               not_contains = {"one", "two", "three", "six"};
+                               break;
+                       case SortedMapTests.SubMapTests.Type.TAIL:
+                               contains = {"six", "three", "two"};
+                               not_contains = {"one", "four", "five"};
+                               break;
+                       case SortedMapTests.SubMapTests.Type.SUB:
+                               contains = {"four", "one", "six"};
+                               not_contains = {"two", "three", "five"};
+                               break;
+                       case SortedMapTests.SubMapTests.Type.EMPTY:
+                               contains = {};
+                               not_contains = {"one", "two", "three", "four", "five", "six"};
+                               break;
+                       default:
+                               assert_not_reached ();
+                       }
+               }
+
+               public void test_bidir_iterators () {
+                       string[] contains, not_contains;
+
+                       var _map_iter = submap.bidir_map_iterator ();
+
+                       assert (!_map_iter.has_next ());
+                       assert (!_map_iter.next ());
+                       assert (!_map_iter.has_previous ());
+                       assert (!_map_iter.previous ());
+                       
+                       set_default_values (out contains, out not_contains);
+                       
+                       var i = 0;
+                       _map_iter = submap.bidir_map_iterator ();
+                       while (_map_iter.next ()) {
+                               assert (_map_iter.get_key () == contains[i]);
+                               assert (_map_iter.get_value () == contains[i]);
+                               i++;
+                       }
+                       assert (i == contains.length);
+                       
+                       i = 0;
+                       foreach (var k in submap.keys)
+                               assert (k == contains[i++]);
+                       assert (i == contains.length);
+                       
+                       i = 0;
+                       foreach (var e in submap.entries) {
+                               MapTests.assert_entry (e, contains[i], contains[i]);
+                               i++;
+                       }
+                       assert (i == contains.length);
+                       
+                       var keys_iter = ((submap.ascending_keys) as BidirSortedSet<string>).bidir_iterator ();
+                       var entries_iter = ((submap.ascending_entries) as BidirSortedSet<Map.Entry<string,string>>).bidir_iterator ();
+                       var map_iter = submap.bidir_map_iterator ();
+                       if (type != SortedMapTests.SubMapTests.Type.EMPTY) {
+                               assert (map_iter.last ());
+                               assert (map_iter.get_key () == contains[contains.length - 1]);
+                               assert (map_iter.get_value () == contains[contains.length - 1]);
+
+                               map_iter = submap.bidir_map_iterator ();
+                               assert (map_iter.next ());
+
+                               assert (map_iter.get_key () == contains[0]);
+                               assert (map_iter.get_value () == contains[0]);
+
+                               assert (map_iter.has_next ());
+                               assert (map_iter.next ());
+                               assert (map_iter.get_key () == contains[1]);
+                               assert (map_iter.get_value () == contains[1]);
+
+                               assert (map_iter.has_previous ());
+                               map_iter.unset ();
+                               assert (map_iter.has_previous ());
+                               if (type != SortedMapTests.SubMapTests.Type.HEAD)
+                                       assert (map_iter.has_next ());
+                               else
+                                       assert (!map_iter.has_next ());
+                               assert (map_iter.previous ());
+                               assert (map_iter.get_key () == contains[0]);
+                               assert (map_iter.get_value () == contains[0]);
+                               
+                               // Repeat for keys
+                               master.clear ();
+                               set_default_values (out contains, out not_contains);
+                               
+                               assert (keys_iter.last ());
+                               assert (keys_iter.get () == contains[contains.length - 1]);
+                               assert (keys_iter.first ());
+
+                               assert (keys_iter.get () == contains[0]);
+                               assert (keys_iter.has_next ());
+                               assert (keys_iter.next ());
+                               assert (keys_iter.get () == contains[1]);
+                               assert (keys_iter.has_previous ());
+                               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
+                                                      TestTrapFlags.SILENCE_STDERR)) {
+                                       keys_iter.remove ();
+                                       Posix.exit (0);
+                               }
+                               assert (keys_iter.has_previous ());
+                               if (type != SortedMapTests.SubMapTests.Type.HEAD)
+                                       assert (keys_iter.has_next ());
+                               else
+                                       assert (!keys_iter.has_next ());
+                               assert (keys_iter.previous ());
+                               assert (keys_iter.get () == contains[0]);
+                               
+                               // Repeat for entries
+                               master.clear ();
+                               set_default_values (out contains, out not_contains);
+
+                               assert (entries_iter.last ());
+                               MapTests.assert_entry (entries_iter.get (), contains[contains.length - 1], contains[contains.length - 1]);
+                               assert (entries_iter.first ());
+
+                               MapTests.assert_entry (entries_iter.get (), contains[0], contains[0]);
+                               assert (entries_iter.has_next ());
+                               assert (entries_iter.next ());
+                               MapTests.assert_entry (entries_iter.get (), contains[1], contains[1]);
+                               assert (entries_iter.has_previous ());
+                               entries_iter.remove ();
+                               assert (entries_iter.has_previous ());
+                               if (type != SortedMapTests.SubMapTests.Type.HEAD)
+                                       assert (entries_iter.has_next ());
+                               else
+                                       assert (!entries_iter.has_next ());
+                               assert (entries_iter.previous ());
+                               MapTests.assert_entry (entries_iter.get (), contains[0], contains[0]);
+                       } else {
+                               assert (!keys_iter.first ());
+                               assert (!keys_iter.last ());
+                               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
+                                                      TestTrapFlags.SILENCE_STDERR)) {
+                                       keys_iter.remove ();
+                                       Posix.exit (0);
+                               }
+                               Test.trap_assert_failed ();
+                               assert (!entries_iter.first ());
+                               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
+                                                      TestTrapFlags.SILENCE_STDERR)) {
+                                       entries_iter.remove ();
+                                       Posix.exit (0);
+                               }
+                               Test.trap_assert_failed ();
+                       }
+               }
+       }
+}
+
diff --git a/tests/testbidirsortedset.vala b/tests/testbidirsortedset.vala
new file mode 100644 (file)
index 0000000..df5da60
--- /dev/null
@@ -0,0 +1,275 @@
+/* testbidirsortedset.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Maciej Piechotka <uzytkownik2@gmail.com>
+ */
+using GLib;
+using Gee;
+
+public abstract class BidirSortedSetTests : SortedSetTests {
+       public BidirSortedSetTests(string name) {
+               base (name);
+               add_test ("[SortedSet] bi-directional iterators can go backward",
+                         test_bidir_iterator_can_go_backward);
+               add_test ("[SortedSet] bi-directional iterators are mutable",
+                         test_mutable_bidir_iterator);
+               add_test ("[SortedSet] bi-directional iterators can to beginning",
+                         test_bidir_iterator_first);
+               add_test ("[SortedSet] bi-directional iterators can to end",
+                         test_bidir_iterator_last);
+               get_suite ().add_suite (new BidirSubSetTests (this, SortedSetTests.SubSetTests.Type.HEAD).get_suite ());
+               get_suite ().add_suite (new BidirSubSetTests (this, SortedSetTests.SubSetTests.Type.TAIL).get_suite ());
+               get_suite ().add_suite (new BidirSubSetTests (this, SortedSetTests.SubSetTests.Type.SUB).get_suite ());
+               get_suite ().add_suite (new BidirSubSetTests (this, SortedSetTests.SubSetTests.Type.EMPTY).get_suite ());
+       }
+
+       public void test_bidir_iterator_can_go_backward () {
+               var test_set = test_collection as BidirSortedSet<string>;
+
+               var iterator = test_set.bidir_iterator ();
+               assert (!iterator.has_previous ());
+
+               assert (test_set.add ("one"));
+               assert (test_set.add ("two"));
+               assert (test_set.add ("three"));
+               assert (test_set.add ("four"));
+               assert (test_set.add ("five"));
+               assert (test_set.add ("six"));
+
+               iterator = test_set.bidir_iterator ();
+               assert (iterator.next ());
+               assert (iterator.get () == "five");
+               assert (!iterator.has_previous ());
+               assert (iterator.next ());
+               assert (iterator.get () == "four");
+               assert (iterator.has_previous ());
+               assert (iterator.next ());
+               assert (iterator.get () == "one");
+               assert (iterator.has_previous ());
+               assert (iterator.next ());
+               assert (iterator.get () == "six");
+               assert (iterator.has_previous ());
+               assert (iterator.next ());
+               assert (iterator.get () == "three");
+               assert (iterator.has_previous ());
+               assert (iterator.next ());
+               assert (iterator.get () == "two");
+               assert (iterator.has_previous ());
+               assert (!iterator.next ());
+               assert (iterator.previous ());
+               assert (iterator.get () == "three");
+               assert (iterator.previous ());
+               assert (iterator.get () == "six");
+               assert (iterator.previous ());
+               assert (iterator.get () == "one");
+               assert (iterator.previous ());
+               assert (iterator.get () == "four");
+               assert (iterator.previous ());
+               assert (iterator.get () == "five");
+               assert (!iterator.previous ());
+               assert (iterator.get () == "five");
+       }
+
+       public void test_bidir_iterator_first () {
+               var test_set = test_collection as BidirSortedSet<string>;
+
+               var iterator = test_set.bidir_iterator ();
+
+               assert (!iterator.first ());
+
+               assert (test_set.add ("one"));
+               assert (test_set.add ("two"));
+               assert (test_set.add ("three"));
+               assert (test_set.add ("four"));
+               assert (test_set.add ("five"));
+               assert (test_set.add ("six"));
+
+               iterator = test_set.bidir_iterator ();
+               assert (iterator.last ());
+               assert (iterator.get () == "two");
+               assert (iterator.first ());
+               assert (iterator.get () == "five");
+       }
+
+       public void test_bidir_iterator_last () {
+               var test_set = test_collection as BidirSortedSet<string>;
+
+               var iterator = test_set.bidir_iterator ();
+
+               assert (!iterator.last ());
+
+               assert (test_set.add ("one"));
+               assert (test_set.add ("two"));
+               assert (test_set.add ("three"));
+               assert (test_set.add ("four"));
+               assert (test_set.add ("five"));
+               assert (test_set.add ("six"));
+
+               iterator = test_set.bidir_iterator ();
+               assert (iterator.last ());
+               assert (iterator.get () == "two");
+       }
+
+       public void test_mutable_bidir_iterator () {
+               var test_set = test_collection as BidirSortedSet<string>;
+
+               var iterator = test_set.bidir_iterator ();
+               assert (!iterator.has_previous ());
+
+               assert (test_set.add ("one"));
+               assert (test_set.add ("two"));
+               assert (test_set.add ("three"));
+               assert (test_set.add ("four"));
+               assert (test_set.add ("five"));
+               assert (test_set.add ("six"));
+
+               iterator = test_set.bidir_iterator ();
+
+               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
+                                      TestTrapFlags.SILENCE_STDERR)) {
+                       iterator.remove ();
+                       Posix.exit (0);
+               }
+               Test.trap_assert_failed ();
+
+               assert (iterator.next ());
+               assert (iterator.get () == "five");
+               iterator.remove ();
+               assert (!test_set.contains ("five"));
+               assert (iterator.has_next ());
+               assert (!iterator.has_previous ());
+               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
+                                      TestTrapFlags.SILENCE_STDERR)) {
+                       iterator.get ();
+                       Posix.exit (0);
+               }
+               assert (!iterator.previous ());
+
+               assert (iterator.next ());
+               assert (iterator.get () == "four");
+               assert (iterator.next ());
+               assert (iterator.get () == "one");
+               iterator.remove ();
+               assert (!test_set.contains ("one"));
+               assert (iterator.has_next ());
+               assert (iterator.has_previous ());
+               assert (iterator.previous ());
+               assert (iterator.get () == "four");
+       }
+
+       public class BidirSubSetTests : Gee.TestCase {
+               private BidirSortedSet<string> master;
+               private BidirSortedSet<string> subset;
+               private BidirSortedSetTests test;
+               private SortedSetTests.SubSetTests.Type type;
+
+               public BidirSubSetTests(BidirSortedSetTests test, SortedSetTests.SubSetTests.Type type) {
+                       base ("%s Subset".printf (type.to_string ()));
+                       this.test = test;
+                       this.type = type;
+                       add_test ("[BidirSortedSet] bi-directional iterator", test_bidir_iterator);
+               }
+
+               public override void set_up () {
+                       test.set_up ();
+                       master = test.test_collection as BidirSortedSet<string>;
+                       switch (type) {
+                       case SortedSetTests.SubSetTests.Type.HEAD:
+                               subset = master.head_set ("one") as BidirSortedSet<string>; break;
+                       case SortedSetTests.SubSetTests.Type.TAIL:
+                               subset = master.tail_set ("six") as BidirSortedSet<string>; break;
+                       case SortedSetTests.SubSetTests.Type.SUB:
+                               subset = master.sub_set ("four", "three") as BidirSortedSet<string>; break;
+                       case SortedSetTests.SubSetTests.Type.EMPTY:
+                               subset = master.sub_set ("three", "four") as BidirSortedSet<string>; break;
+                       default:
+                               assert_not_reached ();
+                       }
+               }
+
+               public override void tear_down () {
+                       test.tear_down ();
+               }
+
+               public void test_bidir_iterator () {
+                       assert (master.add ("one"));
+                       assert (master.add ("two"));
+                       assert (master.add ("three"));
+                       assert (master.add ("four"));
+                       assert (master.add ("five"));
+                       assert (master.add ("six"));
+                       assert (master.size == 6);
+
+                       string[] contains;
+                       switch (type) {
+                       case SortedSetTests.SubSetTests.Type.HEAD:
+                               contains = {"five", "four"};
+                               break;
+                       case SortedSetTests.SubSetTests.Type.TAIL:
+                               contains = {"six", "three", "two"};
+                               break;
+                       case SortedSetTests.SubSetTests.Type.SUB:
+                               contains = {"four", "one", "six"};
+                               break;
+                       case SortedSetTests.SubSetTests.Type.EMPTY:
+                               contains = {};
+                               break;
+                       default:
+                               assert_not_reached ();
+                       }
+
+                       uint i = 0;
+                       foreach (var e in subset) {
+                               assert (e == contains[i++]);
+                       }
+                       assert (i == contains.length);
+
+
+                       var iter = subset.bidir_iterator ();
+                       if (type != SortedSetTests.SubSetTests.Type.EMPTY) {
+                               assert (iter.last ());
+                               assert (iter.get () == contains[contains.length - 1]);
+                               assert (iter.first ());
+
+                               assert (iter.get () == contains[0]);
+                               assert (iter.has_next ());
+                               assert (iter.next ());
+                               assert (iter.get () == contains[1]);
+                               assert (iter.has_previous ());
+                               iter.remove ();
+                               assert (iter.has_previous ());
+                               if (type != SortedSetTests.SubSetTests.Type.HEAD)
+                                       assert (iter.has_next ());
+                               else
+                                       assert (!iter.has_next ());
+                               assert (iter.previous ());
+                               assert (iter.get () == contains[0]);
+                       } else {
+                               assert (!iter.first ());
+                               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
+                                                      TestTrapFlags.SILENCE_STDERR)) {
+                                       iter.remove ();
+                                       Posix.exit (0);
+                               }
+                               Test.trap_assert_failed ();
+                       }
+               }
+       }
+}
+
index 6fcc440..abfbfc8 100644 (file)
@@ -31,14 +31,10 @@ public abstract class Gee.SortedMapTests : MapTests {
                add_test ("[SortedMap] higher", test_higher);
                add_test ("[SortedMap] floor", test_floor);
                add_test ("[SortedMap] ceil", test_ceil);
-               add_test ("[SortedMap] bi-directional iterators can go backward",
-                         test_bidir_iterator_can_go_backward);
-               add_test ("[SortedSet] bi-directional iterators can to end",
-                         test_bidir_iterator_last);
-               get_suite ().add_suite (new SubMap (this, SubMap.Type.HEAD).get_suite ());
-               get_suite ().add_suite (new SubMap (this, SubMap.Type.TAIL).get_suite ());
-               get_suite ().add_suite (new SubMap (this, SubMap.Type.SUB).get_suite ());
-               get_suite ().add_suite (new SubMap (this, SubMap.Type.EMPTY).get_suite ());
+               get_suite ().add_suite (new SubMapTests (this, SubMapTests.Type.HEAD).get_suite ());
+               get_suite ().add_suite (new SubMapTests (this, SubMapTests.Type.TAIL).get_suite ());
+               get_suite ().add_suite (new SubMapTests (this, SubMapTests.Type.SUB).get_suite ());
+               get_suite ().add_suite (new SubMapTests (this, SubMapTests.Type.EMPTY).get_suite ());
        }
 
        public void test_key_ordering () {
@@ -126,7 +122,7 @@ public abstract class Gee.SortedMapTests : MapTests {
                assert (keys.first () == "eight");
                /*assert_entry (entries.first (), "eight", "eight");*/
        }
-       
+
        public void test_last () {
                var test_sorted_map = test_map as SortedMap<string,string>;
                var keys = test_sorted_map.ascending_keys;
@@ -386,205 +382,7 @@ public abstract class Gee.SortedMapTests : MapTests {
                assert_entry (entries.ceil (entry_for ("s", "six")), "six", "six");
        }
 
-       public void test_bidir_iterator_can_go_backward () {
-               var test_sorted_map = test_map as SortedMap<string,string>;
-               var keys = test_sorted_map.ascending_keys;
-               var entries = test_sorted_map.ascending_entries;
-
-               var keys_iterator = keys.bidir_iterator ();
-               var entries_iterator = entries.bidir_iterator ();
-               var map_iterator = test_sorted_map.bidir_map_iterator ();
-
-               assert (!keys_iterator.has_previous ());
-               assert (!entries_iterator.has_previous ());
-
-               assert (!map_iterator.has_previous ());
-               assert (!keys_iterator.previous ());
-               assert (!entries_iterator.has_previous ());
-
-               assert (!map_iterator.previous ());
-
-               test_sorted_map.set ("one", "one");
-               test_sorted_map.set ("two", "two");
-               test_sorted_map.set ("three", "three");
-               test_sorted_map.set ("four", "four");
-               test_sorted_map.set ("five", "five");
-               test_sorted_map.set ("six", "six");
-
-               keys_iterator = keys.bidir_iterator ();
-               entries_iterator = entries.bidir_iterator ();
-               map_iterator = test_sorted_map.bidir_map_iterator ();
-
-               assert (keys_iterator.next ());
-               assert (entries_iterator.next ());
-
-               assert (map_iterator.next ());
-               assert (keys_iterator.get () == "five");
-               assert_entry (entries_iterator.get (), "five", "five");
-
-               assert (map_iterator.get_key () == "five");
-               assert (map_iterator.get_value () == "five");
-
-               assert (!keys_iterator.has_previous ());
-               assert (!entries_iterator.has_previous ());
-
-               assert (!map_iterator.has_previous ());
-               assert (keys_iterator.next ());
-               assert (entries_iterator.next ());
-
-               assert (map_iterator.next ());
-               assert (keys_iterator.get () == "four");
-               assert_entry (entries_iterator.get (), "four", "four");
-
-               assert (map_iterator.get_key () == "four");
-               assert (map_iterator.get_value () == "four");
-
-               assert (keys_iterator.has_previous ());
-               assert (entries_iterator.has_previous ());
-
-               assert (map_iterator.has_previous ());
-               assert (keys_iterator.next ());
-               assert (entries_iterator.next ());
-
-               assert (map_iterator.next ());
-               assert (keys_iterator.get () == "one");
-               assert_entry (entries_iterator.get (), "one", "one");
-
-               assert (map_iterator.get_key () == "one");
-               assert (map_iterator.get_value () == "one");
-
-               assert (keys_iterator.has_previous ());
-               assert (entries_iterator.has_previous ());
-
-               assert (map_iterator.has_previous ());
-               assert (keys_iterator.next ());
-               assert (entries_iterator.next ());
-
-               assert (map_iterator.next ());
-               assert (keys_iterator.get () == "six");
-               assert_entry (entries_iterator.get (), "six", "six");
-
-               assert (map_iterator.get_key () == "six");
-               assert (map_iterator.get_value () == "six");
-               assert (keys_iterator.has_previous ());
-
-               assert (entries_iterator.has_previous ());
-               assert (map_iterator.has_previous ());
-               assert (keys_iterator.next ());
-
-               assert (entries_iterator.next ());
-               assert (map_iterator.next ());
-               assert (keys_iterator.get () == "three");
-
-               assert_entry (entries_iterator.get (), "three", "three");
-               assert (map_iterator.get_key () == "three");
-               assert (map_iterator.get_value () == "three");
-
-               assert (keys_iterator.has_previous ());
-               assert (entries_iterator.has_previous ());
-               assert (map_iterator.has_previous ());
-
-               assert (keys_iterator.next ());
-               assert (entries_iterator.next ());
-               assert (map_iterator.next ());
-
-               assert (keys_iterator.get () == "two");
-               assert_entry (entries_iterator.get (), "two", "two");
-               assert (map_iterator.get_key () == "two");
-               assert (map_iterator.get_value () == "two");
-
-               assert (keys_iterator.has_previous ());
-               assert (entries_iterator.has_previous ());
-               assert (map_iterator.has_previous ());
-
-               assert (!keys_iterator.next ());
-               assert (!entries_iterator.next ());
-               assert (!map_iterator.next ());
-
-               assert (keys_iterator.previous ());
-               assert (entries_iterator.previous ());
-               assert (map_iterator.previous ());
-
-               assert (keys_iterator.get () == "three");
-               assert_entry (entries_iterator.get (), "three", "three");
-               assert (map_iterator.get_key () == "three");
-               assert (map_iterator.get_value () == "three");
-
-               assert (keys_iterator.previous ());
-               assert (entries_iterator.previous ());
-               assert (map_iterator.previous ());
-
-               assert (keys_iterator.get () == "six");
-               assert_entry (entries_iterator.get (), "six", "six");
-               assert (map_iterator.get_key () == "six");
-               assert (map_iterator.get_value () == "six");
-
-               assert (keys_iterator.previous ());
-               assert (entries_iterator.previous ());
-               assert (map_iterator.previous ());
-
-               assert (keys_iterator.get () == "one");
-               assert_entry (entries_iterator.get (), "one", "one");
-               assert (map_iterator.get_key () == "one");
-               assert (map_iterator.get_value () == "one");
-
-               assert (keys_iterator.previous ());
-               assert (entries_iterator.previous ());
-               assert (map_iterator.previous ());
-
-               assert (keys_iterator.get () == "four");
-               assert_entry (entries_iterator.get (), "four", "four");
-               assert (map_iterator.get_key () == "four");
-               assert (map_iterator.get_value () == "four");
-
-               assert (keys_iterator.previous ());
-               assert (entries_iterator.previous ());
-               assert (map_iterator.previous ());
-
-               assert (keys_iterator.get () == "five");
-               assert_entry (entries_iterator.get (), "five", "five");
-               assert (map_iterator.get_key () == "five");
-               assert (map_iterator.get_value () == "five");
-
-               assert (!keys_iterator.previous ());
-               assert (!entries_iterator.previous ());
-               assert (!map_iterator.previous ());
-
-               assert (keys_iterator.get () == "five");
-               assert_entry (entries_iterator.get (), "five", "five");
-               assert (map_iterator.get_key () == "five");
-               assert (map_iterator.get_value () == "five");
-       }
-
-       public void test_bidir_iterator_last () {
-               var test_sorted_map = test_map as SortedMap<string,string>;
-               var keys = test_sorted_map.ascending_keys;
-               var entries = test_sorted_map.ascending_entries;
-
-               var keys_iterator = keys.bidir_iterator ();
-               var entries_iterator = entries.bidir_iterator ();
-
-               assert (!keys_iterator.last ());
-               assert (!entries_iterator.last ());
-
-               test_sorted_map.set ("one", "one");
-               test_sorted_map.set ("two", "two");
-               test_sorted_map.set ("three", "three");
-               test_sorted_map.set ("four", "four");
-               test_sorted_map.set ("five", "five");
-               test_sorted_map.set ("six", "six");
-
-               keys_iterator = keys.bidir_iterator ();
-               entries_iterator = entries.bidir_iterator ();
-
-               assert (keys_iterator.last ());
-               assert (entries_iterator.last ());
-
-               assert (keys_iterator.get () == "two");
-               assert_entry (entries_iterator.get (), "two", "two");
-       }
-
-       public class SubMap : Gee.TestCase {
+       public class SubMapTests : Gee.TestCase {
                private SortedMap<string,string> master;
                private SortedMap<string,string> submap;
                private SortedMapTests test;
@@ -605,7 +403,7 @@ public abstract class Gee.SortedMapTests : MapTests {
                }
                private Type type;
                
-               public SubMap (SortedMapTests test, Type type) {
+               public SubMapTests (SortedMapTests test, Type type) {
                        base ("%s Submap".printf (type.to_string ()));
                        this.test = test;
                        this.type = type;
@@ -881,45 +679,36 @@ public abstract class Gee.SortedMapTests : MapTests {
                public void test_iterators () {
                        string[] contains, not_contains;
 
-                       var _map_iter = submap.bidir_map_iterator ();
+                       var _map_iter = submap.map_iterator ();
 
                        assert (!_map_iter.has_next ());
                        assert (!_map_iter.next ());
-                       assert (!_map_iter.has_previous ());
-                       assert (!_map_iter.previous ());
-                       
+
                        set_default_values (out contains, out not_contains);
-                       
+
                        var i = 0;
-                       _map_iter = submap.bidir_map_iterator ();
+                       _map_iter = submap.map_iterator ();
                        while (_map_iter.next ()) {
                                assert (_map_iter.get_key () == contains[i]);
                                assert (_map_iter.get_value () == contains[i]);
                                i++;
                        }
                        assert (i == contains.length);
-                       
+
                        i = 0;
                        foreach (var k in submap.keys)
                                assert (k == contains[i++]);
                        assert (i == contains.length);
-                       
+
                        i = 0;
                        foreach (var e in submap.entries) {
                                MapTests.assert_entry (e, contains[i], contains[i]);
                                i++;
                        }
                        assert (i == contains.length);
-                       
-                       var keys_iter = submap.ascending_keys.bidir_iterator ();
-                       var entries_iter = submap.ascending_entries.bidir_iterator ();
-                       var map_iter = submap.bidir_map_iterator ();
-                       if (type != Type.EMPTY) {
-                               assert (map_iter.last ());
-                               assert (map_iter.get_key () == contains[contains.length - 1]);
-                               assert (map_iter.get_value () == contains[contains.length - 1]);
 
-                               map_iter = submap.bidir_map_iterator ();
+                       if (type != Type.EMPTY) {
+                               var map_iter = submap.map_iterator ();
                                assert (map_iter.next ());
 
                                assert (map_iter.get_key () == contains[0]);
@@ -930,80 +719,39 @@ public abstract class Gee.SortedMapTests : MapTests {
                                assert (map_iter.get_key () == contains[1]);
                                assert (map_iter.get_value () == contains[1]);
 
-                               assert (map_iter.has_previous ());
-                               map_iter.unset ();
-                               assert (map_iter.has_previous ());
-                               if (type != Type.HEAD)
-                                       assert (map_iter.has_next ());
-                               else
-                                       assert (!map_iter.has_next ());
-                               assert (map_iter.previous ());
-                               assert (map_iter.get_key () == contains[0]);
-                               assert (map_iter.get_value () == contains[0]);
-                               
                                // Repeat for keys
                                master.clear ();
                                set_default_values (out contains, out not_contains);
-                               
-                               assert (keys_iter.last ());
-                               assert (keys_iter.get () == contains[contains.length - 1]);
-                               assert (keys_iter.first ());
+                               var keys_iter = submap.ascending_keys.iterator ();
+
+                               assert (keys_iter.has_next ());
+                               assert (keys_iter.next ());
 
                                assert (keys_iter.get () == contains[0]);
                                assert (keys_iter.has_next ());
                                assert (keys_iter.next ());
                                assert (keys_iter.get () == contains[1]);
-                               assert (keys_iter.has_previous ());
-                               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
-                                                      TestTrapFlags.SILENCE_STDERR)) {
-                                       keys_iter.remove ();
-                                       Posix.exit (0);
-                               }
-                               assert (keys_iter.has_previous ());
-                               if (type != Type.HEAD)
-                                       assert (keys_iter.has_next ());
-                               else
-                                       assert (!keys_iter.has_next ());
-                               assert (keys_iter.previous ());
-                               assert (keys_iter.get () == contains[0]);
                                
                                // Repeat for entries
                                master.clear ();
                                set_default_values (out contains, out not_contains);
+                               var entries_iter = submap.ascending_entries.iterator ();
 
-                               assert (entries_iter.last ());
-                               MapTests.assert_entry (entries_iter.get (), contains[contains.length - 1], contains[contains.length - 1]);
-                               assert (entries_iter.first ());
+                               assert (entries_iter.has_next ());
+                               assert (entries_iter.next ());
 
                                MapTests.assert_entry (entries_iter.get (), contains[0], contains[0]);
                                assert (entries_iter.has_next ());
                                assert (entries_iter.next ());
                                MapTests.assert_entry (entries_iter.get (), contains[1], contains[1]);
-                               assert (entries_iter.has_previous ());
-                               entries_iter.remove ();
-                               assert (entries_iter.has_previous ());
-                               if (type != Type.HEAD)
-                                       assert (entries_iter.has_next ());
-                               else
-                                       assert (!entries_iter.has_next ());
-                               assert (entries_iter.previous ());
-                               MapTests.assert_entry (entries_iter.get (), contains[0], contains[0]);
                        } else {
-                               assert (!keys_iter.first ());
-                               assert (!keys_iter.last ());
+                               var keys_iter = submap.ascending_keys.iterator ();
                                if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
                                                       TestTrapFlags.SILENCE_STDERR)) {
                                        keys_iter.remove ();
                                        Posix.exit (0);
                                }
                                Test.trap_assert_failed ();
-                               assert (!entries_iter.first ());
-                               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
-                                                      TestTrapFlags.SILENCE_STDERR)) {
-                                       entries_iter.remove ();
-                                       Posix.exit (0);
-                               }
-                               Test.trap_assert_failed ();
                        }
                }
                
index 5371d7c..fdd6e44 100644 (file)
@@ -24,7 +24,6 @@ using GLib;
 using Gee;
 
 public abstract class SortedSetTests : SetTests {
-
        public SortedSetTests (string name) {
                base (name);
                add_test ("[SortedSet] first", test_first);
@@ -35,18 +34,10 @@ public abstract class SortedSetTests : SetTests {
                add_test ("[SortedSet] higher", test_higher);
                add_test ("[SortedSet] floor", test_floor);
                add_test ("[SortedSet] ceil", test_ceil);
-               add_test ("[SortedSet] bi-directional iterators can go backward",
-                         test_bidir_iterator_can_go_backward);
-               add_test ("[SortedSet] bi-directional iterators are mutable",
-                         test_mutable_bidir_iterator);
-               add_test ("[SortedSet] bi-directional iterators can to beginning",
-                         test_bidir_iterator_first);
-               add_test ("[SortedSet] bi-directional iterators can to end",
-                         test_bidir_iterator_last);
-               get_suite ().add_suite (new SubSet (this, SubSet.Type.HEAD).get_suite ());
-               get_suite ().add_suite (new SubSet (this, SubSet.Type.TAIL).get_suite ());
-               get_suite ().add_suite (new SubSet (this, SubSet.Type.SUB).get_suite ());
-               get_suite ().add_suite (new SubSet (this, SubSet.Type.EMPTY).get_suite ());
+               get_suite ().add_suite (new SubSetTests (this, SubSetTests.Type.HEAD).get_suite ());
+               get_suite ().add_suite (new SubSetTests (this, SubSetTests.Type.TAIL).get_suite ());
+               get_suite ().add_suite (new SubSetTests (this, SubSetTests.Type.SUB).get_suite ());
+               get_suite ().add_suite (new SubSetTests (this, SubSetTests.Type.EMPTY).get_suite ());
        }
 
        public void test_ordering () {
@@ -255,141 +246,7 @@ public abstract class SortedSetTests : SetTests {
                assert (test_set.ceil ("s") == "six");
        }
 
-       public void test_bidir_iterator_can_go_backward () {
-               var test_set = test_collection as SortedSet<string>;
-
-               var iterator = test_set.bidir_iterator ();
-               assert (!iterator.has_previous ());
-
-               assert (test_set.add ("one"));
-               assert (test_set.add ("two"));
-               assert (test_set.add ("three"));
-               assert (test_set.add ("four"));
-               assert (test_set.add ("five"));
-               assert (test_set.add ("six"));
-
-               iterator = test_set.bidir_iterator ();
-               assert (iterator.next ());
-               assert (iterator.get () == "five");
-               assert (!iterator.has_previous ());
-               assert (iterator.next ());
-               assert (iterator.get () == "four");
-               assert (iterator.has_previous ());
-               assert (iterator.next ());
-               assert (iterator.get () == "one");
-               assert (iterator.has_previous ());
-               assert (iterator.next ());
-               assert (iterator.get () == "six");
-               assert (iterator.has_previous ());
-               assert (iterator.next ());
-               assert (iterator.get () == "three");
-               assert (iterator.has_previous ());
-               assert (iterator.next ());
-               assert (iterator.get () == "two");
-               assert (iterator.has_previous ());
-               assert (!iterator.next ());
-               assert (iterator.previous ());
-               assert (iterator.get () == "three");
-               assert (iterator.previous ());
-               assert (iterator.get () == "six");
-               assert (iterator.previous ());
-               assert (iterator.get () == "one");
-               assert (iterator.previous ());
-               assert (iterator.get () == "four");
-               assert (iterator.previous ());
-               assert (iterator.get () == "five");
-               assert (!iterator.previous ());
-               assert (iterator.get () == "five");
-       }
-
-       public void test_bidir_iterator_first () {
-               var test_set = test_collection as SortedSet<string>;
-
-               var iterator = test_set.bidir_iterator ();
-
-               assert (!iterator.first ());
-
-               assert (test_set.add ("one"));
-               assert (test_set.add ("two"));
-               assert (test_set.add ("three"));
-               assert (test_set.add ("four"));
-               assert (test_set.add ("five"));
-               assert (test_set.add ("six"));
-
-               iterator = test_set.bidir_iterator ();
-               assert (iterator.last ());
-               assert (iterator.get () == "two");
-               assert (iterator.first ());
-               assert (iterator.get () == "five");
-       }
-
-       public void test_bidir_iterator_last () {
-               var test_set = test_collection as SortedSet<string>;
-
-               var iterator = test_set.bidir_iterator ();
-
-               assert (!iterator.last ());
-
-               assert (test_set.add ("one"));
-               assert (test_set.add ("two"));
-               assert (test_set.add ("three"));
-               assert (test_set.add ("four"));
-               assert (test_set.add ("five"));
-               assert (test_set.add ("six"));
-
-               iterator = test_set.bidir_iterator ();
-               assert (iterator.last ());
-               assert (iterator.get () == "two");
-       }
-
-       public void test_mutable_bidir_iterator () {
-               var test_set = test_collection as SortedSet<string>;
-
-               var iterator = test_set.bidir_iterator ();
-               assert (!iterator.has_previous ());
-
-               assert (test_set.add ("one"));
-               assert (test_set.add ("two"));
-               assert (test_set.add ("three"));
-               assert (test_set.add ("four"));
-               assert (test_set.add ("five"));
-               assert (test_set.add ("six"));
-
-               iterator = test_set.bidir_iterator ();
-
-               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
-                                      TestTrapFlags.SILENCE_STDERR)) {
-                       iterator.remove ();
-                       Posix.exit (0);
-               }
-               Test.trap_assert_failed ();
-
-               assert (iterator.next ());
-               assert (iterator.get () == "five");
-               iterator.remove ();
-               assert (!test_set.contains ("five"));
-               assert (iterator.has_next ());
-               assert (!iterator.has_previous ());
-               if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
-                                      TestTrapFlags.SILENCE_STDERR)) {
-                       iterator.get ();
-                       Posix.exit (0);
-               }
-               assert (!iterator.previous ());
-
-               assert (iterator.next ());
-               assert (iterator.get () == "four");
-               assert (iterator.next ());
-               assert (iterator.get () == "one");
-               iterator.remove ();
-               assert (!test_set.contains ("one"));
-               assert (iterator.has_next ());
-               assert (iterator.has_previous ());
-               assert (iterator.previous ());
-               assert (iterator.get () == "four");
-       }
-
-       public class SubSet : Gee.TestCase {
+       protected class SubSetTests : Gee.TestCase {
                private SortedSet<string> master;
                private SortedSet<string> subset;
                private SortedSetTests test;
@@ -410,7 +267,7 @@ public abstract class SortedSetTests : SetTests {
                }
                private Type type;
 
-               public SubSet (SortedSetTests test, Type type) {
+               public SubSetTests (SortedSetTests test, Type type) {
                        base ("%s Subset".printf (type.to_string ()));
                        this.test = test;
                        this.type = type;
@@ -644,27 +501,15 @@ public abstract class SortedSetTests : SetTests {
                        assert (i == contains.length);
 
 
-                       var iter = subset.bidir_iterator ();
+                       var iter = subset.iterator ();
                        if (type != Type.EMPTY) {
-                               assert (iter.last ());
-                               assert (iter.get () == contains[contains.length - 1]);
-                               assert (iter.first ());
-
+                               assert (iter.has_next ());
+                               assert (iter.next ());
                                assert (iter.get () == contains[0]);
                                assert (iter.has_next ());
                                assert (iter.next ());
                                assert (iter.get () == contains[1]);
-                               assert (iter.has_previous ());
-                               iter.remove ();
-                               assert (iter.has_previous ());
-                               if (type != Type.HEAD)
-                                       assert (iter.has_next ());
-                               else
-                                       assert (!iter.has_next ());
-                               assert (iter.previous ());
-                               assert (iter.get () == contains[0]);
                        } else {
-                               assert (!iter.first ());
                                if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT |
                                                       TestTrapFlags.SILENCE_STDERR)) {
                                        iter.remove ();
index 6cb7857..6babece 100644 (file)
@@ -23,7 +23,7 @@
 
 using Gee;
 
-public class TreeMapTests : SortedMapTests {
+public class TreeMapTests : BidirSortedMapTests {
 
        public TreeMapTests () {
                base ("TreeMap");
index 0a28d7e..e407945 100644 (file)
@@ -23,7 +23,7 @@
 
 using Gee;
 
-public class TreeSetTests : SortedSetTests {
+public class TreeSetTests : BidirSortedSetTests {
 
        public TreeSetTests () {
                base ("TreeSet");