Thread overview
error when std.range.Cycle of static array is a member
Jul 24, 2011
Lutger Blijdestijn
Jul 24, 2011
Jonathan M Davis
Jul 24, 2011
Lutger Blijdestijn
Jul 27, 2011
Lutger Blijdestijn
July 24, 2011
I'm trying to have a Cycle range of a static array as a struct member, but getting a compilation error. Can anybody tell me if I'm doing something wrong, or is this a bug?

import std.range;

struct Foo
{
    ubyte[] buf;
    Cycle!(typeof(buf)) cbuf1; // ok

    ubyte[1024] staticBuf;
    Cycle!(typeof(staticBuf)) cbuf2; // error

    void test()
    {
        Cycle!(typeof(staticBuf)) cbuf3;
        cbuf3 = cycle(staticBuf); // ok
    }
}

/std/range.d(228): Error: template instance std.array.front!(ubyte[1024u]) incompatible arguments for template instantiation
July 24, 2011
On Sunday 24 July 2011 12:06:47 Lutger Blijdestijn wrote:
> I'm trying to have a Cycle range of a static array as a struct member, but getting a compilation error. Can anybody tell me if I'm doing something wrong, or is this a bug?
> 
> import std.range;
> 
> struct Foo
> {
>     ubyte[] buf;
>     Cycle!(typeof(buf)) cbuf1; // ok
> 
>     ubyte[1024] staticBuf;
>     Cycle!(typeof(staticBuf)) cbuf2; // error
> 
>     void test()
>     {
>         Cycle!(typeof(staticBuf)) cbuf3;
>         cbuf3 = cycle(staticBuf); // ok
>     }
> }
> 
> /std/range.d(228): Error: template instance std.array.front!(ubyte[1024u])
> incompatible arguments for template instantiation

static arrays are not ranges. You can't pop the front off of them, so no range- based algorithm would work with a static range. Now, you _can_ get a dynamic range over a static range and _that_ is a valid range, so what you need to do is make the Cycle a Cycle!(ubyte[]) rather than Cycle!(ubyte[1024]), and you when you pass the static array to cycle, you need to slice it: cycle(staticBuf[]).

- Jonathan M Davis
July 24, 2011
Jonathan M Davis wrote:

> On Sunday 24 July 2011 12:06:47 Lutger Blijdestijn wrote:
>> I'm trying to have a Cycle range of a static array as a struct member, but getting a compilation error. Can anybody tell me if I'm doing something wrong, or is this a bug?
>> 
>> import std.range;
>> 
>> struct Foo
>> {
>>     ubyte[] buf;
>>     Cycle!(typeof(buf)) cbuf1; // ok
>> 
>>     ubyte[1024] staticBuf;
>>     Cycle!(typeof(staticBuf)) cbuf2; // error
>> 
>>     void test()
>>     {
>>         Cycle!(typeof(staticBuf)) cbuf3;
>>         cbuf3 = cycle(staticBuf); // ok
>>     }
>> }
>> 
>> /std/range.d(228): Error: template instance
>> std.array.front!(ubyte[1024u]) incompatible arguments for template
>> instantiation
> 
> static arrays are not ranges. You can't pop the front off of them, so no range- based algorithm would work with a static range. Now, you _can_ get a dynamic range over a static range and _that_ is a valid range, so what you need to do is make the Cycle a Cycle!(ubyte[]) rather than Cycle!(ubyte[1024]), and you when you pass the static array to cycle, you need to slice it: cycle(staticBuf[]).
> 
> - Jonathan M Davis

That would work, but the docs explicitly mention that Cycle is specialized for static arrays (for performance reasons). This is how cycle is implemented:

Cycle!(R) cycle(R)(ref R input, size_t index = 0) if (isStaticArray!R)
{
    return Cycle!(R)(input, index);
}
July 25, 2011
On Sun, 24 Jul 2011 10:51:32 -0400, Lutger Blijdestijn <lutger.blijdestijn@gmail.com> wrote:

> Jonathan M Davis wrote:
>
>> On Sunday 24 July 2011 12:06:47 Lutger Blijdestijn wrote:
>>> I'm trying to have a Cycle range of a static array as a struct member,
>>> but getting a compilation error. Can anybody tell me if I'm doing
>>> something wrong, or is this a bug?
>>>
>>> import std.range;
>>>
>>> struct Foo
>>> {
>>>     ubyte[] buf;
>>>     Cycle!(typeof(buf)) cbuf1; // ok
>>>
>>>     ubyte[1024] staticBuf;
>>>     Cycle!(typeof(staticBuf)) cbuf2; // error
>>>
>>>     void test()
>>>     {
>>>         Cycle!(typeof(staticBuf)) cbuf3;
>>>         cbuf3 = cycle(staticBuf); // ok
>>>     }
>>> }
>>>
>>> /std/range.d(228): Error: template instance
>>> std.array.front!(ubyte[1024u]) incompatible arguments for template
>>> instantiation
>>
>> static arrays are not ranges. You can't pop the front off of them, so no
>> range- based algorithm would work with a static range. Now, you _can_ get
>> a dynamic range over a static range and _that_ is a valid range, so what
>> you need to do is make the Cycle a Cycle!(ubyte[]) rather than
>> Cycle!(ubyte[1024]), and you when you pass the static array to cycle, you
>> need to slice it: cycle(staticBuf[]).
>>
>> - Jonathan M Davis
>
> That would work, but the docs explicitly mention that Cycle is specialized
> for static arrays (for performance reasons). This is how cycle is
> implemented:
>
> Cycle!(R) cycle(R)(ref R input, size_t index = 0) if (isStaticArray!R)
> {
>     return Cycle!(R)(input, index);
> }

This is definitely a bug.  In fact, it's a regression, since it passes on 2.051 (fails on 2.052 and later).  The error is occurring during the execution of the *template constraint*.

Reduced case:

import std.range;

pragma(msg, isInputRange!(ubyte[2u]).stringof);

If it's not a bug in dmd (or rather it's the result of a fixed bug), then it's a bug in Phobos' isInputRange implementation.  However, I doubt that.  Also, the same line works in the context of a function:

import std.range;

void main()
{
   pragma(msg, isInputRange!(ubyte[2u]).stringof); // no error
}

Please file a 'rejects-valid' bug.

-Steve
July 26, 2011
On Mon, 25 Jul 2011 11:25:17 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:


> Please file a 'rejects-valid' bug.

http://d.puremagic.com/issues/show_bug.cgi?id=6385
July 27, 2011
Steven Schveighoffer wrote:

> On Mon, 25 Jul 2011 11:25:17 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> 
> 
>> Please file a 'rejects-valid' bug.
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=6385

Thanks, I'm sorry for slacking, have been a bit busy the last couple of days.