Background
For convenience, I used this alias:
typealias Deck = [Int]
My needs are expanding so I have now converted my code to:
class Deck
{
var deck : [Int]
// ... other members
}
I am able to delegate most of my calls through to self.deck
, but after googling around somewhat, I am still having trouble figuring out how to delegate this call:
let deck = Deck()
for i in deck[0..<5] { } // <--- PROBLEMS HERE
Question
How do I implement the delegation of this call?
I think it has something to do with subscript
and range
(or maybe sequence
?), but I had no luck googling the intersection of these two topics.
For deck[0..<5]
you need to implement the Sliceable
protocol, which in turn
requires CollectionType
and SequenceType
.
The following example implements MutableCollectionType
so that setting
elements is forwarded to the array as well:
class Deck
{
typealias DeckValueType = Int
typealias DeckIndexType = Array<DeckValueType>.Index
var deck : [DeckValueType] = [0, 1, 2, 3, 4, 5, 6] // just for demonstration ...
}
extension Deck : SequenceType {
func generate() -> IndexingGenerator<[DeckValueType]> {
return deck.generate()
}
}
extension Deck: MutableCollectionType {
var startIndex : DeckIndexType { return deck.startIndex }
var endIndex : DeckIndexType { return deck.endIndex }
subscript(index: DeckIndexType) -> DeckValueType {
get {
return deck[index]
}
set(newValue) {
deck[index] = newValue
}
}
}
extension Deck : Sliceable {
subscript (bounds: Range<DeckIndexType>) -> ArraySlice<DeckValueType> {
get {
return deck[bounds]
}
}
}
And then it works:
let deck = Deck()
for i in deck[0..<5] {
println(i)
}
The type aliases are not strictly necessary, but they make it easier to
distinguish whether Int
is used as the type of an array element or as the
type for an array index.
Also you can put all the code into the class definition. I have chosen separate
extensions to make clear which method is needed for which protocol.