Add read_only_view to SortedSet
authorMaciej Piechotka <uzytkownik2@gmail.com>
Wed, 7 Oct 2009 22:59:34 +0000 (23:59 +0100)
committerMaciej Piechotka <uzytkownik2@gmail.com>
Mon, 2 May 2011 10:45:25 +0000 (11:45 +0100)
gee/Makefile.am
gee/abstractsortedset.vala [new file with mode: 0644]
gee/readonlysortedset.vala [new file with mode: 0644]
gee/sortedset.vala
gee/treemap.vala
gee/treeset.vala

index 30f6c99..bef9dc4 100644 (file)
@@ -12,6 +12,7 @@ libgee_la_SOURCES = \
        abstractmultiset.vala \
        abstractqueue.vala \
        abstractset.vala \
+       abstractsortedset.vala \
        arraylist.vala \
        bidiriterator.vala \
        bidirmapiterator.vala \
@@ -39,6 +40,7 @@ libgee_la_SOURCES = \
        readonlylist.vala \
        readonlymap.vala \
        readonlyset.vala \
+       readonlysortedset.vala \
        set.vala \
        sortedmap.vala \
        sortedset.vala \
diff --git a/gee/abstractsortedset.vala b/gee/abstractsortedset.vala
new file mode 100644 (file)
index 0000000..7663d72
--- /dev/null
@@ -0,0 +1,103 @@
+/* abstractsortedset.vala
+ *
+ * Copyright (C) 2009-2011  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 SortedSet} interface.
+ *
+ * Contains common code shared by all set implementations.
+ *
+ * @see TreeSet
+ */
+public abstract class Gee.AbstractSortedSet<G> : Gee.AbstractSet<G>, SortedSet<G> {
+       /**
+        * {@inheritDoc}
+        */
+       public abstract G first ();
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract G last ();
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract BidirIterator<G> bidir_iterator ();
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract BidirIterator<G>? iterator_at (G element);
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract G? lower (G element);
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract G? higher (G element);
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract G? floor (G element);
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract G? ceil (G element);
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract SortedSet<G> head_set (G before);
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract SortedSet<G> tail_set (G after);
+
+       /**
+        * {@inheritDoc}
+        */
+       public abstract SortedSet<G> sub_set (G from, G to);
+       
+       private weak SortedSet<G> _read_only_view;
+       
+       /**
+        * {@inheritDoc}
+        */
+       public virtual new SortedSet<G> read_only_view {
+               owned get {
+                       SortedSet<G> instance = _read_only_view;
+                       if (_read_only_view == null) {
+                               instance = new ReadOnlySortedSet<G> (this);
+                               _read_only_view = instance;
+                               instance.add_weak_pointer ((void**) (&_read_only_view));
+                       }
+                       return instance;
+               }
+       }
+}
+
diff --git a/gee/readonlysortedset.vala b/gee/readonlysortedset.vala
new file mode 100644 (file)
index 0000000..54d1786
--- /dev/null
@@ -0,0 +1,152 @@
+/* readonlysortedset.vala
+ *
+ * Copyright (C) 2009  Didier Villevalois, Maciej Piechotka
+ * Copyright (C) 2011  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 SortedSet} collections.
+ *
+ * This class decorates any class which implements the {@link SortedSet} interface
+ * by making it read only. Any method which normally modify data will throw an
+ * error.
+ *
+ * @see SortedSet
+ */
+internal class Gee.ReadOnlySortedSet<G> : ReadOnlySet<G>, SortedSet<G> {
+       /**
+        * Constructs a read-only set that mirrors the content of the specified set.
+        *
+        * @param set the set to decorate.
+        */
+       public ReadOnlySortedSet (SortedSet<G> set) {
+               base (set);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public G first () {
+               return (_collection as SortedSet<G>).first ();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public G last () {
+               return (_collection as SortedSet<G>).last ();
+       }
+
+       /**
+        * {@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) {
+               var iter = (_collection as SortedSet<G>).iterator_at (element);
+               return (iter != null) ? new BidirIterator<G> (iter) : null;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public G? lower (G element) {
+               return (_collection as SortedSet<G>).lower (element);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public G? higher (G element) {
+               return (_collection as SortedSet<G>).higher (element);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public G? floor (G element) {
+               return (_collection as SortedSet<G>).floor (element);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public G? ceil (G element) {
+               return (_collection as SortedSet<G>).ceil (element);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public SortedSet<G> head_set (G before) {
+               return (_collection as SortedSet<G>).head_set (before).read_only_view;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public SortedSet<G> tail_set (G after) {
+               return(_collection as SortedSet<G>).tail_set (after).read_only_view;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public SortedSet<G> sub_set (G from, G to) {
+               return (_collection as SortedSet<G>).sub_set (from, to).read_only_view;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public new SortedSet<G> read_only_view {
+               owned get {
+                       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 a8058c3..318c748 100644 (file)
@@ -1,6 +1,7 @@
 /* sortedset.vala
  *
  * Copyright (C) 2009  Didier Villevalois, Maciej Piechotka
+ * Copyright (C) 2011  Maciej Piechotka
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -126,4 +127,18 @@ public interface Gee.SortedSet<G> : Gee.Set<G> {
         * @return     the corresponding sub-set of this sorted set
         */
        public abstract SortedSet<G> sub_set (G from, G to);
+
+       /**
+        * The read-only view of this set.
+        */
+       public abstract new SortedSet<G> read_only_view { owned get; }
+
+       /**
+        * Returns an immutable empty sorted set.
+        *
+        * @return an immutable empty sorted set
+        */
+       public static SortedSet<G> empty<G> () {
+               return new TreeSet<G> ().read_only_view;
+       }
 }
index d708202..e0828d0 100644 (file)
@@ -961,6 +961,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V>, SortedMap<K,V> {
                public 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> {
@@ -1078,6 +1082,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V>, SortedMap<K,V> {
                        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> {
@@ -1263,6 +1271,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V>, SortedMap<K,V> {
                        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>> {
@@ -1380,6 +1392,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V>, SortedMap<K,V> {
                        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 {
index 6e2af21..e9dbfef 100644 (file)
@@ -1,6 +1,6 @@
 /* treeset.vala
  *
- * Copyright (C) 2009-2010  Maciej Piechotka
+ * Copyright (C) 2009-2011  Maciej Piechotka
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -32,7 +32,7 @@ using GLib;
  *
  * @see HashSet
  */
-public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
+public class Gee.TreeSet<G> : AbstractSortedSet<G> {
        /**
         * {@inheritDoc}
         */
@@ -350,7 +350,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
        /**
         * {@inheritDoc}
         */
-       public BidirIterator<G> bidir_iterator () {
+       public override BidirIterator<G> bidir_iterator () {
                return new Iterator<G> (this);
        }
 
@@ -361,7 +361,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
        /**
         * {@inheritDoc}
         */
-       public G first () {
+       public override G first () {
                assert (_first != null);
                return _first.key;
        }
@@ -369,7 +369,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
        /**
         * {@inheritDoc}
         */
-       public G last () {
+       public override G last () {
                assert (_last != null);
                return _last.key;
        }
@@ -377,21 +377,21 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
        /**
         * {@inheritDoc}
         */
-       public SortedSet<G> head_set (G before) {
+       public override SortedSet<G> head_set (G before) {
                return new SubSet<G>.head (this, before);
        }
 
        /**
         * {@inheritDoc}
         */
-       public SortedSet<G> tail_set (G after) {
+       public override SortedSet<G> tail_set (G after) {
                return new SubSet<G>.tail (this, after);
        }
 
        /**
         * {@inheritDoc}
         */
-       public SortedSet<G> sub_set (G after, G before) {
+       public override SortedSet<G> sub_set (G after, G before) {
                return new SubSet<G> (this, after, before);
        }
 
@@ -413,7 +413,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
        /**
         * {@inheritDoc}
         */
-       public BidirIterator<G>? iterator_at (G item) {
+       public override BidirIterator<G>? iterator_at (G item) {
                weak Node<G>? node = find_node (item);
                return node != null ? new Iterator<G>.pointing (this, node) : null;
        }
@@ -468,28 +468,28 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
        /**
         * {@inheritDoc}
         */
-       public G? lower (G item) {
+       public override G? lower (G item) {
                return lift_null_get (find_lower (item));
        }
 
        /**
         * {@inheritDoc}
         */
-       public G? higher (G item) {
+       public override G? higher (G item) {
                return lift_null_get (find_higher (item));
        }
 
        /**
         * {@inheritDoc}
         */
-       public G? floor (G item) {
+       public override G? floor (G item) {
                return lift_null_get (find_floor (item));
        }
 
        /**
         * {@inheritDoc}
         */
-       public G? ceil (G item) {
+       public override G? ceil (G item) {
                return lift_null_get (find_ceil (item));
        }
 
@@ -888,7 +888,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
                BOUNDED
        }
 
-       private class SubSet<G> : AbstractSet<G>, SortedSet<G> {
+       private class SubSet<G> : AbstractSortedSet<G> {
                public SubSet (TreeSet<G> set, G after, G before) {
                        this.set = set;
                        this.range = new Range<G> (set, after, before);
@@ -952,35 +952,35 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
                        return new SubIterator<G> (set, range);
                }
 
-               public BidirIterator<G> bidir_iterator () {
+               public override BidirIterator<G> bidir_iterator () {
                        return new SubIterator<G> (set, range);
                }
 
-               public G first () {
+               public override G first () {
                        weak Node<G>? _first = range.first ();
                        assert (_first != null);
                        return _first.key;
                }
 
-               public G last () {
+               public override G last () {
                        weak Node<G>? _last = range.last ();
                        assert (_last != null);
                        return _last.key;
                }
 
-               public SortedSet<G> head_set (G before) {
+               public override SortedSet<G> head_set (G before) {
                        return new SubSet<G>.from_range (set, range.cut_tail (before));
                }
 
-               public SortedSet<G> tail_set (G after) {
+               public override SortedSet<G> tail_set (G after) {
                        return new SubSet<G>.from_range (set, range.cut_head (after));
                }
 
-               public SortedSet<G> sub_set (G after, G before) {
+               public override SortedSet<G> sub_set (G after, G before) {
                        return new SubSet<G>.from_range (set, range.cut (after, before));
                }
 
-               public BidirIterator<G>? iterator_at (G item) {
+               public override BidirIterator<G>? iterator_at (G item) {
                        if (!range.in_range (item))
                                return null;
                        weak Node<G>? n = set.find_node (item);
@@ -989,7 +989,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
                        return new SubIterator<G>.pointing (set, range, n);
                }
 
-               public G? lower (G item) {
+               public override G? lower (G item) {
                        var res = range.compare_range (item);
                        if (res > 0)
                                return last ();
@@ -997,7 +997,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
                        return l != null && range.in_range (l) ? l : null;
                }
 
-               public G? higher (G item) {
+               public override G? higher (G item) {
                        var res = range.compare_range (item);
                        if (res < 0)
                                return first ();
@@ -1005,7 +1005,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
                        return h != null && range.in_range (h) ? h : null;
                }
 
-               public G? floor (G item) {
+               public override G? floor (G item) {
                        var res = range.compare_range (item);
                        if (res > 0)
                                return last ();
@@ -1013,7 +1013,7 @@ public class Gee.TreeSet<G> : AbstractSet<G>, SortedSet<G> {
                        return l != null && range.in_range (l) ? l : null;
                }
 
-               public G? ceil (G item) {
+               public override G? ceil (G item) {
                        var res = range.compare_range (item);
                        if (res < 0)
                                return first ();