-
-
Notifications
You must be signed in to change notification settings - Fork 411
[WIP] Fixes needed for the _d_arrayappend{T,cTX} dmd PR #2718
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,7 +40,7 @@ template _d_arrayappendcTXImpl(Tarr : T[], T) | |
| mixin(_d_arrayappendcTXBody); | ||
| } | ||
| else | ||
| ref Tarr _d_arrayappendcTX(return scope ref Tarr px, size_t n) @trusted pure nothrow | ||
| ref Tarr _d_arrayappendcTX(return scope ref Tarr px, size_t n) @trusted pure | ||
| { | ||
| pragma(inline, false); | ||
|
|
||
|
|
@@ -109,19 +109,27 @@ template _d_arrayappendTImpl(Tarr : T[], T) | |
| } | ||
|
|
||
| private enum _d_arrayappendTBody = q{ | ||
| import core.stdc.string : memcpy; | ||
| import core.internal.traits : Unqual; | ||
| version (D_TypeInfo) | ||
| { | ||
| import core.stdc.string : memcpy; | ||
| import core.internal.traits : Unqual; | ||
|
|
||
| auto length = x.length; | ||
| auto sizeelem = T.sizeof; | ||
| auto length = x.length; | ||
| auto sizeelem = T.sizeof; | ||
|
|
||
| _d_arrayappendcTXImpl!Tarr._d_arrayappendcTX(x, y.length); | ||
| if (_d_arrayappendcTXImpl!Tarr._d_arrayappendcTX(x, y.length) is null) | ||
| assert(0); | ||
|
|
||
| if (y.length) | ||
| memcpy(cast(Unqual!T *)&x[length], cast(Unqual!T *)&y[0], y.length * sizeelem); | ||
|
|
||
| // do postblit | ||
| __doPostblit(cast(Unqual!Tarr)x[length .. length + y.length]); | ||
| if (y.length) | ||
| memcpy(cast(Unqual!T *)&x[length], cast(Unqual!T *)&y[0], y.length * sizeelem); | ||
|
|
||
| // do postblit | ||
| if (__doPostblit(cast(Unqual!Tarr)x[length .. length + y.length]) is null) | ||
| assert(0); | ||
| } | ||
| else | ||
| assert(0, "Cannot append arrays if compiling without support for runtime type information!"); | ||
| return x; | ||
| }; | ||
|
|
||
|
|
@@ -139,7 +147,7 @@ template _d_arrayappendTImpl(Tarr : T[], T) | |
| * Run postblit on `t` if it is a struct and needs it. | ||
| * Or if `t` is a array, run it on the children if they have a postblit. | ||
| */ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the return type is changing, I recommend updating the DDoc comment to include a |
||
| private void __doPostblit(T)(auto ref T t) @trusted pure | ||
| private auto __doPostblit(T)(auto ref T t) @trusted pure | ||
| { | ||
| import core.internal.traits : hasElaborateCopyConstructor; | ||
|
|
||
|
|
@@ -149,14 +157,26 @@ private void __doPostblit(T)(auto ref T t) @trusted pure | |
| static if (__traits(hasMember, T, "__xpostblit") && | ||
| // Bugzilla 14746: Check that it's the exact member of S. | ||
| __traits(isSame, T, __traits(parent, t.__xpostblit))) | ||
| t.__xpostblit(); | ||
| { | ||
| import core.internal.array.utils : isPure; | ||
| static if (isPure!(t.__xpostblit)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be |
||
| t.__xpostblit(); | ||
| else | ||
| (cast(void delegate() pure)&t.__xpostblit)(); | ||
| return &t; | ||
| } | ||
| } | ||
| else static if (is(T U : U[]) && hasElaborateCopyConstructor!U) | ||
| else static if (is(T U : U[])) | ||
| { | ||
| // only do a postblit if the `U` requires it. | ||
| foreach (ref el; t) | ||
| __doPostblit(el); | ||
| static if (hasElaborateCopyConstructor!U) | ||
| foreach (ref el; t) | ||
| __doPostblit(el); | ||
|
|
||
| return t; | ||
| } | ||
| else | ||
| static assert(0, "No idea how to postblit " ~ typeof(t).stringof); | ||
| } | ||
|
|
||
| @safe unittest | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ | |
| */ | ||
| module core.internal.array.utils; | ||
|
|
||
| import core.internal.traits : Parameters; | ||
| import core.internal.traits : Parameters, hasElaborateCopyConstructor; | ||
|
|
||
| private auto gcStatsPure() nothrow pure | ||
| { | ||
|
|
@@ -93,7 +93,7 @@ auto _d_HookTraceImpl(T, alias Hook, string errorMessage)(string file, int line, | |
| } | ||
|
|
||
| /** | ||
| * Check if the function `F` is calleable in a `nothrow` scope. | ||
| * Check if the function `F` is callable in a `nothrow` scope. | ||
| * Params: | ||
| * F = Function that does not take any parameters | ||
| * Returns: | ||
|
|
@@ -102,7 +102,16 @@ auto _d_HookTraceImpl(T, alias Hook, string errorMessage)(string file, int line, | |
| enum isNoThrow(alias F) = is(typeof(() nothrow { F(); })); | ||
|
|
||
| /** | ||
| * Check if the type `T`'s postblit is called in nothrow, if it exist | ||
| * Check if the function `F` is callable in a `pure` scope. | ||
| * Params: | ||
| * F = Function that does not take any parameters | ||
| * Returns: | ||
| * if the function is callable in a `pure` scope. | ||
| */ | ||
| enum isPure(alias F) = is(typeof(() pure { F(); })); | ||
|
|
||
| /** | ||
| * Check if the type `T`'s postblit is called in a `nothrow` scope, if it exist | ||
| * Params: | ||
| * T = Type to check | ||
| * Returns: | ||
|
|
@@ -112,10 +121,39 @@ enum isNoThrow(alias F) = is(typeof(() nothrow { F(); })); | |
| template isPostblitNoThrow(T) { | ||
| static if (__traits(isStaticArray, T)) | ||
| enum isPostblitNoThrow = isPostblitNoThrow!(typeof(T.init[0])); | ||
| else static if (__traits(hasMember, T, "__xpostblit") && | ||
| // Bugzilla 14746: Check that it's the exact member of S. | ||
| __traits(isSame, T, __traits(parent, T.init.__xpostblit))) | ||
| enum isPostblitNoThrow = isNoThrow!(T.init.__xpostblit); | ||
| else static if (is(T == struct) && hasElaborateCopyConstructor!T) | ||
| { | ||
| static if (__traits(hasMember, T, "__xpostblit") && | ||
| // Bugzilla 14746: Check that it's the exact member of S. | ||
| __traits(isSame, T, __traits(parent, T.init.__xpostblit))) | ||
| enum isPostblitNoThrow = isNoThrow!(T.init.__xpostblit); | ||
| else | ||
| enum isPostblitNoThrow = true; | ||
| } | ||
| else | ||
| enum isPostblitNoThrow = true; | ||
| }; | ||
|
|
||
| /** | ||
| * Check if the type `T`'s postblit is called in a `pure` scope, if it exist | ||
| * Params: | ||
| * T = Type to check | ||
| * Returns: | ||
| * if the postblit is callable in a `pure` scope, if it exist. | ||
| * if it does not exist, return true. | ||
| */ | ||
| template isPostblitPure(T) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curly braces on new line |
||
| static if (__traits(isStaticArray, T)) | ||
| enum isPostblitPure = isPostblitPure!(typeof(T.init[0])); | ||
| else static if (is(T == struct) && hasElaborateCopyConstructor!T) | ||
| { | ||
| static if (__traits(hasMember, T, "__xpostblit") && | ||
| // Bugzilla 14746: Check that it's the exact member of S. | ||
| __traits(isSame, T, __traits(parent, T.init.__xpostblit))) | ||
| enum isPostblitPure = isPure!(T.init.__xpostblit); | ||
| else | ||
| enum isPostblitNoThrow = true; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
| else | ||
| enum isPostblitPure = true; | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Under what condition would
_d_arrayappendcTxImplreturnnull?