HashTable/Set: Add proper assignment
This commit is contained in:
parent
9efbc9d5e0
commit
c268696ee9
@ -164,13 +164,22 @@ package struct HashArray(alias hasher, K, V = void)
|
|||||||
.swap(this.length, data.length);
|
.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
|
* Returns bucket position for `hash`. `0` may mean the 0th position or an
|
||||||
* empty `buckets` array.
|
* empty `buckets` array.
|
||||||
*/
|
*/
|
||||||
size_t locateBucket(ref const Key key) const
|
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)
|
ref Bucket insert(ref Key key)
|
||||||
{
|
{
|
||||||
while (true)
|
while ((this.lengthIndex + 1) != primes.length)
|
||||||
{
|
{
|
||||||
auto bucketPosition = locateBucket(key);
|
foreach (ref e; this.array[locateBucket(key) .. $])
|
||||||
|
|
||||||
foreach (ref e; this.array[bucketPosition .. $])
|
|
||||||
{
|
{
|
||||||
if (e == 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))
|
if (this.rehashToSize(this.lengthIndex + 1))
|
||||||
{
|
{
|
||||||
++this.lengthIndex;
|
++this.lengthIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.array.insertBack(Bucket(key));
|
||||||
|
return this.array[$ - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes an index in the primes array.
|
// Takes an index in the primes array.
|
||||||
@ -221,7 +225,7 @@ package struct HashArray(alias hasher, K, V = void)
|
|||||||
{
|
{
|
||||||
if (e1.status == BucketStatus.used)
|
if (e1.status == BucketStatus.used)
|
||||||
{
|
{
|
||||||
auto bucketPosition = hasher(e1.key) % storage.length;
|
auto bucketPosition = hasher(e1.key) % primes[n];
|
||||||
|
|
||||||
foreach (ref e2; storage[bucketPosition .. $])
|
foreach (ref e2; storage[bucketPosition .. $])
|
||||||
{
|
{
|
||||||
@ -267,8 +271,7 @@ package struct HashArray(alias hasher, K, V = void)
|
|||||||
|
|
||||||
size_t remove(ref Key key)
|
size_t remove(ref Key key)
|
||||||
{
|
{
|
||||||
auto bucketPosition = locateBucket(key);
|
foreach (ref e; this.array[locateBucket(key) .. $])
|
||||||
foreach (ref e; this.array[bucketPosition .. $])
|
|
||||||
{
|
{
|
||||||
if (e == key) // Found.
|
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
|
bool opBinaryRight(string op : "in")(ref inout(Key) key) inout
|
||||||
{
|
{
|
||||||
auto bucketPosition = locateBucket(key);
|
foreach (ref e; this.array[locateBucket(key) .. $])
|
||||||
foreach (ref e; this.array[bucketPosition .. $])
|
|
||||||
{
|
{
|
||||||
if (e == key) // Found.
|
if (e == key) // Found.
|
||||||
{
|
{
|
||||||
|
@ -194,7 +194,7 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
this(allocator);
|
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))
|
if (is(Unqual!S == HashTable))
|
||||||
{
|
{
|
||||||
this.data = that.data;
|
this.data = that.data;
|
||||||
this.data.lengthIndex = that.data.lengthIndex;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,6 +603,16 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
assert(hashTable.capacity == 7);
|
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
|
// Assigns by value
|
||||||
@nogc nothrow pure @safe unittest
|
@nogc nothrow pure @safe unittest
|
||||||
{
|
{
|
||||||
@ -611,3 +620,14 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
hashTable = HashTable!(string, int)(7);
|
hashTable = HashTable!(string, int)(7);
|
||||||
assert(hashTable.capacity == 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);
|
||||||
|
}
|
||||||
|
@ -191,7 +191,7 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
this(allocator);
|
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))
|
if (is(Unqual!S == Set))
|
||||||
{
|
{
|
||||||
this.data = that.data;
|
this.data = that.data;
|
||||||
this.data.lengthIndex = that.data.lengthIndex;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,6 +618,16 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
assert(set.capacity == 7);
|
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
|
// Assigns by value
|
||||||
@nogc nothrow pure @safe unittest
|
@nogc nothrow pure @safe unittest
|
||||||
{
|
{
|
||||||
@ -626,3 +635,14 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
set = Set!int(7);
|
set = Set!int(7);
|
||||||
assert(set.capacity == 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);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user