From 64ef16379bc23e225a925c433b9f5381dc9ae9f3 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Mon, 18 Jun 2018 16:11:35 -0700 Subject: [PATCH] Support structs for key types in the hashmap/treemap. #71 --- src/containers/hashmap.d | 6 +++--- src/containers/treemap.d | 12 ++++++------ test/compile_test.d | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/containers/hashmap.d b/src/containers/hashmap.d index 66e1b55..53261e3 100644 --- a/src/containers/hashmap.d +++ b/src/containers/hashmap.d @@ -252,7 +252,7 @@ struct HashMap(K, V, Allocator = Mallocator, alias hashFunction = generateHash!K foreach (ref const bucket; buckets) { foreach (item; bucket) - app.put(item.key); + app.put(cast(K) item.key); } return app.data; } @@ -437,7 +437,7 @@ private: } } Node* n; - n = buckets[index].insertAnywhere(Node(hash, key, value)); + n = buckets[index].insertAnywhere(Node(hash, cast(ContainerStorageType!K) key, value)); if (modifyLength) _length++; if (shouldRehash()) @@ -481,7 +481,7 @@ private: foreach (ref bucket; oldBuckets) { foreach (node; bucket) - insert(node.key, node.value, node.hash, false); + insert(cast(K) node.key, node.value, node.hash, false); typeid(typeof(bucket)).destroy(&bucket); } static if (useGC) diff --git a/src/containers/treemap.d b/src/containers/treemap.d index 2be60bb..c54b3cd 100644 --- a/src/containers/treemap.d +++ b/src/containers/treemap.d @@ -54,9 +54,9 @@ struct TreeMap(K, V, Allocator = Mallocator, alias less = "a < b", /** * Inserts or overwrites the given key-value pair. */ - void insert(const K key, V value) @safe + void insert(const K key, V value) @trusted { - auto tme = TreeMapElement(key, value); + auto tme = TreeMapElement(cast(ContainerStorageType!K) key, value); auto r = tree.equalRange(tme); if (r.empty) tree.insert(tme, true); @@ -78,7 +78,7 @@ struct TreeMap(K, V, Allocator = Mallocator, alias less = "a < b", auto opIndex(this This)(const K key) inout { alias CET = ContainerElementType!(This, V); - auto tme = TreeMapElement(key); + auto tme = TreeMapElement(cast(ContainerStorageType!K) key); return cast(CET) tree.equalRange(tme).front.value; } @@ -126,16 +126,16 @@ struct TreeMap(K, V, Allocator = Mallocator, alias less = "a < b", */ bool remove(const K key) { - auto tme = TreeMapElement(key); + auto tme = TreeMapElement(cast(ContainerStorageType!K) key); return tree.remove(tme); } /** * Returns: true if the mapping contains the given key */ - bool containsKey(const K key) inout pure nothrow @nogc @safe + bool containsKey(const K key) inout pure nothrow @nogc @trusted { - auto tme = TreeMapElement(key); + auto tme = TreeMapElement(cast(ContainerStorageType!K) key); return tree.contains(tme); } diff --git a/test/compile_test.d b/test/compile_test.d index a27c07f..6a52f3d 100644 --- a/test/compile_test.d +++ b/test/compile_test.d @@ -69,6 +69,45 @@ private void testContainerDouble(alias Container)() { testContainerDoubleVal!(Container)(); testContainerDoubleRef!(Container)(); + testContainerDoubleAggregateKey!(Container)(); +} + +private void testContainerDoubleAggregateKey(alias Container)() +{ + static struct KeyType + { + int a; + string[] c; + + int opCmp(ref const KeyType other) const + { + if (other.a < a) + return -1; + return other.a > a; + } + + size_t toHash() const + { + return 10; + } + + bool opEquals(ref const KeyType other) const + { + return a == other.a; + } + } + + Container!(const KeyType, int) cm; + + Container!(immutable KeyType, int) im; + + checkIndexFunctionality!(int, const KeyType)(cm); + + checkIndexFunctionality!(int, const KeyType)(im); + + checkSliceFunctionality!(int)(cm); + + checkSliceFunctionality!(int)(im); } private void testContainerDoubleVal(alias Container)()