> On Jul 2, 2016, at 9:48 AM, Tim Vermeulen via swift-users 
> <swift-users@swift.org> wrote:
> 
> Why is endIndex one greater than the last valid subscript argument, rather 
> than simply the last valid subscript argument? I’m sure there are great 
> reasons for this, but I just can’t think of them myself.

It’s hard to handle empty collections, otherwise. If endIndex were the last 
valid subscript, then in an empty collection what would its value be? 
Presumably it would have to point to one before the start, which is rather 
weird because that’s never a valid index (in an int-indexed collection it would 
be negative.) Even worse, endIndex is never reachable from startIndex, so an 
iteration can’t simply continue until it reaches the endIndex. Instead the 
Indexable type would have to implement a (cheap, constant-time) >= operator to 
use as the test for an iteration.

These are probably the reasons why C++ also uses the convention of a 
collection’s end() pointing to one past the end.

> I’m implementing a binary tree and I want to implement 
> BidirectionalCollection. Each index contains a (private) reference to the 
> corresponding node in the tree. However, endIndex shouldn’t point to 
> anything, and it makes things very complicated if I want a constant time 
> implementation of index(before:).

Have the tree object keep a pointer to its last node. That makes it cheap to 
get that node as the ‘before’ of the last node. You’ll also have the benefit of 
making endIndex() itself constant-time, whereas presumably it’s now O(log n) 
since you have to walk down the tree to find it.

Or alternatively, you could add a flag to your index type that indicates it’s 
pointing to the end of the collection. Then the endIndex() really points to the 
last node but has the flag set.

—Jens
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to