Thread overview
opSlice and foreach with ranges
Feb 17, 2011
Ali Çehreli
Feb 17, 2011
Jesse Phillips
Feb 17, 2011
Ali Çehreli
February 17, 2011
Is that not implemented yet?

TDPL mentions a very useful feature on page 381 under "12.9.1 foreach with Iteration Primitives".

(Note: I am copying all of this manually; the typos are mine):

It first shows a function that includes a possible "compiler rewrite" of a foreach loop:

void process(SimpleList!int lst) {
    for (auto __c = lst; !__c.empty; __c.popFront()) {
        auto value = __c.front;
        ... // Use value of type int
    }
}

It then says

<quote>
... if the iterated object offers the slice operator with no arguments lst[], __c is initialized with lst[] instead of lst. This is in order to allow "extracting" the iteration means out of a container without requiring the container to define the three iteration primitives.
</quote>

I couldn't get that to work with the following code:

import std.stdio;

struct MyRange
{
    int theOnlyOne;

    @property bool empty() const
    {
        return false;
    }

    @property ref int front()
    {
        return theOnlyOne;
    }

    void popFront()
    {}
}

struct MyCollection
{
    MyRange opSlice() const
    {
        return MyRange();
    }
}

void main()
{
    auto coll = MyCollection();

    foreach (i; coll) {            // <-- compilation error
        // ...
    }
}

Error: cannot infer type for i

Providing the type of i as 'int' or 'ref int' produce a different error:

    foreach (int i; coll) {

or

    foreach (ref int i; coll) {

produce

Error: no property 'opApply' for type 'MyCollection'

Please note that taking a slice explicitly works:

    foreach (i; coll[]) {

but not the feature mentioned in TDPL.

Thank you,
Ali
February 17, 2011
Ali Çehreli Wrote:

> <quote>
> ... if the iterated object offers the slice operator with no arguments
> lst[], __c is initialized with lst[] instead of lst. This is in order to
> allow "extracting" the iteration means out of a container without
> requiring the container to define the three iteration primitives.
> </quote>

Yeah I don't think it is implemented, file a bug.
February 17, 2011
On 02/17/2011 01:49 PM, Jesse Phillips wrote:
> Ali �ehreli Wrote:
>
>> <quote>
>> ... if the iterated object offers the slice operator with no arguments
>> lst[], __c is initialized with lst[] instead of lst. This is in order to
>> allow "extracting" the iteration means out of a container without
>> requiring the container to define the three iteration primitives.
>> </quote>
>
> Yeah I don't think it is implemented, file a bug.

http://d.puremagic.com/issues/show_bug.cgi?id=5605

Thank you,
Ali