mirror of
https://review.haiku-os.org/buildtools
synced 2025-02-12 00:37:41 +01:00
Updated dependencies: * GMP 6.2.1 * ISL 0.24 * MPL 1.2.1 * MPFR 4.1.0 The dependencies were pulled in by running the ./contrib/download_prerequisites script and then manually removing the symbolic links and archives, and renaming the directories (i.e mv isl-0.24 to isl)
275 lines
6.0 KiB
D
275 lines
6.0 KiB
D
/**
|
|
This module contains support for D's postblit feature
|
|
|
|
Copyright: Copyright Digital Mars 2000 - 2019.
|
|
License: Distributed under the
|
|
$(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
|
|
(See accompanying file LICENSE)
|
|
Source: $(DRUNTIMESRC core/_internal/_destruction.d)
|
|
*/
|
|
module core.internal.postblit;
|
|
|
|
// compiler frontend lowers struct array postblitting to this
|
|
void __ArrayPostblit(T)(T[] a)
|
|
{
|
|
foreach (ref T e; a)
|
|
e.__xpostblit();
|
|
}
|
|
|
|
package void postblitRecurse(S)(ref S s)
|
|
if (is(S == struct))
|
|
{
|
|
static if (__traits(hasMember, S, "__xpostblit") &&
|
|
// Bugzilla 14746: Check that it's the exact member of S.
|
|
__traits(isSame, S, __traits(parent, s.__xpostblit)))
|
|
s.__xpostblit();
|
|
}
|
|
|
|
package void postblitRecurse(E, size_t n)(ref E[n] arr)
|
|
{
|
|
import core.internal.destruction: destructRecurse;
|
|
import core.internal.traits : hasElaborateCopyConstructor;
|
|
|
|
static if (hasElaborateCopyConstructor!E)
|
|
{
|
|
size_t i;
|
|
scope(failure)
|
|
{
|
|
for (; i != 0; --i)
|
|
{
|
|
destructRecurse(arr[i - 1]); // What to do if this throws?
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < arr.length; ++i)
|
|
postblitRecurse(arr[i]);
|
|
}
|
|
}
|
|
|
|
// Test destruction/postblit order
|
|
@safe nothrow pure unittest
|
|
{
|
|
string[] order;
|
|
|
|
struct InnerTop
|
|
{
|
|
~this() @safe nothrow pure
|
|
{
|
|
order ~= "destroy inner top";
|
|
}
|
|
|
|
this(this) @safe nothrow pure
|
|
{
|
|
order ~= "copy inner top";
|
|
}
|
|
}
|
|
|
|
struct InnerMiddle {}
|
|
|
|
version (none) // https://issues.dlang.org/show_bug.cgi?id=14242
|
|
struct InnerElement
|
|
{
|
|
static char counter = '1';
|
|
|
|
~this() @safe nothrow pure
|
|
{
|
|
order ~= "destroy inner element #" ~ counter++;
|
|
}
|
|
|
|
this(this) @safe nothrow pure
|
|
{
|
|
order ~= "copy inner element #" ~ counter++;
|
|
}
|
|
}
|
|
|
|
struct InnerBottom
|
|
{
|
|
~this() @safe nothrow pure
|
|
{
|
|
order ~= "destroy inner bottom";
|
|
}
|
|
|
|
this(this) @safe nothrow pure
|
|
{
|
|
order ~= "copy inner bottom";
|
|
}
|
|
}
|
|
|
|
struct S
|
|
{
|
|
char[] s;
|
|
InnerTop top;
|
|
InnerMiddle middle;
|
|
version (none) InnerElement[3] array; // https://issues.dlang.org/show_bug.cgi?id=14242
|
|
int a;
|
|
InnerBottom bottom;
|
|
~this() @safe nothrow pure { order ~= "destroy outer"; }
|
|
this(this) @safe nothrow pure { order ~= "copy outer"; }
|
|
}
|
|
|
|
string[] destructRecurseOrder;
|
|
{
|
|
import core.internal.destruction: destructRecurse;
|
|
|
|
S s;
|
|
destructRecurse(s);
|
|
destructRecurseOrder = order;
|
|
order = null;
|
|
}
|
|
|
|
assert(order.length);
|
|
assert(destructRecurseOrder == order);
|
|
order = null;
|
|
|
|
S s;
|
|
postblitRecurse(s);
|
|
assert(order.length);
|
|
auto postblitRecurseOrder = order;
|
|
order = null;
|
|
S s2 = s;
|
|
assert(order.length);
|
|
assert(postblitRecurseOrder == order);
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
// Bugzilla 14746
|
|
static struct HasPostblit
|
|
{
|
|
this(this) { assert(0); }
|
|
}
|
|
static struct Owner
|
|
{
|
|
HasPostblit* ptr;
|
|
alias ptr this;
|
|
}
|
|
|
|
Owner o;
|
|
assert(o.ptr is null);
|
|
postblitRecurse(o); // must not reach in HasPostblit.__postblit()
|
|
}
|
|
|
|
// Test handling of fixed-length arrays
|
|
// Separate from first test because of https://issues.dlang.org/show_bug.cgi?id=14242
|
|
@safe unittest
|
|
{
|
|
string[] order;
|
|
|
|
struct S
|
|
{
|
|
char id;
|
|
|
|
this(this)
|
|
{
|
|
order ~= "copy #" ~ id;
|
|
}
|
|
|
|
~this()
|
|
{
|
|
order ~= "destroy #" ~ id;
|
|
}
|
|
}
|
|
|
|
string[] destructRecurseOrder;
|
|
{
|
|
import core.internal.destruction: destructRecurse;
|
|
|
|
S[3] arr = [S('1'), S('2'), S('3')];
|
|
destructRecurse(arr);
|
|
destructRecurseOrder = order;
|
|
order = null;
|
|
}
|
|
assert(order.length);
|
|
assert(destructRecurseOrder == order);
|
|
order = null;
|
|
|
|
S[3] arr = [S('1'), S('2'), S('3')];
|
|
postblitRecurse(arr);
|
|
assert(order.length);
|
|
auto postblitRecurseOrder = order;
|
|
order = null;
|
|
|
|
auto arrCopy = arr;
|
|
assert(order.length);
|
|
assert(postblitRecurseOrder == order);
|
|
}
|
|
|
|
// Test handling of failed postblit
|
|
// Not nothrow or @safe because of https://issues.dlang.org/show_bug.cgi?id=14242
|
|
/+ nothrow @safe +/ unittest
|
|
{
|
|
static class FailedPostblitException : Exception { this() nothrow @safe { super(null); } }
|
|
static string[] order;
|
|
static struct Inner
|
|
{
|
|
char id;
|
|
|
|
@safe:
|
|
this(this)
|
|
{
|
|
order ~= "copy inner #" ~ id;
|
|
if (id == '2')
|
|
throw new FailedPostblitException();
|
|
}
|
|
|
|
~this() nothrow
|
|
{
|
|
order ~= "destroy inner #" ~ id;
|
|
}
|
|
}
|
|
|
|
static struct Outer
|
|
{
|
|
Inner inner1, inner2, inner3;
|
|
|
|
nothrow @safe:
|
|
this(char first, char second, char third)
|
|
{
|
|
inner1 = Inner(first);
|
|
inner2 = Inner(second);
|
|
inner3 = Inner(third);
|
|
}
|
|
|
|
this(this)
|
|
{
|
|
order ~= "copy outer";
|
|
}
|
|
|
|
~this()
|
|
{
|
|
order ~= "destroy outer";
|
|
}
|
|
}
|
|
|
|
auto outer = Outer('1', '2', '3');
|
|
|
|
try postblitRecurse(outer);
|
|
catch (FailedPostblitException) {}
|
|
catch (Exception) assert(false);
|
|
|
|
auto postblitRecurseOrder = order;
|
|
order = null;
|
|
|
|
try auto copy = outer;
|
|
catch (FailedPostblitException) {}
|
|
catch (Exception) assert(false);
|
|
|
|
assert(postblitRecurseOrder == order);
|
|
order = null;
|
|
|
|
Outer[3] arr = [Outer('1', '1', '1'), Outer('1', '2', '3'), Outer('3', '3', '3')];
|
|
|
|
try postblitRecurse(arr);
|
|
catch (FailedPostblitException) {}
|
|
catch (Exception) assert(false);
|
|
|
|
postblitRecurseOrder = order;
|
|
order = null;
|
|
|
|
try auto arrCopy = arr;
|
|
catch (FailedPostblitException) {}
|
|
catch (Exception) assert(false);
|
|
|
|
assert(postblitRecurseOrder == order);
|
|
}
|