diff options
| author | Eugen Wissner <belka@caraus.de> | 2018-10-29 11:14:33 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2018-10-29 11:14:33 +0100 |
| commit | 1e46109e50d9b283eaead24aa13fb5216f18866d (patch) | |
| tree | 2824c8f29141a350e7c335e162af391d2fe2d578 /source | |
| parent | 64ceb0330cb89147fbe4d94902ce3ea2072a209a (diff) | |
| download | tanya-1e46109e50d9b283eaead24aa13fb5216f18866d.tar.gz | |
algorithm.mutation.destroyAll: Newv0.13.0
Fix #71.
Diffstat (limited to 'source')
| -rw-r--r-- | source/tanya/algorithm/mutation.d | 46 | ||||
| -rw-r--r-- | source/tanya/container/array.d | 20 | ||||
| -rw-r--r-- | source/tanya/memory/package.d | 8 |
3 files changed, 53 insertions, 21 deletions
diff --git a/source/tanya/algorithm/mutation.d b/source/tanya/algorithm/mutation.d index 49539d1..99ba239 100644 --- a/source/tanya/algorithm/mutation.d +++ b/source/tanya/algorithm/mutation.d @@ -561,3 +561,49 @@ if (isInputRange!Range && hasLvalueElements!Range) NonCopyable[] nonCopyable; initializeAll(nonCopyable); } + +/** + * Destroys all elements in the $(D_PARAM range). + * + * This function has effect only if the element type of $(D_PARAM Range) has + * an elaborate destructor, i.e. it is a $(D_PSYMBOL struct) with an explicit + * or generated by the compiler destructor. + * + * Params: + * Range = Input range type. + * range = Input range. + */ +void destroyAll(Range)(Range range) +if (isInputRange!Range && hasLvalueElements!Range) +{ + static if (hasElaborateDestructor!(ElementType!Range)) + { + foreach (ref e; range) + { + destroy(e); + } + } +} + +/// +@nogc nothrow pure @trusted unittest +{ + static struct WithDtor + { + private size_t* counter; + ~this() @nogc nothrow pure + { + if (this.counter !is null) + { + ++(*this.counter); + } + } + } + + size_t counter; + WithDtor[2] withDtor = [WithDtor(&counter), WithDtor(&counter)]; + + destroyAll(withDtor[]); + + assert(counter == 2); +} diff --git a/source/tanya/container/array.d b/source/tanya/container/array.d index 57ea482..e0556dd 100644 --- a/source/tanya/container/array.d +++ b/source/tanya/container/array.d @@ -414,27 +414,19 @@ struct Array(T) */ @property void length(size_t len) @trusted { - if (len == length) - { - return; - } - else if (len > length) + if (len > length) { reserve(len); initializeAll(this.data[length_ .. len]); } else { - static if (hasElaborateDestructor!T) - { - const T* end = this.data + length_ - 1; - for (T* e = this.data + len; e != end; ++e) - { - destroy(*e); - } - } + destroyAll(this.data[len .. this.length_]); + } + if (len != length) + { + length_ = len; } - length_ = len; } /// diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d index f0a1c0d..77dc388 100644 --- a/source/tanya/memory/package.d +++ b/source/tanya/memory/package.d @@ -341,13 +341,7 @@ if (isPolymorphicType!T) package(tanya) void[] finalize(T)(ref T[] p) { - static if (hasElaborateDestructor!(typeof(p[0]))) - { - foreach (ref e; p) - { - destroy(e); - } - } + destroyAll(p); return p; } |
