Created
September 8, 2017 15:03
-
-
Save guidomb/883b4fe939c65ff41873cedb330a0738 to your computer and use it in GitHub Desktop.
An example of how I would like custom type conversion to work.
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
let foo = ZipList(left: [1, 2, 3], center: 4, right: [5, 6, 7]) | |
// This is what I would like to have, a custom type conversion / casting | |
// ([Element], Element, [Element]) => ZipList<Element> | |
let bar: ZipList<Int> = ([1, 2, 3], 4, [5, 6, 7]) | |
// ZipList type definition | |
public struct ZipList<Element>: Collection, CustomDebugStringConvertible { | |
public var startIndex: Int { | |
return 0 | |
} | |
public var endIndex: Int { | |
return count | |
} | |
public var count: Int { | |
return left.count + right.count + 1 | |
} | |
public var centerIndex: Int { | |
return left.count | |
} | |
public var debugDescription: String { | |
return "ZipList(\n\tleft: \(left)\n\tcenter: \(center)\n\tright: \(right))" | |
} | |
public let left: [Element] | |
public let center: Element | |
public let right: [Element] | |
public init(element: Element) { | |
self.init(left: [], center: element, right: []) | |
} | |
public init(left: [Element], center: Element, right: [Element]) { | |
self.left = left | |
self.center = center | |
self.right = right | |
} | |
public subscript(index: Int) -> Element { | |
precondition(index >= 0 && index < count, "Index of out bounds") | |
if index < left.count { | |
return left[index] | |
} else if index == left.count { | |
return center | |
} else { | |
return right[index - left.count - 1] | |
} | |
} | |
public func index(after index: Int) -> Int { | |
return index + 1 | |
} | |
public func shiftLeft(count: UInt) -> ZipList<Element>? { | |
guard count <= UInt(right.count) else { return .none } | |
if count == 0 { return self } | |
let newLeft = left + [center] + Array(right.dropLast(right.count + 1 - Int(count))) | |
let newRight = Array(right.dropFirst(Int(count))) | |
return ZipList(left: newLeft, center: right[Int(count) - 1], right: newRight) | |
} | |
public func shiftRight(count: UInt) -> ZipList<Element>? { | |
guard count <= UInt(left.count) else { return .none } | |
if count == 0 { return self } | |
let newLeft = Array(left.dropLast(Int(count))) | |
let newRight = Array(left.dropFirst(left.count + 1 - Int(count))) + [center] + right | |
return ZipList(left: newLeft, center: left[left.count - Int(count)], right: newRight) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment