1/**
2 This module contains implementations for destroying instances of types
3
4  Copyright: Copyright Digital Mars 2000 - 2019.
5  License: Distributed under the
6       $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
7     (See accompanying file LICENSE)
8  Source: $(DRUNTIMESRC core/_internal/_destruction.d)
9*/
10module core.internal.destruction;
11
12// compiler frontend lowers dynamic array deconstruction to this
13void __ArrayDtor(T)(scope T[] a)
14{
15    foreach_reverse (ref T e; a)
16        e.__xdtor();
17}
18
19public void destructRecurse(E, size_t n)(ref E[n] arr)
20{
21    import core.internal.traits : hasElaborateDestructor;
22
23    static if (hasElaborateDestructor!E)
24    {
25        foreach_reverse (ref elem; arr)
26            destructRecurse(elem);
27    }
28}
29
30public void destructRecurse(S)(ref S s)
31    if (is(S == struct))
32{
33    static if (__traits(hasMember, S, "__xdtor") &&
34            // Bugzilla 14746: Check that it's the exact member of S.
35            __traits(isSame, S, __traits(parent, s.__xdtor)))
36        s.__xdtor();
37}
38
39// Test static struct
40nothrow @safe @nogc unittest
41{
42    static int i = 0;
43    static struct S { ~this() nothrow @safe @nogc { i = 42; } }
44    S s;
45    destructRecurse(s);
46    assert(i == 42);
47}
48