diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d index ed508bd..ff09669 100644 --- a/source/tanya/container/entry.d +++ b/source/tanya/container/entry.d @@ -164,13 +164,22 @@ package struct HashArray(alias hasher, K, V = void) .swap(this.length, data.length); } + void opAssign(ref typeof(this) that) + { + this.array = that.array; + this.lengthIndex = that.lengthIndex; + this.length = that.length; + } + /* * Returns bucket position for `hash`. `0` may mean the 0th position or an * empty `buckets` array. */ size_t locateBucket(ref const Key key) const { - return this.array.length == 0 ? 0 : hasher(key) % this.array.length; + return this.array.length == 0 + ? 0 + : hasher(key) % primes[this.lengthIndex]; } /* @@ -179,11 +188,9 @@ package struct HashArray(alias hasher, K, V = void) */ ref Bucket insert(ref Key key) { - while (true) + while ((this.lengthIndex + 1) != primes.length) { - auto bucketPosition = locateBucket(key); - - foreach (ref e; this.array[bucketPosition .. $]) + foreach (ref e; this.array[locateBucket(key) .. $]) { if (e == key) { @@ -196,16 +203,13 @@ package struct HashArray(alias hasher, K, V = void) } } - if (primes.length == (this.lengthIndex + 1)) - { - this.array.insertBack(Bucket(key)); - return this.array[$ - 1]; - } if (this.rehashToSize(this.lengthIndex + 1)) { ++this.lengthIndex; } } + this.array.insertBack(Bucket(key)); + return this.array[$ - 1]; } // Takes an index in the primes array. @@ -221,7 +225,7 @@ package struct HashArray(alias hasher, K, V = void) { if (e1.status == BucketStatus.used) { - auto bucketPosition = hasher(e1.key) % storage.length; + auto bucketPosition = hasher(e1.key) % primes[n]; foreach (ref e2; storage[bucketPosition .. $]) { @@ -267,8 +271,7 @@ package struct HashArray(alias hasher, K, V = void) size_t remove(ref Key key) { - auto bucketPosition = locateBucket(key); - foreach (ref e; this.array[bucketPosition .. $]) + foreach (ref e; this.array[locateBucket(key) .. $]) { if (e == key) // Found. { @@ -286,8 +289,7 @@ package struct HashArray(alias hasher, K, V = void) bool opBinaryRight(string op : "in")(ref inout(Key) key) inout { - auto bucketPosition = locateBucket(key); - foreach (ref e; this.array[bucketPosition .. $]) + foreach (ref e; this.array[locateBucket(key) .. $]) { if (e == key) // Found. { diff --git a/source/tanya/container/hashtable.d b/source/tanya/container/hashtable.d index b7224fa..b1a347d 100644 --- a/source/tanya/container/hashtable.d +++ b/source/tanya/container/hashtable.d @@ -194,7 +194,7 @@ if (is(typeof(hasher(Key.init)) == size_t)) do { this(allocator); - rehash(n); + this.data.rehash(n); } /// @@ -265,7 +265,6 @@ if (is(typeof(hasher(Key.init)) == size_t)) if (is(Unqual!S == HashTable)) { this.data = that.data; - this.data.lengthIndex = that.data.lengthIndex; return this; } @@ -604,6 +603,16 @@ if (is(typeof(hasher(Key.init)) == size_t)) assert(hashTable.capacity == 7); } +// Assigns by reference +@nogc nothrow pure @safe unittest +{ + auto hashTable1 = HashTable!(string, int)(7); + HashTable!(string, int) hashTable2; + hashTable1 = hashTable2; + assert(hashTable1.length == hashTable2.length); + assert(hashTable1.capacity == hashTable2.capacity); +} + // Assigns by value @nogc nothrow pure @safe unittest { @@ -611,3 +620,14 @@ if (is(typeof(hasher(Key.init)) == size_t)) hashTable = HashTable!(string, int)(7); assert(hashTable.capacity == 7); } + +// Postblit copies +@nogc nothrow pure @safe unittest +{ + auto hashTable = HashTable!(string, int)(7); + void testFunc(HashTable!(string, int) hashTable) + { + assert(hashTable.capacity == 7); + } + testFunc(hashTable); +} diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d index 2ac3e2e..b8fd0e6 100644 --- a/source/tanya/container/set.d +++ b/source/tanya/container/set.d @@ -191,7 +191,7 @@ if (is(typeof(hasher(T.init)) == size_t)) do { this(allocator); - rehash(n); + this.data.rehash(n); } /// @@ -262,7 +262,6 @@ if (is(typeof(hasher(T.init)) == size_t)) if (is(Unqual!S == Set)) { this.data = that.data; - this.data.lengthIndex = that.data.lengthIndex; return this; } @@ -619,6 +618,16 @@ if (is(typeof(hasher(T.init)) == size_t)) assert(set.capacity == 7); } +// Assigns by reference +@nogc nothrow pure @safe unittest +{ + auto set1 = Set!int(7); + Set!int set2; + set1 = set2; + assert(set1.length == set2.length); + assert(set1.capacity == set2.capacity); +} + // Assigns by value @nogc nothrow pure @safe unittest { @@ -626,3 +635,14 @@ if (is(typeof(hasher(T.init)) == size_t)) set = Set!int(7); assert(set.capacity == 7); } + +// Postblit copies +@nogc nothrow pure @safe unittest +{ + auto set = Set!int(7); + void testFunc(Set!int set) + { + assert(set.capacity == 7); + } + testFunc(set); +}