public struct Weak<T> {
private weak var _value: AnyObject?
public var value: T? {
get {
return _value as? T
}
set {
_value = newValue.map { $0 as AnyObject }
}
}
public init(value: T?) {
self.value = value
}
}
public struct WeakArray<Element> {
private var array: [Weak<Element>] = []
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)
}
}
}