Files
SideStore/Pods/Nuke/Sources/Internal/LinkedList.swift
2023-03-01 16:38:49 -06:00

86 lines
1.9 KiB
Swift

// The MIT License (MIT)
//
// Copyright (c) 2015-2022 Alexander Grebenyuk (github.com/kean).
import Foundation
/// A doubly linked list.
final class LinkedList<Element> {
// first <-> node <-> ... <-> last
private(set) var first: Node?
private(set) var last: Node?
deinit {
removeAll()
#if TRACK_ALLOCATIONS
Allocations.decrement("LinkedList")
#endif
}
init() {
#if TRACK_ALLOCATIONS
Allocations.increment("LinkedList")
#endif
}
var isEmpty: Bool {
last == nil
}
/// Adds an element to the end of the list.
@discardableResult
func append(_ element: Element) -> Node {
let node = Node(value: element)
append(node)
return node
}
/// Adds a node to the end of the list.
func append(_ node: Node) {
if let last = last {
last.next = node
node.previous = last
self.last = node
} else {
last = node
first = node
}
}
func remove(_ node: Node) {
node.next?.previous = node.previous // node.previous is nil if node=first
node.previous?.next = node.next // node.next is nil if node=last
if node === last {
last = node.previous
}
if node === first {
first = node.next
}
node.next = nil
node.previous = nil
}
func removeAll() {
// avoid recursive Nodes deallocation
var node = first
while let next = node?.next {
node?.next = nil
next.previous = nil
node = next
}
last = nil
first = nil
}
final class Node {
let value: Element
fileprivate var next: Node?
fileprivate var previous: Node?
init(value: Element) {
self.value = value
}
}
}