// // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // /** * Container for a weakly referenced object. * * Only use this for |T| with reference-semantic entities * That is - should inherit from AnyObject or Class-only protocols, but not structs or enums. * * Based on https://devforums.apple.com/message/981472#981472, but also supports class-only protocols */ public struct Weak { private weak var _value: AnyObject? public var value: T? { get { return _value as? T } set { _value = newValue as AnyObject } } public init(value: T) { self.value = value } } public struct WeakArray { private var array: [Weak] = [] public var elements: [Element] { array.compactMap { $0.value } } public var weakReferenceCount: Int { array.count } public mutating func append(_ element: Element) { array = array.filter { $0.value != nil } + [Weak(value: element)] } public mutating func removeAll(where shouldDelete: (Element) throws -> Bool) rethrows { try array.removeAll { weakBox in guard let element = weakBox.value else { return true } return try shouldDelete(element) } } public mutating func cullExpired() { array.removeAll { weakBox in weakBox.value == nil } } } extension WeakArray: ExpressibleByArrayLiteral { public typealias ArrayLiteralElement = Element public init(arrayLiteral elements: Element...) { self.init() for element in elements { self.append(element) } } }