summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2018-09-14 15:16:08 +0200
committerEugen Wissner <belka@caraus.de>2018-09-14 15:16:08 +0200
commitb831a05407aaac5f834c6a604b7323ab06ffa70f (patch)
tree30781ce8ea9bbed18e7af5c8842c089b98a170b2 /source
parentb6d1766d58a93bb8c537d3a1a127cda703cf2034 (diff)
downloadtanya-b831a05407aaac5f834c6a604b7323ab06ffa70f.tar.gz
Introduce hash.lookup.isHashFunction trait
Fix #66.
Diffstat (limited to 'source')
-rw-r--r--source/tanya/container/hashtable.d2
-rw-r--r--source/tanya/container/set.d6
-rw-r--r--source/tanya/hash/lookup.d24
3 files changed, 28 insertions, 4 deletions
diff --git a/source/tanya/container/hashtable.d b/source/tanya/container/hashtable.d
index 08f395f..771e0fa 100644
--- a/source/tanya/container/hashtable.d
+++ b/source/tanya/container/hashtable.d
@@ -386,7 +386,7 @@ struct ByValue(T)
* hasher = Hash function for $(D_PARAM Key).
*/
struct HashTable(Key, Value, alias hasher = hash)
-if (is(typeof(((Key k) => hasher(k))(Key.init)) == size_t))
+if (isHashFunction!(hasher, Key))
{
private alias HashArray = .HashArray!(hasher, Key, Value);
private alias Buckets = HashArray.Buckets;
diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d
index e5dc2d6..0c8a3f3 100644
--- a/source/tanya/container/set.d
+++ b/source/tanya/container/set.d
@@ -154,7 +154,7 @@ struct Range(T)
* hasher = Hash function for $(D_PARAM T).
*/
struct Set(T, alias hasher = hash)
-if (is(typeof(((T x) => hasher(x))(T.init)) == size_t))
+if (isHashFunction!(hasher, T))
{
private alias HashArray = .HashArray!(hasher, T);
private alias Buckets = HashArray.Buckets;
@@ -768,8 +768,8 @@ if (is(typeof(((T x) => hasher(x))(T.init)) == size_t))
testFunc(set);
}
+// Hasher can take argument by ref
@nogc nothrow pure @safe unittest
{
- // Using hasher that takes argument by ref.
- Set!(int, (const ref x) => cast(size_t)x) set;
+ static assert(is(Set!(int, (const ref x) => cast(size_t) x)));
}
diff --git a/source/tanya/hash/lookup.d b/source/tanya/hash/lookup.d
index 9b0d883..f0163ac 100644
--- a/source/tanya/hash/lookup.d
+++ b/source/tanya/hash/lookup.d
@@ -636,3 +636,27 @@ static if (size_t.sizeof == 8) @nogc nothrow pure @safe unittest
assert(hash(r500!"~") == 0xc1af12bdfe16b5b5UL);
assert(hash(r500!"\x7f") == 0x39e9f18f2f85e221UL);
}
+
+/**
+ * Determines whether $(D_PARAM hasher) is hash function for $(D_PARAM T), i.e.
+ * it is callable with a value of type $(D_PARAM T) and returns a
+ * $(D_PSYMBOL size_t) value.
+ *
+ * Params:
+ * hasher = Hash function candidate.
+ * T = Type to test the hash function with.
+ *
+ * Returns: $(D_KEYWORD true) if $(D_PARAM hasher) is a hash function for
+ * $(D_PARAM T), $(D_KEYWORD false) otherwise.
+ */
+template isHashFunction(alias hasher, T)
+{
+ private alias wrapper = (T x) => hasher(x);
+ enum bool isHashFunction = is(typeof(wrapper(T.init)) == size_t);
+}
+
+///
+@nogc nothrow pure @safe unittest
+{
+ static assert(isHashFunction!(hash, int));
+}