<div dir="ltr"><div><br></div><div>How GeneratorType confirm to Equatable??</div><div><br></div><div>struct Fib : SequenceType {</div><div> </div><div> var a: Int</div><div> var b: Int</div><div> </div><div> var limit: Int</div><div> </div><div> func generate() -> FibGenerator {</div><div> return Generator(a: a, b: b, limit: limit)</div><div> }</div><div>}</div><div><br></div><div>let c = Multipass(Fib(a: 1, b: -1, limit: 10))</div><div><br></div><div>-Susan</div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">2016-01-01 11:17 GMT+08:00 Dave Abrahams <span dir="ltr"><<a href="mailto:dabrahams@apple.com" target="_blank">dabrahams@apple.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">FWIW, Indexable is an implementation artifact that will go away when Swift’s generics system is improved.<br>
<br>
But if your real objection is that you have to come up with an Index and a subscripting operator, I can understand that. Part of the reason for this is our reluctance to create any distinct protocols with identical syntactic requirements <<a href="http://news.gmane.org/find-root.php?message_id=2A3E0C76-1C88-4752-8A70-AA64BB14223A@apple.com" rel="noreferrer" target="_blank">http://news.gmane.org/find-root.php?message_id=2A3E0C76-1C88-4752-8A70-AA64BB14223A@apple.com</a>>. To justify having a separate multi-pass sequence protocol, there would have to be a significant/important class of multi-pass sequences for which CollectionType was unimplementable without serious costs.<br>
<br>
In principle there’s a way to ease the pain of creating CollectionType conformances for multipass SequenceTypes…if only it didn’t crash the compiler <<a href="https://bugs.swift.org/browse/SR-427" rel="noreferrer" target="_blank">https://bugs.swift.org/browse/SR-427</a>> ;-). Here’s a variation that uses a generic adapter instead of a protocol conformance declaration:<br>
<br>
/// A `CollectionType` containing the same elements as `Base`, without storing them.<br>
///<br>
/// - Requires: `Base` supports multiple passes (traversing it does not<br>
/// consume the sequence), and `Base.Generator` has value semantics<br>
public struct Multipass<Base: SequenceType where Base.Generator: Equatable> : CollectionType {<br>
public var startIndex: MultipassIndex<Base> {<br>
var g = _base.generate()<br>
return MultipassIndex(buffer: g.next(), generator: g)<br>
}<br>
<br>
public var endIndex: MultipassIndex<Base> {<br>
return MultipassIndex(buffer: nil, generator: _base.generate())<br>
}<br>
<br>
public subscript(position: MultipassIndex<Base>) -> Base.Generator.Element {<br>
return position.buffer!<br>
}<br>
<br>
public init(_ base: Base) {<br>
_base = base<br>
}<br>
<br>
var _base: Base<br>
}<br>
<br>
// Note: Requires T.Generator has value semantics<br>
public struct MultipassIndex<T: SequenceType where T.Generator: Equatable> : ForwardIndexType {<br>
public func successor() -> MultipassIndex {<br>
var r = self<br>
r.buffer = r.generator.next()<br>
return r<br>
}<br>
var buffer: T.Generator.Element?<br>
var generator: T.Generator<br>
}<br>
<br>
public func == <T>(x: MultipassIndex<T>, y: MultipassIndex<T>) -> Bool {<br>
return x.buffer == nil && y.buffer == nil || x.generator == y.generator<br>
}<br>
<br>
//===--- An example fibonacci sequence ------------------------------------===//<br>
struct FibGenerator : GeneratorType {<br>
mutating func next() -> Int? {<br>
let c = a + b<br>
a = b<br>
b = c<br>
return a < limit ? a : nil<br>
}<br>
var a, b, limit: Int<br>
}<br>
<br>
<br>
struct Fib : SequenceType {<br>
var limit = 1000<br>
<br>
func generate() -> FibGenerator {<br>
return Generator(a: 0, b: 1, limit: limit)<br>
}<br>
}<br>
<br>
//===--- Adapt Fib for use with Multipass ---------------------------------===//<br>
extension FibGenerator : Equatable {}<br>
func == (x: Fib.Generator, y: Fib.Generator) -> Bool {<br>
return x.a == y.a<br>
}<br>
<br>
//===--- Demonstration ----------------------------------------------------===//<br>
let c = Multipass(Fib())<br>
print(c.first)<br>
print(c.count)<br>
print(c.lazy.map { $0 + 1 })<br>
</blockquote></div><br></div></div>