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
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>
<Value
ExistentialFuture.swift:21
    func upon(queue: dispatch_queue_t, body: Value -> ()) {
ExistentialFuture.swift:25
    func wait(time: Timeout) -> Value? {
>: FutureType { 0021 func upon
ExistentialFuture.swift:99
        return box.upon(queue, body: body)
(queue: dispatch_queue_t, body: Value -> ()) { 0022 fatalError() 0023 } 0024 0025 func wait
ExistentialFuture.swift:107
        return box.wait(time)
(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:81
        self.box = ForwardingFuture(base: base)
<Future
ExistentialFuture.swift:31
private final class ForwardingFuture<Future: FutureType>: FutureBase<Future.Value> {
ExistentialFuture.swift:32
    let base: Future
ExistentialFuture.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? {
: FutureType>: FutureBase<Future.Value> { 0032 let base
ExistentialFuture.swift:34
        self.base = base
ExistentialFuture.swift:38
        return base.upon(queue, body: body)
ExistentialFuture.swift:42
        return base.wait(time)
: Future 0033 init
ExistentialFuture.swift:81
        self.box = ForwardingFuture(base: base)
(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:86
        self.box = FilledFuture(value: value)
<Value
ExistentialFuture.swift:47
private final class FilledFuture<Value>: FutureBase<Value> {
ExistentialFuture.swift:48
    let value: Value
ExistentialFuture.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? {
>: FutureBase<Value> { 0048 let value
ExistentialFuture.swift:50
        self.value = value
ExistentialFuture.swift:54
        dispatch_async(queue) { [value] in
ExistentialFuture.swift:60
        return value
: Value 0049 init
ExistentialFuture.swift:86
        self.box = FilledFuture(value: 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: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 in
FutureType.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
<Value
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? {
>: FutureType { 0077 private let box
ExistentialFuture.swift:81
        self.box = ForwardingFuture(base: base)
ExistentialFuture.swift:86
        self.box = FilledFuture(value: value)
ExistentialFuture.swift:91
        self.box = other.box
ExistentialFuture.swift:91
        self.box = other.box
ExistentialFuture.swift:99
        return box.upon(queue, body: body)
ExistentialFuture.swift:107
        return box.wait(time)
: FutureBase<Value> 0078 0079 /// Create a future whose `upon(_:function:)` method forwards to `base`. 0080 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)
<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:34
            return Future(value: [])
(value: Value) { 0086 self.box = FilledFuture(value: value) 0087 } 0088 0089 /// Create a future having the same underlying future as `other`. 0090 public init
FutureType.swift:164
        return Future(flatMap { t in other.map { u in (t, u) } })
FutureType.swift:175
        return Future(flatMap { t in
FutureType.swift:191
        return Future(flatMap { t in
(_ 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