Default bounds subscript for BidirectionalCollection


(Tim Vermeulen) #1

I expected the following code to compile:

struct Wrapper<Element>: BidirectionalCollection {
    
    var elements: [Element]
    
    var startIndex: Int { return 0 }
    var endIndex: Int { return elements.count }
    
    func index(after index: Int) -> Int { return index + 1 }
    func index(before index: Int) -> Int { return index - 1 }
    
    subscript(position: Int) -> Element {
        return elements[position]
    }
    
}

However, I got a long list of errors. I tried adding this:

extension Wrapper {
    
    subscript(bounds: Range<Int>) -> BidirectionalSlice<Wrapper> {
        return BidirectionalSlice(base: self, bounds: bounds)
    }
    
}

But not Xcode shows an interesting error message: “Type `Wrapper<Element>.Index` does not conform to protocol `Comparable`”. Surely, Wrapper<Element>.Index is just Int which can be inferred from the startIndex property, for example. I tried setting the Index type explicitly:

struct Wrapper<Element>: BidirectionalCollection {
    typealias Index = Int
    ...
}

Now the code finally compiles. Bug?


(Tim Vermeulen) #2

No problem! But no, count is correct. From the docs: “endIndex: The collection's "past the end" position---that is, the position one greater than the last valid subscript argument."

···

On 28 Jun 2016, at 22:45, Roy Henderson <roy@scotmail.net> wrote:

Definitely not trying to correct your code Tim - but, being a Swift-101 guy, I'm confused by endIndex as count. Should it not be count - 1?

Roy

On 28 Jun 2016, at 20:45, Tim Vermeulen via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

I expected the following code to compile:

struct Wrapper<Element>: BidirectionalCollection {
    
    var elements: [Element]
    
    var startIndex: Int { return 0 }
    var endIndex: Int { return elements.count }
    
    func index(after index: Int) -> Int { return index + 1 }
    func index(before index: Int) -> Int { return index - 1 }
    
    subscript(position: Int) -> Element {
        return elements[position]
    }
    
}

However, I got a long list of errors. I tried adding this:

extension Wrapper {
    
    subscript(bounds: Range<Int>) -> BidirectionalSlice<Wrapper> {
        return BidirectionalSlice(base: self, bounds: bounds)
    }
    
}

But not Xcode shows an interesting error message: “Type `Wrapper<Element>.Index` does not conform to protocol `Comparable`”. Surely, Wrapper<Element>.Index is just Int which can be inferred from the startIndex property, for example. I tried setting the Index type explicitly:

struct Wrapper<Element>: BidirectionalCollection {
    typealias Index = Int
    ...
}

Now the code finally compiles. Bug?
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users