container.Set and HashTable: Fix constructors
This commit is contained in:
parent
385ec19e2f
commit
c511b97b1b
@ -26,7 +26,7 @@ Tanya consists of the following packages and (top-level) modules:
|
|||||||
* `algorithm`: Collection of generic algorithms.
|
* `algorithm`: Collection of generic algorithms.
|
||||||
* `async`: Event loop (epoll, kqueue and IOCP).
|
* `async`: Event loop (epoll, kqueue and IOCP).
|
||||||
* `container`: Queue, Array, Singly and doubly linked lists, Buffers, UTF-8
|
* `container`: Queue, Array, Singly and doubly linked lists, Buffers, UTF-8
|
||||||
string, Hash table.
|
string, Set, Hash table.
|
||||||
* `conv`: This module provides functions for converting between different
|
* `conv`: This module provides functions for converting between different
|
||||||
types.
|
types.
|
||||||
* `encoding`: This package provides tools to work with text encodings.
|
* `encoding`: This package provides tools to work with text encodings.
|
||||||
|
@ -16,7 +16,9 @@ module tanya.container.entry;
|
|||||||
|
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
|
import tanya.meta.transform;
|
||||||
import tanya.typecons;
|
import tanya.typecons;
|
||||||
|
|
||||||
package struct SEntry(T)
|
package struct SEntry(T)
|
||||||
@ -119,6 +121,49 @@ package struct HashArray(alias hasher, K, V = void)
|
|||||||
size_t lengthIndex;
|
size_t lengthIndex;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
|
this(shared Allocator allocator)
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(allocator !is null);
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
this.array = Buckets(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
this(T)(ref T data, shared Allocator allocator)
|
||||||
|
if (is(Unqual!T == HashArray))
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(allocator !is null);
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
this.array = Buckets(data.array, allocator);
|
||||||
|
this.lengthIndex = data.lengthIndex;
|
||||||
|
this.length = data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move constructor
|
||||||
|
void move(ref HashArray data, shared Allocator allocator)
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(allocator !is null);
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
this.array = Buckets(.move(data.array), allocator);
|
||||||
|
this.lengthIndex = data.lengthIndex;
|
||||||
|
this.length = data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(ref HashArray data)
|
||||||
|
{
|
||||||
|
.swap(this.array, data.array);
|
||||||
|
.swap(this.lengthIndex, data.lengthIndex);
|
||||||
|
.swap(this.length, data.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.
|
||||||
@ -189,7 +234,7 @@ package struct HashArray(alias hasher, K, V = void)
|
|||||||
return false; // Rehashing failed.
|
return false; // Rehashing failed.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
move(storage, this.array);
|
.move(storage, this.array);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ struct Range(T)
|
|||||||
* Params:
|
* Params:
|
||||||
* Key = Key type.
|
* Key = Key type.
|
||||||
* Value = Value type.
|
* Value = Value type.
|
||||||
* hasher = Hash function for $(D_PARAM K).
|
* hasher = Hash function for $(D_PARAM Key).
|
||||||
*/
|
*/
|
||||||
struct HashTable(Key, Value, alias hasher = hash)
|
struct HashTable(Key, Value, alias hasher = hash)
|
||||||
if (is(typeof(hasher(Key.init)) == size_t))
|
if (is(typeof(hasher(Key.init)) == size_t))
|
||||||
@ -170,6 +170,13 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
/// ditto
|
/// ditto
|
||||||
alias ConstRange = .Range!(const HashArray);
|
alias ConstRange = .Range!(const HashArray);
|
||||||
|
|
||||||
|
invariant
|
||||||
|
{
|
||||||
|
assert(this.data.lengthIndex < primes.length);
|
||||||
|
assert(this.data.array.length == 0
|
||||||
|
|| this.data.array.length == primes[this.data.lengthIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@ -190,6 +197,13 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
rehash(n);
|
rehash(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
auto hashTable = HashTable!(string, int)(5);
|
||||||
|
assert(hashTable.capacity == 7);
|
||||||
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
this(shared Allocator allocator)
|
this(shared Allocator allocator)
|
||||||
in
|
in
|
||||||
@ -198,7 +212,7 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
this.data = HashArray(Buckets(allocator));
|
this.data = HashArray(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,7 +234,7 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
this.data = HashArray(Buckets(init.data, allocator));
|
this.data = HashArray(init.data, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
@ -232,9 +246,7 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
this.data = HashArray(Buckets(move(init.data), allocator));
|
this.data.move(init.data, allocator);
|
||||||
this.lengthIndex = init.lengthIndex;
|
|
||||||
init.lengthIndex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,8 +273,7 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
ref typeof(this) opAssign(S)(S that) @trusted
|
ref typeof(this) opAssign(S)(S that) @trusted
|
||||||
if (is(S == HashTable))
|
if (is(S == HashTable))
|
||||||
{
|
{
|
||||||
swap(this.data, that.data);
|
this.data.swap(that.data);
|
||||||
swap(this.lengthIndex, that.lengthIndex);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,3 +587,27 @@ if (is(typeof(hasher(Key.init)) == size_t))
|
|||||||
static assert(is(const HashTable!(string, int)));
|
static assert(is(const HashTable!(string, int)));
|
||||||
static assert(isForwardRange!(HashTable!(string, int).Range));
|
static assert(isForwardRange!(HashTable!(string, int).Range));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructs by reference
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
auto hashTable1 = HashTable!(string, int)(7);
|
||||||
|
auto hashTable2 = HashTable!(string, int)(hashTable1);
|
||||||
|
assert(hashTable1.length == hashTable2.length);
|
||||||
|
assert(hashTable1.capacity == hashTable2.capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs by value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
auto hashTable = HashTable!(string, int)(HashTable!(string, int)(7));
|
||||||
|
assert(hashTable.capacity == 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assigns by value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
HashTable!(string, int) hashTable;
|
||||||
|
hashTable = HashTable!(string, int)(7);
|
||||||
|
assert(hashTable.capacity == 7);
|
||||||
|
}
|
||||||
|
@ -194,6 +194,13 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
rehash(n);
|
rehash(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
auto set = Set!int(5);
|
||||||
|
assert(set.capacity == 7);
|
||||||
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
this(shared Allocator allocator)
|
this(shared Allocator allocator)
|
||||||
in
|
in
|
||||||
@ -202,7 +209,7 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
this.data = HashArray(Buckets(allocator));
|
this.data = HashArray(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,7 +231,7 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
this.data = HashArray(Buckets(init.data, allocator));
|
this.data = HashArray(init.data, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
@ -236,9 +243,7 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
this.data = HashArray(Buckets(move(init.data), allocator));
|
this.data.move(init.data, allocator);
|
||||||
this.lengthIndex = init.lengthIndex;
|
|
||||||
init.lengthIndex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -257,7 +262,7 @@ 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.lengthIndex = that.lengthIndex;
|
this.data.lengthIndex = that.data.lengthIndex;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,8 +270,7 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
ref typeof(this) opAssign(S)(S that) @trusted
|
ref typeof(this) opAssign(S)(S that) @trusted
|
||||||
if (is(S == Set))
|
if (is(S == Set))
|
||||||
{
|
{
|
||||||
swap(this.data, that.data);
|
this.data.swap(that.data);
|
||||||
swap(this.lengthIndex, that.lengthIndex);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,3 +602,27 @@ if (is(typeof(hasher(T.init)) == size_t))
|
|||||||
auto set = Set!int(8);
|
auto set = Set!int(8);
|
||||||
assert(set.capacity == 13);
|
assert(set.capacity == 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructs by reference
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
auto set1 = Set!int(7);
|
||||||
|
auto set2 = Set!int(set1);
|
||||||
|
assert(set1.length == set2.length);
|
||||||
|
assert(set1.capacity == set2.capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs by value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
auto set = Set!int(Set!int(7));
|
||||||
|
assert(set.capacity == 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assigns by value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Set!int set;
|
||||||
|
set = Set!int(7);
|
||||||
|
assert(set.capacity == 7);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user