4
4
//
5
5
// Created by Kyle on 2023/1/5.
6
6
// Lastest Version: iOS 15.5
7
- // Status: WIP
7
+ // Status: Complete
8
+ // ID: C1C63C2F6F2B9F3EB30DD747F0605FBD
8
9
9
- struct PreferenceList {
10
+ struct PreferenceList : CustomStringConvertible {
10
11
private var first : PreferenceNode ?
11
-
12
+
12
13
subscript< Key: PreferenceKey > ( _ keyType: Key . Type ) -> Value < Key . Value > {
13
- get { fatalError ( " TODO " ) }
14
- set { fatalError ( " TODO " ) }
14
+ get {
15
+ guard let first,
16
+ let node = first. find ( key: keyType) else {
17
+ return Value ( value: keyType. defaultValue, seed: . zero)
18
+ }
19
+ return Value ( value: node. value, seed: node. seed)
20
+ }
21
+ set {
22
+ if let first,
23
+ let _ = first. find ( key: keyType) {
24
+ removeValue ( for: keyType)
25
+ }
26
+ first = _PreferenceNode < Key > ( value: newValue. value, seed: newValue. seed, next: first)
27
+ }
28
+ }
29
+
30
+ mutating func removeValue< Key: PreferenceKey > ( for keyType: Key . Type ) {
31
+ let first = first
32
+ self . first = nil
33
+ first? . forEach { node in
34
+ guard node. keyType != keyType else {
35
+ return
36
+ }
37
+ self . first = node. copy ( next: self . first)
38
+ }
39
+ }
40
+
41
+ func valueIfPresent< Key: PreferenceKey > ( _ keyType: Key . Type ) -> Value < Key . Value > ? {
42
+ guard let first else {
43
+ return nil
44
+ }
45
+ return first. find ( key: keyType) . map { node in
46
+ Value ( value: node. value, seed: node. seed)
47
+ }
48
+ }
49
+
50
+ func contains< Key: PreferenceKey > ( _ keyType: Key . Type ) -> Bool {
51
+ first? . find ( key: keyType) != nil
52
+ }
53
+
54
+ mutating func modifyValue< Key: PreferenceKey > ( for keyType: Key . Type , transform: Value < ( inout Key . Value ) -> Void > ) {
55
+ var value = self [ keyType]
56
+ value. seed = value. seed. merge ( transform. seed)
57
+ transform. value ( & value. value)
58
+ removeValue ( for: keyType)
59
+ first = _PreferenceNode < Key > ( value: value. value, seed: value. seed, next: first)
60
+ }
61
+
62
+ var description : String {
63
+ var description = " \( ( first? . mergedSeed ?? . zero) . description) : [ "
64
+ var currentNode = first
65
+ var shouldAddSeparator = false
66
+ while let node = currentNode {
67
+ if shouldAddSeparator {
68
+ description. append ( " , " )
69
+ } else {
70
+ shouldAddSeparator = true
71
+ }
72
+ description. append ( node. description)
73
+ currentNode = node. next
74
+ }
75
+ description. append ( " ] " )
76
+ return description
15
77
}
16
78
}
17
79
@@ -22,13 +84,93 @@ extension PreferenceList {
22
84
}
23
85
}
24
86
25
- private class PreferenceNode {
87
+ private class PreferenceNode : CustomStringConvertible {
26
88
let keyType : Any . Type
27
89
let seed : VersionSeed
28
90
let mergedSeed : VersionSeed
29
91
let next : PreferenceNode ?
30
92
31
93
init ( keyType: Any . Type , seed: VersionSeed , next: PreferenceNode ? ) {
32
- fatalError ( " TODO " )
94
+ self . keyType = keyType
95
+ self . seed = seed
96
+ let seedResult : VersionSeed = if let next {
97
+ next. mergedSeed. merge ( seed)
98
+ } else {
99
+ seed
100
+ }
101
+ self . mergedSeed = seedResult
102
+ self . next = next
103
+ }
104
+
105
+ final func forEach( _ body: ( PreferenceNode ) -> Void ) {
106
+ var node = self
107
+ repeat {
108
+ body ( node)
109
+ if let next = node. next {
110
+ node = next
111
+ } else {
112
+ break
113
+ }
114
+ } while true
115
+ }
116
+
117
+ final func find< Key: PreferenceKey > ( key: Key . Type ) -> _PreferenceNode < Key > ? {
118
+ var node = self
119
+ repeat {
120
+ if node. keyType == key {
121
+ return node as? _PreferenceNode < Key >
122
+ } else {
123
+ if let next = node. next {
124
+ node = next
125
+ } else {
126
+ break
127
+ }
128
+ }
129
+ } while true
130
+ return nil
131
+ }
132
+
133
+ func find( from _: PreferenceNode ? ) -> PreferenceNode ? { fatalError ( ) }
134
+ func combine( from _: PreferenceNode ? , next _: PreferenceNode ? ) -> PreferenceNode ? { fatalError ( ) }
135
+ func copy( next _: PreferenceNode ? ) -> PreferenceNode { fatalError ( ) }
136
+ var description : String { fatalError ( ) }
137
+ }
138
+
139
+ private class _PreferenceNode < Key: PreferenceKey > : PreferenceNode {
140
+ let value : Key . Value
141
+
142
+ init ( value: Key . Value , seed: VersionSeed , next: PreferenceNode ? ) {
143
+ self . value = value
144
+ super. init ( keyType: Key . self, seed: seed, next: next)
145
+ }
146
+
147
+ override func find( from: PreferenceNode ? ) -> PreferenceNode ? {
148
+ from? . find ( key: Key . self)
149
+ }
150
+
151
+ override func combine( from: PreferenceNode ? , next: PreferenceNode ? ) -> PreferenceNode ? {
152
+ var currentNode = from
153
+ while let node = currentNode {
154
+ if keyType == node. keyType {
155
+ var value = self . value
156
+ var seed = self . seed
157
+ Key . reduce ( value: & value) {
158
+ seed = seed. merge ( node. seed)
159
+ return ( node as! _PreferenceNode ) . value
160
+ }
161
+ return _PreferenceNode ( value: value, seed: seed, next: next)
162
+ } else {
163
+ currentNode = node. next
164
+ }
165
+ }
166
+ return nil
167
+ }
168
+
169
+ override func copy( next: PreferenceNode ? ) -> PreferenceNode {
170
+ _PreferenceNode ( value: value, seed: seed, next: next)
171
+ }
172
+
173
+ override var description : String {
174
+ " \( Key . self) = \( value) "
33
175
}
34
176
}
0 commit comments