Skip to content

Commit

Permalink
Fix _postblitRecurse for structs with private fields
Browse files Browse the repository at this point in the history
Fixup for dlang#1181
  • Loading branch information
Jakob Ovrum committed Apr 30, 2015
1 parent 0f4f326 commit 8e62860
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 49 deletions.
38 changes: 38 additions & 0 deletions src/core/internal/convert.d
Original file line number Diff line number Diff line change
Expand Up @@ -633,3 +633,41 @@ const(ubyte)[] toUbyte(T)(ref T val) if (is(T == struct) || is(T == union))
return (cast(const(ubyte)*)&val)[0 .. T.sizeof];
}
}

char[] itoa(ulong n) pure nothrow @safe
{
if (n == 0)
return ['0'];

char[20] buffer;
size_t length = 0;

while (n != 0)
{
uint rem = n % 10;
buffer[length++] = cast(char)(rem + '0');
n /= 10;
}

for (size_t i = 0; i < length / 2; ++i)
{
char c = buffer[i];
buffer[i] = buffer[length - i - 1];
buffer[length - i - 1] = c;
}

return buffer[0 .. length].dup;
}

pure nothrow @safe unittest
{
static assert(itoa(0) == "0");
static assert(itoa(3) == "3");
static assert(itoa(42) == "42");
static assert(itoa(ulong.max) == "18446744073709551615");

assert(itoa(0) == "0");
assert(itoa(3) == "3");
assert(itoa(42) == "42");
assert(itoa(ulong.max) == "18446744073709551615");
}
37 changes: 0 additions & 37 deletions src/core/internal/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -155,40 +155,3 @@ template hasElaborateCopyConstructor(T...)
else
enum bool hasElaborateCopyConstructor = false;
}

template staticMap(alias F, T...)
{
static if (T.length == 0)
{
alias staticMap = TypeTuple!();
}
else static if (T.length == 1)
{
alias staticMap = TypeTuple!(F!(T[0]));
}
else
{
alias staticMap =
TypeTuple!(
staticMap!(F, T[ 0 .. $/2]),
staticMap!(F, T[$/2 .. $ ]));
}
}

template isNested(T)
if(is(T == class) || is(T == struct) || is(T == union))
{
enum isNested = __traits(isNested, T);
}

private enum NameOf(alias T) = T.stringof;

template FieldNameTuple(T)
{
static if (is(T == struct) || is(T == union))
alias FieldNameTuple = staticMap!(NameOf, T.tupleof[0 .. $ - isNested!T]);
else static if (is(T == class))
alias FieldNameTuple = staticMap!(NameOf, T.tupleof);
else
alias FieldNameTuple = TypeTuple!"";
}
12 changes: 6 additions & 6 deletions src/object.di
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ private void _destructRecurse(S)(ref S s)
static if (__traits(hasMember, S, "__dtor"))
s.__dtor();

foreach_reverse (i, ref field; s.tupleof)
foreach_reverse (ref field; s.tupleof)
{
static if (hasElaborateDestructor!(typeof(field)))
_destructRecurse(field);
Expand All @@ -632,17 +632,17 @@ private void _destructRecurse(E, size_t n)(ref E[n] arr)

private string _genFieldPostblit(S)()
{
import core.internal.convert : itoa;
import core.internal.traits : hasElaborateCopyConstructor;
import core.internal.traits : FieldNameTuple;

string code;
foreach(fieldName; FieldNameTuple!S)
foreach(i, FieldType; typeof(S.init.tupleof))
{
static if(hasElaborateCopyConstructor!(typeof(__traits(getMember, S.init, fieldName))))
static if(hasElaborateCopyConstructor!FieldType)
{
code ~= `
_postblitRecurse(s.` ~ fieldName ~ `);
scope(failure) _destructRecurse(s. ` ~ fieldName ~ `);
_postblitRecurse(s.tupleof[` ~ itoa(i) ~ `]);
scope(failure) _destructRecurse(s.tupleof[` ~ itoa(i) ~ `]);
`;
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/object_.d
Original file line number Diff line number Diff line change
Expand Up @@ -2502,7 +2502,7 @@ private void _destructRecurse(S)(ref S s)
static if (__traits(hasMember, S, "__dtor"))
s.__dtor();

foreach_reverse (i, ref field; s.tupleof)
foreach_reverse (ref field; s.tupleof)
{
static if (hasElaborateDestructor!(typeof(field)))
_destructRecurse(field);
Expand All @@ -2522,17 +2522,17 @@ private void _destructRecurse(E, size_t n)(ref E[n] arr)

private string _genFieldPostblit(S)()
{
import core.internal.convert : itoa;
import core.internal.traits : hasElaborateCopyConstructor;
import core.internal.traits : FieldNameTuple;

string code;
foreach(fieldName; FieldNameTuple!S)
foreach(i, FieldType; typeof(S.init.tupleof))
{
static if(hasElaborateCopyConstructor!(typeof(__traits(getMember, S.init, fieldName))))
static if(hasElaborateCopyConstructor!FieldType)
{
code ~= `
_postblitRecurse(s.` ~ fieldName ~ `);
scope(failure) _destructRecurse(s. ` ~ fieldName ~ `);
_postblitRecurse(s.tupleof[` ~ itoa(i) ~ `]);
scope(failure) _destructRecurse(s.tupleof[` ~ itoa(i) ~ `]);
`;
}
}
Expand Down

0 comments on commit 8e62860

Please sign in to comment.