summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2018-10-29 11:14:33 +0100
committerEugen Wissner <belka@caraus.de>2018-10-29 11:14:33 +0100
commit1e46109e50d9b283eaead24aa13fb5216f18866d (patch)
tree2824c8f29141a350e7c335e162af391d2fe2d578
parent64ceb0330cb89147fbe4d94902ce3ea2072a209a (diff)
downloadtanya-1e46109e50d9b283eaead24aa13fb5216f18866d.tar.gz
algorithm.mutation.destroyAll: Newv0.13.0
Fix #71.
-rw-r--r--source/tanya/algorithm/mutation.d46
-rw-r--r--source/tanya/container/array.d20
-rw-r--r--source/tanya/memory/package.d8
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;
}