summaryrefslogtreecommitdiff
path: root/gee/functions.vala
blob: c391c5f1258850e574c16e9f0c5dabced18a1266 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/* functions.vala
 *
 * Copyright (C) 2009  Didier Villevalois, 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:
 * 	Didier 'Ptitjes' Villevalois <ptitjes@free.fr>
 * 	Maciej Piechotka <uzytkownik2@gmail.com>
 */

using GLib;

namespace Gee {

	/**
	 * Helpers for equal, hash and compare functions.
	 *
	 * With those functions, you can retrieve the equal, hash and compare
	 * functions that best match your element, key or value types. Supported
	 * types are (non-boxed) primitive, string and ``Object`` types.
	 *
	 * A special care is taken for classes inheriting from the
	 * {@link Comparable} interface. For such types, an appropriate compare
	 * function is returned that calls {@link Comparable.compare_to}.
	 *
	 */
	namespace Functions {

		/**
		 * Get a equality testing function for a given type.
		 *
		 * @param t the type which to get an equality testing function for.
		 *
		 * @return the equality testing function corresponding to the given type.
		 */
		public static EqualDataFunc<void*> get_equal_func_for (Type t) {
			if (t == typeof (string)) {
				return (a, b) => {
					if (a == b)
						return true;
					else if (a == null || b == null)
						return false;
					else
						return str_equal ((string) a, (string) b);
				};
			} else if (t.is_a (typeof (Hashable))) {
				return (a, b) => {
					if (a == b)
						return true;
					else if (a == null || b == null)
						return false;
					else
						return ((Hashable<Hashable>) a).equal_to ((Hashable) b);
				};
			} else if (t.is_a (typeof (Comparable))) {
				return (a, b) => {					
					if (a == b)
						return true;
					else if (a == null || b == null)
						return false;
					else
						return ((Comparable<Comparable>) a).compare_to ((Comparable) b) == 0;};
			} else {
				return (a, b) => {return direct_equal (a, b);};
			}
		}

		/**
		 * Get a hash function for a given type.
		 *
		 * @param t the type which to get the hash function for.
		 *
		 * @return the hash function corresponding to the given type.
		 */
		public static HashDataFunc<void*> get_hash_func_for (Type t) {
			if (t == typeof (string)) {
				return (a) => {
					if (a == null)
						return (uint)0xdeadbeef;
					else
						return str_hash ((string) a);
				};
			} else if (t.is_a (typeof (Hashable))) {
				return (a) => {
					if (a == null)
						return (uint)0xdeadbeef;
					else
						return ((Hashable) a).hash();
				};
			} else {
				return (a) => {return direct_hash (a);};
			}
		}

		/**
		 * Get a comparator function for a given type.
		 *
		 * @param t the type which to get a comparator function for.
		 *
		 * @return the comparator function corresponding to the given type.
		 */
		public static CompareDataFunc<void*> get_compare_func_for (Type t) {
			if (t == typeof (string)) {
				return (a, b) => {
					if (a == b)
						return 0;
					else if (a == null)
						return -1;
					else if (b == null)
						return 1;
					else
						return strcmp((string) a, (string) b);
				};
			} else if (t.is_a (typeof (Comparable))) {
				return (a, b) => {
					if (a == b)
						return 0;
					else if (a == null)
						return -1;
					else if (b == null)
						return 1;
					else
						return ((Comparable<Comparable>) a).compare_to ((Comparable) b);
				};
			} else {
				return (_val1, _val2) => {
					long val1 = (long)_val1, val2 = (long)_val2;
					if (val1 > val2) {
						return 1;
					} else if (val1 == val2) {
						return 0;
					} else {
						return -1;
					}
				};
			}
		}

		[CCode (simple_generics = true)]
		internal class EqualDataFuncClosure<G> {
			public EqualDataFuncClosure(owned EqualDataFunc<G> func) {
				this.func = (owned)func;
			}
			public EqualDataFunc<G> func;
			public EqualDataFunc<G> clone_func () {
				return (a, b) => {return func (a, b);};
			}
		}

		[CCode (simple_generics = true)]
		internal class HashDataFuncClosure<G> {
			public HashDataFuncClosure(owned HashDataFunc<G> func) {
				this.func = (owned)func;
			}
			public HashDataFunc<G> func;
			public HashDataFunc<G> clone_func () {
				return (a) => {return func (a);};
			}
		}

		[CCode (simple_generics = true)]
		internal class CompareDataFuncClosure<G> {
			public CompareDataFuncClosure(owned CompareDataFunc<G> func) {
				this.func = (owned)func;
			}
			public CompareDataFunc<G> func;
			public CompareDataFunc<G> clone_func () {
				return (a, b) => {return func (a, b);};
			}
		}
	}
}