Thread overview
Re: isRandomAccessRange!(const(size_t[])) is false ... ?
Sep 12, 2013
Andrej Mitrovic
Sep 12, 2013
H. S. Teoh
Sep 12, 2013
Jonathan M Davis
Sep 12, 2013
Jonathan M Davis
September 12, 2013
On 9/12/13, Joseph Rushton Wakeling <joseph.wakeling@webdrake.net> wrote:
> import std.range;
>
> void main()
> {
>      assert(isRandomAccessRange!(const(size_t[])));
> }
>
> .... results in an assertion error.  This is a bug, no ... ?

I think ranges have to be non-const. I mean how can you iterate over one if e.g. popFront can't manipulate the inner state?

Maybe you meant:

const(size_t)[]

P.S. you can use a 'static assert' in your code.
September 12, 2013
On Thu, Sep 12, 2013 at 03:12:48PM -0700, Ali Çehreli wrote:
> On 09/12/2013 02:53 PM, Joseph Rushton Wakeling wrote:
> >import std.range;
> >
> >void main()
> >{
> >     assert(isRandomAccessRange!(const(size_t[])));
> >}
> >
> >.... results in an assertion error.  This is a bug, no ... ?
> 
> That one is fine. You probably want a slice of const(size_t):
> 
> import std.range;
> 
> void main()
> {
>     assert(!isRandomAccessRange!(const(size_t[])));
>     assert( isRandomAccessRange!(const(size_t)[])); // <--
> }
[...]

Explanation:

const(size_t)[] means the elements of the array can't be modified, but
the array itself can (necessary to implement popFront, popBack, etc.).

const(size_t[]) means the array itself can't be modified, so popFront, popBack are invalid. So it cannot be a range.


T

-- 
Food and laptops don't mix.
September 12, 2013
On Thursday, September 12, 2013 23:53:15 Joseph Rushton Wakeling wrote:
> import std.range;
> 
> void main()
> {
> assert(isRandomAccessRange!(const(size_t[])));
> }
> 
> .... results in an assertion error. This is a bug, no ... ?

Nope. It's correct. Because it's const, you can't call popFront on it or any of the other mutating range operations. So, it's not a valid range.

- Jonathan M Davis
September 12, 2013
On 13/09/13 00:15, Jonathan M Davis wrote:
> Nope. It's correct. Because it's const, you can't call popFront on it or any
> of the other mutating range operations. So, it's not a valid range.

D'oh! :-P

I gave the assert as an example, but this one snuck up on me rather unexpectedly -- I'd got a class method that was something like this:

    auto foo(in size_t n) @safe const nothrow pure
    {
        return buf[n];      // where buf is a size_t[][]
    }

... and it turned out that foo was trying to return a const(size_t[]) rather than a size_t[].
September 12, 2013
On Friday, September 13, 2013 00:46:20 Joseph Rushton Wakeling wrote:
> On 13/09/13 00:15, Jonathan M Davis wrote:
> > Nope. It's correct. Because it's const, you can't call popFront on it or any of the other mutating range operations. So, it's not a valid range.
> D'oh! :-P
> 
> I gave the assert as an example, but this one snuck up on me rather unexpectedly -- I'd got a class method that was something like this:
> 
> auto foo(in size_t n) @safe const nothrow pure
> {
> return buf[n]; // where buf is a size_t[][]
> }
> 
> ... and it turned out that foo was trying to return a const(size_t[]) rather
> than a size_t[].

At present, const and ranges basically don't mix. Slicing an array results in a tail-const slice, which allows you to get away with using const arrays and then slice them when you need to operate on a range which is const, but it's actually really, really hard to define opSlice in a way that that works for user-defined types. We really need to fix that, but for now, it generally means that you don't use const if you're using ranges (which of course is not what we want, but we're stuck for the moment).

- Jonathan M Davis