From: Tomaž Vajngerl Date: Sun, 26 Jul 2009 10:33:49 +0000 (+0200) Subject: Add List.first|last|insert_all methods and AbstractList implementations X-Git-Tag: LIBGEE_0_3_0~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d74a1a126c947026898e7e7446e3ef8b9637a16c;p=platform%2Fupstream%2Flibgee.git Add List.first|last|insert_all methods and AbstractList implementations Fixes bug 589894. --- diff --git a/gee/Makefile.am b/gee/Makefile.am index d46b5ed..9008f23 100644 --- a/gee/Makefile.am +++ b/gee/Makefile.am @@ -14,6 +14,7 @@ lib_LTLIBRARIES = \ libgee_la_VALASOURCES = \ abstractcollection.vala \ + abstractlist.vala \ arraylist.vala \ collection.vala \ functions.vala \ diff --git a/gee/abstractlist.vala b/gee/abstractlist.vala new file mode 100644 index 0000000..5a4b919 --- /dev/null +++ b/gee/abstractlist.vala @@ -0,0 +1,55 @@ +/* abstractlist.vala + * + * Copyright (C) 2007 Jürg Billeter + * Copyright (C) 2009 Didier Villevalois + * + * 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: + * Didier 'Ptitjes' Villevalois + */ + +/** + * Serves as the base class for implementing list classes. + */ +public abstract class Gee.AbstractList : Gee.AbstractCollection, List { + + public abstract new G? get (int index); + + public abstract new void set (int index, G item); + + public abstract int index_of (G item); + + public abstract void insert (int index, G item); + + public abstract void remove_at (int index); + + public abstract List? slice (int start, int stop); + + public virtual G? first () { + return get (0); + } + + public virtual G? last () { + return get (size - 1); + } + + public virtual void insert_all (int index, Collection collection) { + foreach (G item in collection) { + insert(index, item); + index++; + } + } +} diff --git a/gee/arraylist.vala b/gee/arraylist.vala index 467e8d0..9d8f10b 100644 --- a/gee/arraylist.vala +++ b/gee/arraylist.vala @@ -27,7 +27,7 @@ using GLib; /** * Arrays of arbitrary elements which grow automatically as elements are added. */ -public class Gee.ArrayList : AbstractCollection, List { +public class Gee.ArrayList : AbstractList { public override int size { get { return _size; } } @@ -52,7 +52,7 @@ public class Gee.ArrayList : AbstractCollection, List { return (index_of (item) != -1); } - public int index_of (G item) { + public override int index_of (G item) { for (int index = 0; index < _size; index++) { if (equal_func (_items[index], item)) { return index; @@ -61,14 +61,14 @@ public class Gee.ArrayList : AbstractCollection, List { return -1; } - public new G? get (int index) { + public override G? get (int index) { assert (index >= 0); assert (index < _size); return _items[index]; } - public new void set (int index, G item) { + public override void set (int index, G item) { assert (index >= 0); assert (index < _size); @@ -84,7 +84,7 @@ public class Gee.ArrayList : AbstractCollection, List { return true; } - public void insert (int index, G item) { + public override void insert (int index, G item) { assert (index >= 0); assert (index <= _size); @@ -106,7 +106,7 @@ public class Gee.ArrayList : AbstractCollection, List { return false; } - public void remove_at (int index) { + public override void remove_at (int index) { assert (index >= 0); assert (index < _size); @@ -125,7 +125,7 @@ public class Gee.ArrayList : AbstractCollection, List { _stamp++; } - public List? slice (int start, int stop) { + public override List? slice (int start, int stop) { return_val_if_fail (start <= stop, null); return_val_if_fail (start >= 0, null); return_val_if_fail (stop <= _size, null); diff --git a/gee/linkedlist.vala b/gee/linkedlist.vala index 220510c..9e54ac4 100644 --- a/gee/linkedlist.vala +++ b/gee/linkedlist.vala @@ -27,7 +27,7 @@ /** * A Gee.List implementation, using a doubly-linked list. */ -public class Gee.LinkedList : AbstractCollection, List { +public class Gee.LinkedList : AbstractList { private int _size = 0; private int _stamp = 0; private Node? _head = null; @@ -87,7 +87,7 @@ public class Gee.LinkedList : AbstractCollection, List { } // List - public new G? get (int index) { + public override G? get (int index) { assert (index >= 0); assert (index < this._size); @@ -99,7 +99,7 @@ public class Gee.LinkedList : AbstractCollection, List { } } - public new void set (int index, G item) { + public override void set (int index, G item) { assert (index >= 0); assert (index < this._size); @@ -108,7 +108,7 @@ public class Gee.LinkedList : AbstractCollection, List { n.data = item; } - public int index_of (G item) { + public override int index_of (G item) { int result = -1; int idx = 0; foreach (G node_item in this) { @@ -122,7 +122,7 @@ public class Gee.LinkedList : AbstractCollection, List { return result; } - public void insert (int index, G item) { + public override void insert (int index, G item) { assert (index >= 0); assert (index <= this._size); @@ -152,7 +152,7 @@ public class Gee.LinkedList : AbstractCollection, List { } } - public void remove_at (int index) { + public override void remove_at (int index) { assert (index >= 0); assert (index < this._size); @@ -161,7 +161,7 @@ public class Gee.LinkedList : AbstractCollection, List { this._remove_node (n); } - public List? slice (int start, int stop) { + public override List? slice (int start, int stop) { return_val_if_fail (start <= stop, null); return_val_if_fail (start >= 0, null); return_val_if_fail (stop <= this._size, null); diff --git a/gee/list.vala b/gee/list.vala index 451e149..479cf4c 100644 --- a/gee/list.vala +++ b/gee/list.vala @@ -73,5 +73,28 @@ public interface Gee.List : Collection { * @return A list containing a slice of this list */ public abstract List? slice (int start, int stop); + + /** + * Returns the first item of the list or null if list is empty. + * + * @return first item in the list + */ + public abstract G? first (); + + /** + * Returns the last item of the list or null if list is empty. + * + * @return last item in the list + */ + public abstract G? last (); + + /** + * Inserts items into this list for the input collection at the + * specified position. + * + * @param index zero-based index of the items to be inserted + * @param collection collection of items to be inserted + */ + public abstract void insert_all (int index, Collection collection); } diff --git a/gee/readonlylist.vala b/gee/readonlylist.vala index eb5bab4..0fc1b55 100644 --- a/gee/readonlylist.vala +++ b/gee/readonlylist.vala @@ -127,6 +127,26 @@ public class Gee.ReadOnlyList : Object, Iterable, Collection, List { assert_not_reached (); } + public G? first () { + if (_list == null) { + return null; + } + + return _list.first (); + } + + public G? last () { + if (_list == null) { + return null; + } + + return _list.last (); + } + + public void insert_all (int index, Collection collection) { + assert_not_reached (); + } + public G[] to_array() { return _list.to_array (); } diff --git a/tests/testarraylist.vala b/tests/testarraylist.vala index e842df1..0c79dba 100644 --- a/tests/testarraylist.vala +++ b/tests/testarraylist.vala @@ -34,6 +34,9 @@ public class ArrayListTests : CollectionTests { add_test("insert", test_arraylist_insert); add_test("remove_at", test_arraylist_remove_at); add_test("index_of", test_arraylist_index_of); + add_test ("first", test_arraylist_first); + add_test ("last", test_arraylist_last); + add_test ("insert_all", test_arraylist_insert_all); // Methods of Collection interface add_test("add", test_arraylist_add); @@ -931,6 +934,204 @@ public class ArrayListTests : CollectionTests { arraylist1.clear (); arraylist2.clear (); } + + void test_arraylist_first () { + var arraylistOfString = new ArrayList (); + + // Check first for empty list + if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT | TestTrapFlags.SILENCE_STDERR)) { + arraylistOfString.first (); + return; + } + Test.trap_assert_failed (); + + // Check first for list with one element + arraylistOfString.add ("1"); + assert (arraylistOfString.first () == "1"); + assert (arraylistOfString.first () == arraylistOfString.get (0)); + + // Check first for for list with multiple element + arraylistOfString.add ("2"); + arraylistOfString.add ("3"); + assert (arraylistOfString.first () == "1"); + assert (arraylistOfString.first () == arraylistOfString.get (0)); + + // Check first if list is cleared and empty again + arraylistOfString.clear (); + + if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT | TestTrapFlags.SILENCE_STDERR)) { + arraylistOfString.first (); + return; + } + Test.trap_assert_failed (); + } + + void test_arraylist_last () { + var arraylistOfString = new ArrayList (); + + // Check last for empty list + if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT | TestTrapFlags.SILENCE_STDERR)) { + arraylistOfString.last (); + return; + } + Test.trap_assert_failed (); + + // Check last for list with one element + arraylistOfString.add ("1"); + assert (arraylistOfString.last () == "1"); + assert (arraylistOfString.last () == arraylistOfString.get (arraylistOfString.size - 1)); + + // Check last for for list with multiple element + arraylistOfString.add ("2"); + arraylistOfString.add ("3"); + assert (arraylistOfString.last () == "3"); + assert (arraylistOfString.last () == arraylistOfString.get (arraylistOfString.size - 1)); + + // Check last if list is cleared and empty again + arraylistOfString.clear (); + + if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT | TestTrapFlags.SILENCE_STDERR)) { + arraylistOfString.last (); + return; + } + Test.trap_assert_failed (); + } + + void test_arraylist_insert_all () { + var arraylist1 = new ArrayList (); + var arraylist2 = new ArrayList (); + + // Insert an empty list + arraylist1.add (0); + arraylist1.add (1); + arraylist1.add (2); + + assert (arraylist1.size == 3); + assert (arraylist2.is_empty); + + arraylist1.insert_all (0, arraylist2); + + assert (arraylist1.size == 3); + assert (arraylist2.is_empty); + + arraylist1.clear (); + arraylist2.clear (); + + // Insert into an empty list at index 0 + arraylist2.add (0); + arraylist2.add (1); + arraylist2.add (2); + + assert (arraylist1.is_empty); + assert (arraylist2.size == 3); + + arraylist1.insert_all (0, arraylist2); + + assert (arraylist1.size == 3); + assert (arraylist2.size == 3); + + arraylist1.clear (); + arraylist2.clear (); + + // Insert all into empty list as index 1 + arraylist2.add (0); + arraylist2.add (1); + arraylist2.add (2); + + assert (arraylist1.is_empty); + + if (Test.trap_fork (0, TestTrapFlags.SILENCE_STDOUT | TestTrapFlags.SILENCE_STDERR)) { + arraylist1.insert_all (1, arraylist2); + return; + } + Test.trap_assert_failed (); + + arraylist1.clear (); + arraylist2.clear (); + + // Insert all in the beginnig + arraylist1.add (3); + arraylist1.add (4); + arraylist1.add (5); + + arraylist2.add (0); + arraylist2.add (1); + arraylist2.add (2); + + assert (arraylist1.size == 3); + assert (arraylist2.size == 3); + + arraylist1.insert_all (0, arraylist2); + + assert (arraylist1.size == 6); + assert (arraylist2.size == 3); + + assert (arraylist1.get (0) == 0); + assert (arraylist1.get (1) == 1); + assert (arraylist1.get (2) == 2); + assert (arraylist1.get (3) == 3); + assert (arraylist1.get (4) == 4); + assert (arraylist1.get (5) == 5); + + arraylist1.clear (); + arraylist2.clear (); + + // Insert all in the middle + arraylist1.add (0); + arraylist1.add (1); + arraylist1.add (5); + arraylist1.add (6); + + arraylist2.add (2); + arraylist2.add (3); + arraylist2.add (4); + + assert (arraylist1.size == 4); + assert (arraylist2.size == 3); + + arraylist1.insert_all (2, arraylist2); + + assert (arraylist1.size == 7); + assert (arraylist2.size == 3); + + assert (arraylist1.get (0) == 0); + assert (arraylist1.get (1) == 1); + assert (arraylist1.get (2) == 2); + assert (arraylist1.get (3) == 3); + assert (arraylist1.get (4) == 4); + assert (arraylist1.get (5) == 5); + assert (arraylist1.get (6) == 6); + + arraylist1.clear (); + arraylist2.clear (); + + // Insert all in at the end + arraylist1.add (0); + arraylist1.add (1); + arraylist1.add (2); + + arraylist2.add (3); + arraylist2.add (4); + arraylist2.add (5); + + assert (arraylist1.size == 3); + assert (arraylist2.size == 3); + + arraylist1.insert_all (3, arraylist2); + + assert (arraylist1.size == 6); + assert (arraylist2.size == 3); + + assert (arraylist1.get (0) == 0); + assert (arraylist1.get (1) == 1); + assert (arraylist1.get (2) == 2); + assert (arraylist1.get (3) == 3); + assert (arraylist1.get (4) == 4); + assert (arraylist1.get (5) == 5); + + arraylist1.clear (); + arraylist2.clear (); + } } void main (string[] args) {