Range.init does not imply Range.empty==true

Jonathan M Davis jmdavisProg at gmx.com
Thu Dec 20 14:04:05 PST 2012


On Thursday, December 20, 2012 13:08:46 H. S. Teoh wrote:
> > However, any range which is a struct whose init value _isn't_ empty is
> > wrong. We should be be able to rely on that at least.
> 
> [...]
> 
> No we can't. For example:
> 
> auto someRangeFunction(RoR)(RoR ror) {
> struct Helper {
> RoR _ror;
> ElementType!R _current;
> 
> this(RoR r) {
> _ror = r;
> assert(_current.empty);
> }
> }
> return Helper(ror);
> }
> 
> If RoR is an array of class objects, the assert line will segfault
> because _current.init is null. Conceptually speaking, I agree that a
> null object is an empty range, but in code, .empty is undefined because
> you can't invoke a method through a null reference.

If _current is an array, then it won't segfault. A null array returns true for 
empty. Only classes have problems with null.

But regardless, my point is that Range.init.empty must be true _for structs_. 
A struct range should be written such that its init value is empty. That's not 
true for classes, because they'll be null.

Your assertion should pass as long as the type of _current is a struct.

If you want to get an empty range from an existing range, then use takeNone. 
If it returns the same type (which it tries to do but can't always do - e.g. 
with non-sliceable ranges which are classes or non-sliceable Voldemort types), 
then you can reassign it to the original. If it doesn't, then there's no 
generic way to get an empty range of the same type from that range other than 
calling popFront until it's empty (which is obviously ineffecient in the finite 
case and impossible in the infinite case).

- Jonathan M Davis


More information about the Digitalmars-d mailing list