Overload for static arrays for std.array.array#6214
Overload for static arrays for std.array.array#6214dukc wants to merge 2 commits intodlang:masterfrom
Conversation
|
Thanks for your pull request and interest in making D better, @dukc! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. |
|
@andralex opinion needed because this is a new symbol overload. |
andralex
left a comment
There was a problem hiding this comment.
We should be able to transport the information about how many elements were filled, should client code need it. I'm thinking of an overload with out size_t as the last parameter.
std/array.d
Outdated
| size_t i; | ||
| foreach (e; r) | ||
| { | ||
|
|
There was a problem hiding this comment.
I copied that comment from regular .array. I think emplaceRef calls memCpy.
std/array.d
Outdated
| /** | ||
| * Returns a static array from the stack with length of s and initializes | ||
| * it with copies of the elements of range $(D r). The remainder of the | ||
| * array is default-initialized. |
There was a problem hiding this comment.
What happens if the range is longer than s?
There was a problem hiding this comment.
A standard overflow. But i think you meant that I add that in comment.
| * Returns a static array from the stack with length of s and initializes | ||
| * it with copies of the elements of range $(D r). The remainder of the | ||
| * array is default-initialized. | ||
| * |
There was a problem hiding this comment.
The documentation should add that this is recommended particularly for nontrivial initialization of static arrays during compilation.
std/array.d
Outdated
| } | ||
|
|
||
| /** | ||
| * Returns a static array from the stack with length of s and initializes |
| * An initialized static array | ||
| */ | ||
| ForeachType!Range[s] array(size_t s, Range)(Range r) | ||
| if (isInputRange!Range && !isInfinite!Range) |
There was a problem hiding this comment.
You don't care whether the range is finite - you take a finite subset anyway.
There was a problem hiding this comment.
That's if I change it to check that. Now it goes unchecked so passing an infinite range is definitely wrong.
|
This somewhat overlaps with #6178 |
|
Yea, I should probably look around before starting doing. EDIT: even closer is #4090, but it was dismissed by Andrei because it (or this) could be used to initialize a dynamic array and then return it out of function. So this should be dismissed too... ...except that we now have -dip1000 which stops that, if used. but the switch is still not the default... you decide. |
…rrays in UFCS style.
01b9885 to
6d7ad05
Compare
|
DIP1000 in Phobos has been "just around the corner" for over a year now. If the same safety issues are present in this implementation, I would close this. |
|
Well, we have Andrei around so I'll let him do it if he agrees with that. |
|
@andralex Review addressed and the overload you requested has been added. On the other hand, check last three comments above this before merging. |
std/array.d
Outdated
| * Params: | ||
| * r = The range (or aggregate with $(D opApply) function) whose elements | ||
| * are copied into the stack-allocated array. Must be as long or shorter | ||
| * than `s`, otherwise causes an array overflow. |
There was a problem hiding this comment.
Please no overflow. It's trivial and low cost to have a test here. In case of overflow, just fill the array and place the real length in rangeLength.
There was a problem hiding this comment.
Take would be easy to add if the user wants it, but not to remove, so this makes it more-than-zero cost abstraction.
On the other hand, we can always add a non-checking equivalent later so I tend to agree with this. Regardless, I'll do it.
std/array.d
Outdated
| import std.conv : emplaceRef; | ||
| import std.algorithm.mutation : uninitializedFill; | ||
|
|
||
| rangeLength = 0; |
There was a problem hiding this comment.
out parameters are always zero-initialized
std/array.d
Outdated
| Unqual!E[s] result; | ||
| foreach (e; r) | ||
| { | ||
|
|
There was a problem hiding this comment.
Please no spurious empty lines. This particular one separates nothing in particular and adds negative readability value.
std/array.d
Outdated
| }()); | ||
|
|
||
|
|
||
| foreach (e; r) |
There was a problem hiding this comment.
This makes a copy for each element in the range.
std/array.d
Outdated
| foreach (e; r) | ||
| { | ||
| emplaceRef!E(result[rangeLength], e); | ||
| rangeLength++; |
There was a problem hiding this comment.
Incrementing via pointer is slow, please use a local value and assign rangeLength at end
|
@andralex All done now. Also extended the first unittest a bit. |
|
I think we need to choose this, #6178, or a careful combination, but not both. Thoughts? |
|
It seems Cour already stated his opinion at #6178 so I decided it's a better place for discussion. See my answer there. |
|
Not needed anymore as #6178 appears to be getting in. |
With static arrays,
autokeyword has been hard to use so far. This changes today!