Use nested type `BagKey.Gen`

This commit is contained in:
Quentin Jin 2019-04-18 10:11:41 +08:00
parent 913a699a6e
commit 66e6c54aa4
2 changed files with 16 additions and 25 deletions

View File

@ -3,29 +3,20 @@ import Foundation
/// A unique key for removing an element from a bag. /// A unique key for removing an element from a bag.
struct BagKey: Equatable { struct BagKey: Equatable {
fileprivate let i: UInt64 private let i: UInt64
fileprivate init(underlying: UInt64) { /// A generator that can generate a sequence of unique `BagKey`.
self.i = underlying ///
} /// let k1 = gen.next()
} /// let k2 = gen.next()
/// ...
/// A generator that can generate a sequence of unique `BagKey`. struct Gen {
/// private var key = BagKey(i: 0)
/// let k1 = gen.next() init() { }
/// let k2 = gen.next() mutating func next() -> BagKey {
/// ... defer { key = BagKey(i: key.i + 1) }
struct BagKeyGenerator: Sequence, IteratorProtocol { return key
}
typealias Element = BagKey
private var k = BagKey(underlying: 0)
/// Advances to the next key and returns it, or nil if no next key exists.
mutating func next() -> BagKey? {
if k.i == UInt64.max { return nil }
defer { k = BagKey(underlying: k.i + 1) }
return k
} }
} }
@ -44,13 +35,13 @@ struct Bag<Element> {
private typealias Entry = (key: BagKey, val: Element) private typealias Entry = (key: BagKey, val: Element)
private var keyGen = BagKeyGenerator() private var keyGen = BagKey.Gen()
private var entries: [Entry] = [] private var entries: [Entry] = []
/// Appends a new element at the end of this bag. /// Appends a new element at the end of this bag.
@discardableResult @discardableResult
mutating func append(_ new: Element) -> BagKey { mutating func append(_ new: Element) -> BagKey {
let key = keyGen.next()! let key = keyGen.next()
let entry = (key: key, val: new) let entry = (key: key, val: new)
entries.append(entry) entries.append(entry)

View File

@ -6,7 +6,7 @@ final class BagTests: XCTestCase {
typealias Fn = () -> Int typealias Fn = () -> Int
func testBagKey() { func testBagKey() {
var g = BagKeyGenerator() var g = BagKey.Gen()
let k1 = g.next() let k1 = g.next()
let k2 = g.next() let k2 = g.next()
XCTAssertNotNil(k1) XCTAssertNotNil(k1)