Last active
November 20, 2017 09:22
-
-
Save dennisvennink/1c0aac76dc7a145f64787ed23246b4e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// The iterator for `LazyAppendSequence`. | |
public struct LazyAppendIterator <BaseIterator1: IteratorProtocol, BaseIterator2: IteratorProtocol>: IteratorProtocol | |
where BaseIterator1.Element == BaseIterator2.Element { | |
public typealias Element = BaseIterator1.Element | |
private var baseIterator1: BaseIterator1 | |
private var baseIterator2: BaseIterator2 | |
private var reachedEndOfBaseIterator1 = false | |
private var reachedEnd = false | |
internal init (_ baseIterator1: BaseIterator1, _ baseIterator2: BaseIterator2) { | |
self.baseIterator1 = baseIterator1 | |
self.baseIterator2 = baseIterator2 | |
} | |
public mutating func next () -> Element? { | |
if self.reachedEnd { | |
return nil | |
} | |
var next: Element? | |
if !self.reachedEndOfBaseIterator1 { | |
next = self.baseIterator1.next() | |
if next == nil { | |
self.reachedEndOfBaseIterator1 = true | |
} | |
} | |
if next == nil { | |
next = self.baseIterator2.next() | |
if next == nil { | |
self.reachedEnd = true | |
} | |
} | |
return next | |
} | |
} | |
/// A lazily evaluated `Sequence` containing the elements of the right-hand base `Sequence` appended to the elements | |
/// of the left-hand base `Sequence`. | |
/// | |
/// - Attention: To create an instance of `LazyAppendSequence`, use the `++(_:_:)` operator. | |
public struct LazyAppendSequence <BaseSequence1: Sequence, BaseSequence2: Sequence>: LazySequenceProtocol | |
where BaseSequence1.Iterator.Element == BaseSequence2.Iterator.Element { | |
public typealias Iterator = LazyAppendIterator<BaseSequence1.Iterator, BaseSequence2.Iterator> | |
public typealias Element = Iterator.Element | |
internal let baseSequence1: BaseSequence1 | |
internal let baseSequence2: BaseSequence2 | |
internal init (_ baseSequence1: BaseSequence1, _ baseSequence2: BaseSequence2) { | |
self.baseSequence1 = baseSequence1 | |
self.baseSequence2 = baseSequence2 | |
} | |
public func makeIterator () -> Iterator { | |
return Iterator(self.baseSequence1.makeIterator(), self.baseSequence2.makeIterator()) | |
} | |
} | |
infix operator ++ | |
/// Creates a lazily evaluated `Sequence` that appends the right-hand base `Sequence` to the left-hand base `Sequence`. | |
/// | |
/// print(Array([1, 2] ++ [3, 4])) | |
/// // Prints "[1, 2, 3, 4]". | |
/// | |
/// - Attention: | |
/// - If the left-hand base `Sequence` is infinite, the result is the left-hand base `Sequence`. | |
/// - Unlike `+(_:_:)`, `++(_:_:)` guarantees to return a lazy `Sequence`. | |
/// - Parameters: | |
/// - lhs: The left-hand base `Sequence`. | |
/// - rhs: The right-hand base `Sequence`. | |
/// - Returns: A lazily evaluated `Sequence` containing the elements from the right-hand base `Sequence` appended to | |
/// the elements of the left-hand base `Sequence`. | |
public func ++ <BaseSequence1: Sequence, BaseSequence2: Sequence> (lhs: BaseSequence1, rhs: BaseSequence2) -> | |
LazyAppendSequence<BaseSequence1, BaseSequence2> { | |
return LazyAppendSequence(lhs, rhs) | |
} | |
import XCTest | |
@testable import SequenceExtensions | |
/// - Note: Since `++(_:_:)` is a newly defined operator without any overloads we only check the type and value for the | |
/// base `Sequence`. | |
class AppendTests: XCTestCase { | |
let baseSequence = sequence(first: 0, next: { | |
if $0 < 2 { | |
return $0 + 1 | |
} | |
return nil | |
}) | |
typealias BaseSequence = UnfoldSequence<Int, (Int?, Bool)> | |
func testShouldReturnCorrectType () { | |
XCTAssertTrue(type(of: self.baseSequence ++ self.baseSequence) == LazyAppendSequence<BaseSequence, BaseSequence> | |
.self) | |
} | |
func testShouldReturnCorrectValue () { | |
XCTAssertEqual(Array(self.baseSequence ++ self.baseSequence), [0, 1, 2, 0, 1, 2]) | |
XCTAssertEqual(Array(self.baseSequence ++ [Int]()), [0, 1, 2]) | |
XCTAssertEqual(Array([Int]() ++ self.baseSequence), [0, 1, 2]) | |
XCTAssertEqual(Array([Int]() ++ [Int]()), []) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment