I need to implement a type-erasing wrapper for my own structure, very similar to SequenceOf, GeneratorOf, etc. So I started by trying to just re-im
Try:
struct MySequenceOf : SequenceType {
private let _generate:() -> MyGeneratorOf
init(_ makeUnderlyingGenerator: () -> G) {
_generate = { MyGeneratorOf(makeUnderlyingGenerator()) }
}
init(_ base: S) {
_generate = { MyGeneratorOf(base.generate()) }
}
func generate() -> MyGeneratorOf {
return _generate()
}
}
struct MyGeneratorOf : GeneratorType, SequenceType {
private let _next:() -> T?
init(_ nextElement: () -> T?) {
_next = nextElement
}
init(var _ base: G) {
_next = { base.next() }
}
mutating func next() -> T? {
return _next()
}
func generate() -> MyGeneratorOf {
return self
}
}
The basic strategy of implementing ProtocolOf is, like this:
protocol ProtocolType {
typealias Value
func methodA() -> Value
func methodB(arg:Value) -> Bool
}
struct ProtocolOf:ProtocolType {
private let _methodA: () -> T
private let _methodB: (T) -> Bool
init(_ base:B) {
_methodA = { base.methodA() }
_methodB = { base.methodB($0) }
}
func methodA() -> T { return _methodA() }
func methodB(arg:T) -> Bool { return _methodB(arg) }
}
Added to answering @MartinR in comment.
Is there a special reason that _generate is a closure and not the generator itself?
First of all, I think, It's a matter of specification or semantics.
Needless to say, the difference is "when to create the generator".
Consider this code:
class Foo:SequenceType {
var vals:[Int] = [1,2,3]
func generate() -> Array.Generator {
return vals.generate()
}
}
let foo = Foo()
let seq = MySequenceOf(foo)
foo.vals = [4,5,6]
let result = Array(seq)
The problem is: result should be [1,2,3] or [4,5,6]? My MySequenceOf and built-in SequenceOf results the latter. I just matched the behaviors with built-in one.