[libgee] Add Gee.Hashable interface



commit ce244dff0b71267fa5f93bdd8d24424065ab8a16
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date:   Tue Aug 24 12:26:13 2010 +0200

    Add Gee.Hashable interface

 gee/Makefile.am          |    1 +
 gee/comparable.vala      |    2 +
 gee/functions.vala       |    4 +++
 gee/hashable.vala        |   44 +++++++++++++++++++++++++++++++
 tests/testfunctions.vala |   64 ++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 113 insertions(+), 2 deletions(-)
---
diff --git a/gee/Makefile.am b/gee/Makefile.am
index 75c6951..dd69136 100644
--- a/gee/Makefile.am
+++ b/gee/Makefile.am
@@ -18,6 +18,7 @@ libgee_la_SOURCES = \
 	comparable.vala \
 	deque.vala \
 	functions.vala \
+	hashable.vala \
 	hashmap.vala \
 	hashmultimap.vala \
 	hashmultiset.vala \
diff --git a/gee/comparable.vala b/gee/comparable.vala
index 01e9a5e..9639483 100644
--- a/gee/comparable.vala
+++ b/gee/comparable.vala
@@ -23,6 +23,8 @@
 /**
  * This interface defines a total ordering among instances of each class
  * implementing it.
+ *
+ * @see Hashable
  */
 public interface Gee.Comparable<G> : Object {
 	/**
diff --git a/gee/functions.vala b/gee/functions.vala
index d77719e..1a5ec54 100644
--- a/gee/functions.vala
+++ b/gee/functions.vala
@@ -49,6 +49,8 @@ namespace Gee {
 		public static EqualDataFunc get_equal_func_for (Type t) {
 			if (t == typeof (string)) {
 				return (a, b) => {return str_equal ((string) a, (string) b);};
+			} else if (t.is_a (typeof (Hashable))) {
+				return (a, b) => {return ((Hashable<Hashable>) a).equal_to ((Hashable) b);};
 			} else if (t.is_a (typeof (Comparable))) {
 				return (a, b) => {return ((Comparable<Comparable>) a).compare_to ((Comparable) b) == 0;};
 			} else {
@@ -66,6 +68,8 @@ namespace Gee {
 		public static HashDataFunc get_hash_func_for (Type t) {
 			if (t == typeof (string)) {
 				return (a) => {return str_hash ((string) a);};
+			} else if (t.is_a (typeof (Hashable))) {
+				return (a) => {return ((Hashable) a).hash();};
 			} else {
 				return (a) => {return direct_hash (a);};
 			}
diff --git a/gee/hashable.vala b/gee/hashable.vala
new file mode 100644
index 0000000..8a2c785
--- /dev/null
+++ b/gee/hashable.vala
@@ -0,0 +1,44 @@
+/* hashable.vala
+ *
+ * Copyright (C) 2010  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 <uzytkwonik2 gmail com>
+ */
+
+/**
+ * This interface defines a hash function amongs instances of each class
+ * implementing it.
+ * 
+ * @see Comparable
+ */
+public interface Gee.Hashable<G> : Object {
+	/**
+	 * Computes hash for an objects. Two hashes of equal objects have to be
+	 * equal. Hash have to not change during lifetime of object.
+	 *
+	 * @return hash of an object
+	 */
+	public abstract uint hash ();
+
+	/**
+	 * Compares this object with the specifed object.
+	 *
+	 * @return true if objects are equal
+	 */
+	public abstract bool equal_to (G object);
+}
diff --git a/tests/testfunctions.vala b/tests/testfunctions.vala
index a241cfd..a174873 100644
--- a/tests/testfunctions.vala
+++ b/tests/testfunctions.vala
@@ -25,7 +25,8 @@ public class FunctionsTests : Gee.TestCase {
 		base ("Functions");
 		add_test ("[Functions] comparing and hashing strings", test_string_func);
 		add_test ("[Functions] comparing and hashing int", test_int_func);
-		add_test ("[Functions] comparing and hashing instances of Comparable", test_compare_func);
+		add_test ("[Functions] comparing instances of Comparable", test_compare_func);
+		add_test ("[Functions] comparing and hashing instances of Hashable", test_hash_func);
 	}
 
 	public void test_string_func () {
@@ -106,8 +107,41 @@ public class FunctionsTests : Gee.TestCase {
 		assert (cmp (two, one) > 0);
 	}
 
+	public void test_hash_func () {
+		MyHashable two = new MyHashable(2);
+		MyHashable one = new MyHashable(1);
+		MyHashable twoCopy = new MyHashable(2);
+		MyHashable minusOne = new MyHashable(-1);
+
+		Gee.EqualDataFunc eq = Gee.Functions.get_equal_func_for (typeof (MyHashable));
+		CompareDataFunc cmp = Gee.Functions.get_compare_func_for (typeof (MyHashable));
+		Gee.HashDataFunc hash = Gee.Functions.get_hash_func_for (typeof (MyHashable));
+
+		assert (eq != null);
+		assert (cmp != null);
+		assert (hash != null);
+
+		assert (eq (two, two));
+		assert (cmp (two, two) == 0);
+		assert (hash (two) == hash (two));
+
+		assert (eq (two, twoCopy));
+		assert (cmp (two, twoCopy) == 0);
+		assert (hash (two) == hash (twoCopy));
+
+		assert (!eq (one, two));
+		assert (cmp (one, two) < 0);
+		
+		assert (!eq (two, one));
+		assert (cmp (two, one) > 0);
+
+		// Check if correct functions taken
+		assert (hash (one) == 1);
+		assert (!eq (minusOne, minusOne));
+	}
+
 	private class MyComparable : GLib.Object, Gee.Comparable<MyComparable> {
-		public MyComparable(int i) {
+		public MyComparable (int i) {
 			this.i = i;
 		}
 
@@ -122,5 +156,31 @@ public class FunctionsTests : Gee.TestCase {
 
 		int i;
 	}
+
+	private class MyHashable : GLib.Object, Gee.Comparable<MyHashable>, Gee.Hashable<MyHashable> {
+		public MyHashable (int i) {
+			this.i = i;
+		}
+
+		public int compare_to (MyHashable cmp) {
+			if (i == cmp.i)
+				return 0;
+			else if (i >= cmp.i)
+				return 1;
+			else
+				return -1;
+		}
+
+		public uint hash () {
+			return i;
+		}
+
+		public bool equal_to (MyHashable hash) {
+			// -1 break API but it is used for checks
+			return i == hash.i && i != -1;
+		}
+
+		int i;
+	}
 }
 



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