Re: Why does std.container.array does not work with foraech( i, a; array ) {} ?

2016-05-29 Thread ParticlePeter via Digitalmars-d-learn

On Sunday, 29 May 2016 at 09:07:07 UTC, Jonathan M Davis wrote:
On Sunday, May 29, 2016 07:14:12 ParticlePeter via 
Digitalmars-d-learn wrote:
Which of the op(Index) operators is responsible for enabling 
this

kind of syntax?
Would it be possible to get it work with UFCS or would I have 
to

wrap the array?


std.container.array.Array works with foreach via ranges.

foreach(e; myContainer)
{
}

gets lowered to

foreach(e; myContainer[])
{
}

which in turn gets lowered to something like

for(auto r = myContainer[]; !r.empty; r.popFront())
{
auto e = r.front;
}

Ranges do not support indices with foreach, and that's why 
you're not able to get the index with foreach and Array. 
However, if you use std.range.lockstep, you can wrap a range to 
get indices with foreach. e.g.


foreach(i, e; lockstep(myContainer[]))
{
}

http://dlang.org/phobos/std_range.html#.lockstep

- Jonathan M Davis



Thanks, due to your answer I found a way which is even better for 
me. I pimped the Array containers with some UFCS functions 
anyway, one of them returns the array data as a slice and this 
works nicely with that foreach variant as well


auto data( T )( Array!T array )  {
if( array.length == 0 ) return null;
return (&array.front())[ 0..array.length ];
}

// this works now
foreach( i, a; someArrayContainer.data ) { ... }

- PP


Re: Why does std.container.array does not work with foraech( i, a; array ) {} ?

2016-05-29 Thread Mithun Hunsur via Digitalmars-d-learn

On Sunday, 29 May 2016 at 09:07:07 UTC, Jonathan M Davis wrote:
On Sunday, May 29, 2016 07:14:12 ParticlePeter via 
Digitalmars-d-learn wrote:

[...]


std.container.array.Array works with foreach via ranges.

foreach(e; myContainer)
{
}

gets lowered to

foreach(e; myContainer[])
{
}

which in turn gets lowered to something like

for(auto r = myContainer[]; !r.empty; r.popFront())
{
auto e = r.front;
}

Ranges do not support indices with foreach, and that's why 
you're not able to get the index with foreach and Array. 
However, if you use std.range.lockstep, you can wrap a range to 
get indices with foreach. e.g.


foreach(i, e; lockstep(myContainer[]))
{
}

http://dlang.org/phobos/std_range.html#.lockstep

- Jonathan M Davis


I'd say that std.range.enumerate is more indicative of intent:

http://dlang.org/phobos/std_range.html#enumerate


Re: Why does std.container.array does not work with foraech( i, a; array ) {} ?

2016-05-29 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 29, 2016 07:14:12 ParticlePeter via Digitalmars-d-learn wrote:
> Which of the op(Index) operators is responsible for enabling this
> kind of syntax?
> Would it be possible to get it work with UFCS or would I have to
> wrap the array?

std.container.array.Array works with foreach via ranges.

foreach(e; myContainer)
{
}

gets lowered to

foreach(e; myContainer[])
{
}

which in turn gets lowered to something like

for(auto r = myContainer[]; !r.empty; r.popFront())
{
auto e = r.front;
}

Ranges do not support indices with foreach, and that's why you're not able
to get the index with foreach and Array. However, if you use
std.range.lockstep, you can wrap a range to get indices with foreach. e.g.

foreach(i, e; lockstep(myContainer[]))
{
}

http://dlang.org/phobos/std_range.html#.lockstep

- Jonathan M Davis