Introduce hash.lookup.isHashFunction trait

Fix #66.
This commit is contained in:
Eugen Wissner 2018-09-14 15:16:08 +02:00
parent b6d1766d58
commit b831a05407
3 changed files with 28 additions and 4 deletions

View File

@ -386,7 +386,7 @@ struct ByValue(T)
* hasher = Hash function for $(D_PARAM Key). * hasher = Hash function for $(D_PARAM Key).
*/ */
struct HashTable(Key, Value, alias hasher = hash) 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 HashArray = .HashArray!(hasher, Key, Value);
private alias Buckets = HashArray.Buckets; private alias Buckets = HashArray.Buckets;

View File

@ -154,7 +154,7 @@ struct Range(T)
* hasher = Hash function for $(D_PARAM T). * hasher = Hash function for $(D_PARAM T).
*/ */
struct Set(T, alias hasher = hash) 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 HashArray = .HashArray!(hasher, T);
private alias Buckets = HashArray.Buckets; private alias Buckets = HashArray.Buckets;
@ -768,8 +768,8 @@ if (is(typeof(((T x) => hasher(x))(T.init)) == size_t))
testFunc(set); testFunc(set);
} }
// Hasher can take argument by ref
@nogc nothrow pure @safe unittest @nogc nothrow pure @safe unittest
{ {
// Using hasher that takes argument by ref. static assert(is(Set!(int, (const ref x) => cast(size_t) x)));
Set!(int, (const ref x) => cast(size_t)x) set;
} }

View File

@ -636,3 +636,27 @@ static if (size_t.sizeof == 8) @nogc nothrow pure @safe unittest
assert(hash(r500!"~") == 0xc1af12bdfe16b5b5UL); assert(hash(r500!"~") == 0xc1af12bdfe16b5b5UL);
assert(hash(r500!"\x7f") == 0x39e9f18f2f85e221UL); 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));
}