www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - error when std.range.Cycle of static array is a member

reply Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
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
Jul 24 2011
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Jul 24 2011
parent reply Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
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); }
Jul 24 2011
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Jul 25 2011
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Jul 26 2011
parent Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
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.
Jul 27 2011