Re: isBidirectionalRange fails for unknown reasons

2015-12-16 Thread Jakob Ovrum via Digitalmars-d-learn
On Wednesday, 16 December 2015 at 20:43:02 UTC, Jack Stouffer 
wrote:

...


You can also use return type covariance:

class ReferenceBidirectionalRange(T) : ReferenceForwardRange!T
{
this(Range)(Range r) if (isInputRange!Range) { super(r); }
final override @property typeof(this) save() { return new 
typeof(this)(_payload); }

final @property ref T back(){ return _payload.back; }
final void popBack(){ _payload.popBack(); }
}

ReferenceBidirectionalRange!T is a subtype of 
ReferenceForwardRange!T, so the override is legal.




Re: isBidirectionalRange fails for unknown reasons

2015-12-16 Thread Jack Stouffer via Digitalmars-d-learn

On Wednesday, 16 December 2015 at 21:40:44 UTC, anonymous wrote:
The `.save` primitive of forward ranges must return the very 
same type that the range has. But your 
ReferenceBidirectionalRange!T.save returns a 
ReferenceForwardRange!T, because it's inherited. That makes 
isForwardRange!(ReferenceBidirectionalRange!T) fail, and 
everything that depends on it.


You can override `save` in ReferenceBidirectionalRange or try 
something clever like using a template this parameter:


@property auto save(this This)() {return new This( _payload);}


Thanks! That did the trick.


Re: isBidirectionalRange fails for unknown reasons

2015-12-16 Thread anonymous via Digitalmars-d-learn

On 16.12.2015 21:43, Jack Stouffer wrote:

I'm trying to add a ReferenceBidirectionalRange range type to
std.internal.test.dummyrange so I can test some range code I'm writing,
but I've hit a wall and I'm not sure why. For some reason, the
isBidirectionalRange check fails even though back and popBack are
present. Any help here would be appreciated.


[...]


class ReferenceForwardRange(T) : ReferenceInputRange!T
{
 this(Range)(Range r) if (isInputRange!Range) { super(r); }
 final @property ReferenceForwardRange save()
 {return new ReferenceForwardRange!T( _payload); }
}

class ReferenceBidirectionalRange(T) : ReferenceForwardRange!T
{
 this(Range)(Range r) if (isInputRange!Range) { super(r); }
 final @property ref T back(){ return _payload.back; }
 final void popBack(){ _payload.popBack(); }
}


The `.save` primitive of forward ranges must return the very same type 
that the range has. But your ReferenceBidirectionalRange!T.save returns 
a ReferenceForwardRange!T, because it's inherited. That makes 
isForwardRange!(ReferenceBidirectionalRange!T) fail, and everything that 
depends on it.


You can override `save` in ReferenceBidirectionalRange or try something 
clever like using a template this parameter:


@property auto save(this This)() {return new This( _payload);}



Re: isBidirectionalRange fails for unknown reasons

2015-12-16 Thread Jack Stouffer via Digitalmars-d-learn
On Wednesday, 16 December 2015 at 20:43:02 UTC, Jack Stouffer 
wrote:

unittest
{
static assert(isInputRange!(ReferenceInputRange!int)); // 
works
static assert(isForwardRange!(ReferenceForwardRange!int)); 
// works
static 
assert(isBidirectionalRange!(ReferenceBidirectionalRange!int)); 
//fails

}


Also, this works just fine

=
unittest
{
auto a = new ReferenceBidirectionalRange!int([1,2]);
a.popBack();
a.back.writeln; // prints 1
}


isBidirectionalRange fails for unknown reasons

2015-12-16 Thread Jack Stouffer via Digitalmars-d-learn
I'm trying to add a ReferenceBidirectionalRange range type to 
std.internal.test.dummyrange so I can test some range code I'm 
writing, but I've hit a wall and I'm not sure why. For some 
reason, the isBidirectionalRange check fails even though back and 
popBack are present. Any help here would be appreciated.


the code:

import std.range;

class ReferenceInputRange(T)
{
import std.array : array;

this(Range)(Range r) if (isInputRange!Range) { _payload = 
array(r); }

final @property ref T front(){ return _payload.front; }
final void popFront(){ _payload.popFront(); }
final @property bool empty(){ return _payload.empty; }
protected T[] _payload;
}

class ReferenceForwardRange(T) : ReferenceInputRange!T
{
this(Range)(Range r) if (isInputRange!Range) { super(r); }
final @property ReferenceForwardRange save()
{return new ReferenceForwardRange!T( _payload); }
}

class ReferenceBidirectionalRange(T) : ReferenceForwardRange!T
{
this(Range)(Range r) if (isInputRange!Range) { super(r); }
final @property ref T back(){ return _payload.back; }
final void popBack(){ _payload.popBack(); }
}

unittest
{
static assert(isInputRange!(ReferenceInputRange!int)); // 
works
static assert(isForwardRange!(ReferenceForwardRange!int)); // 
works
static 
assert(isBidirectionalRange!(ReferenceBidirectionalRange!int)); 
//fails

}