Skip to content

Comments

Overload for static arrays for std.array.array#6214

Closed
dukc wants to merge 2 commits intodlang:masterfrom
dukc:arrayForStatic
Closed

Overload for static arrays for std.array.array#6214
dukc wants to merge 2 commits intodlang:masterfrom
dukc:arrayForStatic

Conversation

@dukc
Copy link
Contributor

@dukc dukc commented Feb 23, 2018

With static arrays, auto keyword has been hard to use so far. This changes today!

@dlang-bot
Copy link
Contributor

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 verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the annotated coverage diff directly on GitHub with CodeCov's browser extension
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

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 references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

@dukc
Copy link
Contributor Author

dukc commented Feb 23, 2018

@andralex opinion needed because this is a new symbol overload.

Copy link
Member

@andralex andralex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
{

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the range is longer than s?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s in backquotes

* An initialized static array
*/
ForeachType!Range[s] array(size_t s, Range)(Range r)
if (isInputRange!Range && !isInfinite!Range)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't care whether the range is finite - you take a finite subset anyway.

Copy link
Contributor Author

@dukc dukc Feb 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's if I change it to check that. Now it goes unchecked so passing an infinite range is definitely wrong.

@JackStouffer
Copy link
Contributor

This somewhat overlaps with #6178

@dukc
Copy link
Contributor Author

dukc commented Feb 23, 2018

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.

@dukc dukc force-pushed the arrayForStatic branch 2 times, most recently from 01b9885 to 6d7ad05 Compare February 23, 2018 21:18
@JackStouffer
Copy link
Contributor

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.

@dukc
Copy link
Contributor Author

dukc commented Feb 23, 2018

Well, we have Andrei around so I'll let him do it if he agrees with that.

@dukc
Copy link
Contributor Author

dukc commented Feb 27, 2018

@andralex Review addressed and the overload you requested has been added. On the other hand, check last three comments above this before merging.

Copy link
Member

@andralex andralex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getting there

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out parameters are always zero-initialized

std/array.d Outdated
Unqual!E[s] result;
foreach (e; r)
{

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please no spurious empty lines. This particular one separates nothing in particular and adds negative readability value.

std/array.d Outdated
}());


foreach (e; r)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes a copy for each element in the range.

std/array.d Outdated
foreach (e; r)
{
emplaceRef!E(result[rangeLength], e);
rangeLength++;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incrementing via pointer is slow, please use a local value and assign rangeLength at end

@dukc dukc force-pushed the arrayForStatic branch from e90dd8e to 8667c0a Compare March 5, 2018 10:52
@dukc
Copy link
Contributor Author

dukc commented Mar 5, 2018

@andralex All done now. Also extended the first unittest a bit.

@andralex
Copy link
Member

andralex commented Mar 6, 2018

I think we need to choose this, #6178, or a careful combination, but not both. Thoughts?

@dukc
Copy link
Contributor Author

dukc commented Mar 7, 2018

It seems Cour already stated his opinion at #6178 so I decided it's a better place for discussion. See my answer there.

@dukc
Copy link
Contributor Author

dukc commented Mar 22, 2018

Not needed anymore as #6178 appears to be getting in.

@dukc dukc closed this Mar 22, 2018
@dukc dukc mentioned this pull request May 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants