-
-
Notifications
You must be signed in to change notification settings - Fork 700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Issue 16745 - Add template helper for creating static arrays with the size inferred #4936
Conversation
Thanks for your pull request, @John-Colvin! We are looking forward to reviewing it, and you should be hearing from a maintainer soon. Some tips to help speed things up:
Bear in mind that large or tricky changes may require multiple rounds of review and revision. Please see CONTRIBUTING.md for more information. Bugzilla references
|
This has been tried before: #4090, see especially Andrei's closing comment |
I don't know why you're using
should be equivalent. However, regardless of that, I'm pretty sure that your solution doesn't work with VRP thanks to https://issues.dlang.org/show_bug.cgi?id=16779. So, something like auto sa = staticArray!ubyte([1, 2, 3, 4]); wouldn't work, whereas ubyte[4] sa = [1, 2, 3, 4]; does. Also, there's the question of whether it works with runtime variables with the equivalent of
which I think that what you have does do, though you're not testing for it. I think that any solution for this should be
which works with VRP properly, unlike what you have right now. It doesn't have a range overload like what you have now, but that's easily fixed. The bigger problem would be that it doesn't work with what you're proposing with dynamic arrays (which is something that you can do with direct initialization and therefore really should work). And it's not going to work with dynamic arrays without an overload that takes the dynamic array as a function argument rather than a template argument. That being the case,
would be a better solution so long as https://issues.dlang.org/show_bug.cgi?id=16779 gets fixed. |
So, is his big concern then that if you do something like
you have memory problems? I think that a fix for https://issues.dlang.org/show_bug.cgi?id=12625 would fix that problem, because slicing a static array that's an rvalue should always be an error. As such, I don't think that it's worth worrying about as far as adding a function like this to Phobos goes. |
I am using it because in that overload the user can specify a
Correct, that's a pain. Maybe it will get fixed soon?
Added a test for that. I've been experimenting with different designs, but I keep being thwarted by https://issues.dlang.org/show_bug.cgi?id=16957. Seeing as some of the errors in there disappear when not inferring static array length, perhaps it's also linked to vrp problem. |
Hmmm. Well, that seems like it adds a fair bit of extra overhead for a case that does not work with normal static array initialization. The
case works and would work with
that wouldn't. I'm inclined to argue that we should be trying to get |
I absolutely agree here. I think the most common use case is just this: [1, 2, 3].asStatic (for which btw the name
So what's the consensus here? A) Use this PR |
@John-Colvin since this has been open since December of last year without getting merged, and since Andrei closed the previous PR, I'm going to close this one as well. @andralex pleas re-open if you've changed your mind. |
OK, I wasn't being passive-aggressive here, this just slipped. I'll add a few comments within. |
… the size inferred
Ok, no problem. I personally don't normally care much about waiting, although of course "good for the project" and all that... I've rebased to fix the conflicts |
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.
staticArray with a range (including an array) seems to be sufficient. The documentation should dedicate a paragraph to the fact that the result is an rvalue, therefore uses like [1, 2, 3].staticArray.find(x)
may be inefficient.
auto sa4 = staticArray!r; | ||
static assert(sa4.length == 3); | ||
assert(sa4 == [0, 1, 2]); | ||
} |
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.
This strikes me as an obscure feature, and the example doesn't add confidence in the usefulness of the approach. I'd think a CTFE range evaluation should work, i.e. the example above should spell like:
auto sa4 = iota(3).staticArray;
assert(is(typeof(sa4) == int[3]));
assert(sa4 == [0, 1, 2]);
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.
This doesn't work as of now. See also:
https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
* Optionally, a target type can be provided as the first template argument, which will result | ||
* in a static array with that element type. | ||
*/ | ||
T[N] staticArray(size_t N, T)(T[N] a) |
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.
perhaps you could add auto ref
to the parameter
|
||
/// ditto | ||
TargetElemT[N] staticArray(TargetElemT, size_t N, T)(T[N] a) | ||
{ |
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.
add constraint if (is(T : TargetElemT))
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.
and possibly auto ref
to the parameter
|
||
import std.conv : emplaceRef; | ||
foreach (i; 0 .. N) | ||
emplaceRef!TargetElemT(result[i], a[i]); |
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.
If any of these throws, the destructors of the already-constructed elements is not called.
foreach (i; 0 .. N) | ||
emplaceRef!TargetElemT(result[i], a[i]); | ||
|
||
return (() @trusted => cast(TargetElemT[N])result)(); |
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.
I'm not clear why this should be always trusted.
/// | ||
@safe nothrow unittest | ||
{ | ||
auto sa = staticArray([1, 2]); |
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.
Examples should use the preferred notation [1, 2].staticArray
.
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.
To summarize, the changes I'm suggesting are:
- Delete the overload taking an alias
- Add an overload that takes a range and is meant to be evaluated during compilation
- Add documentation explaining the tradeoffs of the rvalue return
@timotheecour has revived this to DRuntime: dlang/druntime#2093 |
No description provided.