0001 // 0002 // ExistentialFuture.swift 0003 // Deferred 0004 // 0005 // Created by Zachary Waldowski on 8/29/15. 0006 // Copyright © 2014-2015 Big Nerd Ranch. Licensed under MIT. 0007 // 0008 0009 import Dispatch 0010 0011 /* 0012 The types in this file provide an implementation of type erasure for `FutureType`. 0013 The techniques were derived from experimenting with `AnySequence` and `Mirror` 0014 in a playground, the following post, and the Swift standard library: 0015 - https://realm.io/news/type-erased-wrappers-in-swift/ 0016 - https://github.com/apple/swift/blob/master/stdlib/public/core/ExistentialCollection.swift.gyb 0017 */ 0018 0019 // Abstract class that fake-conforms to `FutureType` for use by `Future`. 0020 private class FutureBase<Value
ExistentialFuture.swift:31 private final class ForwardingFuture<Future: FutureType>: FutureBase<Future.Value> {ExistentialFuture.swift:47 private final class FilledFuture<Value>: FutureBase<Value> {ExistentialFuture.swift:77 private let box: FutureBase<Value>>: FutureType { 0021 func upon
ExistentialFuture.swift:21 func upon(queue: dispatch_queue_t, body: Value -> ()) {ExistentialFuture.swift:25 func wait(time: Timeout) -> Value? {(queue: dispatch_queue_t, body: Value -> ()) { 0022 fatalError() 0023 } 0024 0025 func wait
ExistentialFuture.swift:99 return box.upon(queue, body: body)(time: Timeout) -> Value? { 0026 fatalError() 0027 } 0028 } 0029 0030 // Concrete future wrapper given an instance of a `FutureType`. 0031 private final class ForwardingFuture
ExistentialFuture.swift:107 return box.wait(time)<Future
ExistentialFuture.swift:81 self.box = ForwardingFuture(base: base): FutureType>: FutureBase<Future.Value> { 0032 let base
ExistentialFuture.swift:31 private final class ForwardingFuture<Future: FutureType>: FutureBase<Future.Value> {ExistentialFuture.swift:32 let base: FutureExistentialFuture.swift:33 init(base: Future) {ExistentialFuture.swift:37 override func upon(queue: dispatch_queue_t, body: Future.Value -> ()) {ExistentialFuture.swift:41 override func wait(time: Timeout) -> Future.Value? {: Future 0033 init
ExistentialFuture.swift:34 self.base = baseExistentialFuture.swift:38 return base.upon(queue, body: body)ExistentialFuture.swift:42 return base.wait(time)(base: Future) { 0034 self.base = base 0035 } 0036 0037 override func upon(queue: dispatch_queue_t, body: Future.Value -> ()) { 0038 return base.upon(queue, body: body) 0039 } 0040 0041 override func wait(time: Timeout) -> Future.Value? { 0042 return base.wait(time) 0043 } 0044 } 0045 0046 // Concrete future wrapper for an always-filled future. 0047 private final class FilledFuture
ExistentialFuture.swift:81 self.box = ForwardingFuture(base: base)<Value
ExistentialFuture.swift:86 self.box = FilledFuture(value: value)>: FutureBase<Value> { 0048 let value
ExistentialFuture.swift:47 private final class FilledFuture<Value>: FutureBase<Value> {ExistentialFuture.swift:48 let value: ValueExistentialFuture.swift:49 init(value: Value) {ExistentialFuture.swift:53 override func upon(queue: dispatch_queue_t, body: Value -> ()) {ExistentialFuture.swift:59 override func wait(time: Timeout) -> Value? {: Value 0049 init
ExistentialFuture.swift:50 self.value = valueExistentialFuture.swift:54 dispatch_async(queue) { [value] inExistentialFuture.swift:60 return value(value: Value) { 0050 self.value = value 0051 } 0052 0053 override func upon(queue: dispatch_queue_t, body: Value -> ()) { 0054 dispatch_async(queue) { [value] in 0055 body(value) 0056 } 0057 } 0058 0059 override func wait(time: Timeout) -> Value? { 0060 return value 0061 } 0062 } 0063 0064 /// A type-erased wrapper over any future. 0065 /// 0066 /// Forwards operations to an arbitrary underlying future having the same 0067 /// `Value` type, hiding the specifics of the underlying `FutureType`. 0068 /// 0069 /// Authors can use this type to: 0070 /// 0071 /// - Prevent clients from coupling to the specific kind of `FutureType` your 0072 /// implementation is currently using. 0073 /// - Publicly expose only the `FutureType` aspect of a deferred value, 0074 /// ensuring that only your implementation can fill the deferred value 0075 /// using the `PromiseType` aspect. 0076 public struct Future
ExistentialFuture.swift:86 self.box = FilledFuture(value: value)<Value
ExistentialFuture.swift:90 public init(_ other: Future<Value>) {FutureCollections.swift:23 return Future(combined)FutureCollections.swift:16 var earliestFilled: Future<Generator.Element.Value> {FutureCollections.swift:34 return Future(value: [])FutureCollections.swift:54 return Future(combined)FutureCollections.swift:32 var joinedValues: Future<[Generator.Element.Value]> {FutureType.swift:127 func flatMap<NewFuture: FutureType>(upon queue: dispatch_queue_t = genericQueue, _ transform: Value -> NewFuture) -> Future<NewFuture.Value> {FutureType.swift:134 return Future(d)FutureType.swift:147 func map<NewValue>(upon queue: dispatch_queue_t = genericQueue, _ transform: Value -> NewValue) -> Future<NewValue> {FutureType.swift:152 return Future(d)FutureType.swift:163 func and<OtherFuture: FutureType>(other: OtherFuture) -> Future<(Value, OtherFuture.Value)> {FutureType.swift:164 return Future(flatMap { t in other.map { u in (t, u) } })FutureType.swift:174 func and<Other1: FutureType, Other2: FutureType>(one: Other1, _ two: Other2) -> Future<(Value, Other1.Value, Other2.Value)> {FutureType.swift:175 return Future(flatMap { t inFutureType.swift:190 func and<Other1: FutureType, Other2: FutureType, Other3: FutureType>(one: Other1, _ two: Other2, _ three: Other3) -> Future<(Value, Other1.Value, Other2.Value, Other3.Value)> {FutureType.swift:191 return Future(flatMap { t in>: FutureType { 0077 private let box
ExistentialFuture.swift:77 private let box: FutureBase<Value>ExistentialFuture.swift:80 public init<Future: FutureType where Future.Value == Value>(_ base: Future) {ExistentialFuture.swift:85 public init(value: Value) {ExistentialFuture.swift:90 public init(_ other: Future<Value>) {ExistentialFuture.swift:98 public func upon(queue: dispatch_queue_t, body: Value -> ()) {ExistentialFuture.swift:106 public func wait(time: Timeout) -> Value? {: FutureBase<Value> 0078 0079 /// Create a future whose `upon(_:function:)` method forwards to `base`. 0080 public init
ExistentialFuture.swift:81 self.box = ForwardingFuture(base: base)ExistentialFuture.swift:86 self.box = FilledFuture(value: value)ExistentialFuture.swift:91 self.box = other.boxExistentialFuture.swift:91 self.box = other.boxExistentialFuture.swift:99 return box.upon(queue, body: body)ExistentialFuture.swift:107 return box.wait(time)<Future: FutureType where Future.Value == Value>(_ base: Future) { 0081 self.box = ForwardingFuture(base: base) 0082 } 0083 0084 /// Wrap and forward future as if it were always filled with `value`. 0085 public init
FutureCollections.swift:23 return Future(combined)FutureCollections.swift:54 return Future(combined)FutureType.swift:134 return Future(d)FutureType.swift:152 return Future(d)(value: Value) { 0086 self.box = FilledFuture(value: value) 0087 } 0088 0089 /// Create a future having the same underlying future as `other`. 0090 public init
FutureCollections.swift:34 return Future(value: [])(_ other: Future<Value>) { 0091 self.box = other.box 0092 } 0093 0094 /// Call some function once the underlying future's value is determined. 0095 /// 0096 /// - parameter queue: A dispatch queue for executing the given function on. 0097 /// - parameter function: A function that uses the determined value. 0098 public func upon(queue: dispatch_queue_t, body: Value -> ()) { 0099 return box.upon(queue, body: body) 0100 } 0101 0102 /// Waits synchronously for the underlying future to become determined. 0103 /// 0104 /// - parameter time: A length of time to wait for the value to be determined. 0105 /// - returns: The determined value, if filled within the timeout, or `nil`. 0106 public func wait(time: Timeout) -> Value? { 0107 return box.wait(time) 0108 } 0109 } 0110
FutureType.swift:164 return Future(flatMap { t in other.map { u in (t, u) } })FutureType.swift:175 return Future(flatMap { t inFutureType.swift:191 return Future(flatMap { t in