diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d index 8822924..a3cc9ee 100644 --- a/source/tanya/container/entry.d +++ b/source/tanya/container/entry.d @@ -120,6 +120,7 @@ package struct HashArray(alias hasher, K, V = void) Array!Bucket array; size_t lengthIndex; + size_t length; /* * Returns bucket position for `hash`. `0` may mean the 0th position or an @@ -144,10 +145,15 @@ package struct HashArray(alias hasher, K, V = void) foreach (ref e; this.array[bucketPosition .. $]) { - if (e == key || e.status != BucketStatus.used) + if (e == key) { return e; } + else if (e.status != BucketStatus.used) + { + ++this.length; + return e; + } } if (primes.length == (this.lengthIndex + 1)) @@ -207,4 +213,46 @@ package struct HashArray(alias hasher, K, V = void) { return this.array.length; } + + void clear() + { + this.array.clear(); + this.length = 0; + } + + size_t remove(ref K value) + { + auto bucketPosition = locateBucket(value); + foreach (ref e; this.array[bucketPosition .. $]) + { + if (e == value) // Found. + { + e.remove(); + --this.length; + return 1; + } + else if (e.status == BucketStatus.empty) + { + break; + } + } + return 0; + } + + bool find(ref const K value) const + { + auto bucketPosition = locateBucket(value); + foreach (ref e; this.array[bucketPosition .. $]) + { + if (e == value) // Found. + { + return true; + } + else if (e.status == BucketStatus.empty) + { + break; + } + } + return false; + } } diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d index 7d7449c..6f1b809 100644 --- a/source/tanya/container/set.d +++ b/source/tanya/container/set.d @@ -314,15 +314,7 @@ if (is(typeof(hasher(T.init)) == size_t)) */ @property size_t length() const { - size_t count; - foreach (ref e; this.data.array[]) - { - if (e.status == BucketStatus.used) - { - ++count; - } - } - return count; + return this.data.length; } /// @@ -335,6 +327,24 @@ if (is(typeof(hasher(T.init)) == size_t)) assert(set.length == 1); } + /** + * Tells whether the container contains any elements. + * + * Returns: Whether the container is empty. + */ + @property bool empty() const + { + return length == 0; + } + + /** + * Removes all elements. + */ + void clear() + { + this.data.clear(); + } + /// The maximum number of buckets the container can have. enum size_t maxBucketCount = primes[$ - 1]; @@ -386,20 +396,7 @@ if (is(typeof(hasher(T.init)) == size_t)) */ size_t remove(T value) { - auto bucketPosition = this.data.locateBucket(value); - foreach (ref e; this.data.array[bucketPosition .. $]) - { - if (e == value) // Found. - { - e.remove(); - return 1; - } - else if (e.status == BucketStatus.empty) - { - break; - } - } - return 0; + return this.data.remove(value); } /// @@ -427,19 +424,7 @@ if (is(typeof(hasher(T.init)) == size_t)) */ bool opBinaryRight(string op : "in")(auto ref const T value) const { - auto bucketPosition = this.data.locateBucket(value); - foreach (ref e; this.data.array[bucketPosition .. $]) - { - if (e == value) // Found. - { - return true; - } - else if (e.status == BucketStatus.empty) - { - break; - } - } - return false; + return this.data.find(value); } ///