list-toolkit 2.2.5 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -36
- package/llms-full.txt +743 -0
- package/llms.txt +100 -0
- package/package.json +40 -32
- package/src/cache/cache-fifo.d.ts +6 -0
- package/src/cache/cache-fifo.js +7 -4
- package/src/cache/cache-lfu.d.ts +18 -0
- package/src/cache/cache-lfu.js +18 -6
- package/src/cache/cache-lru.d.ts +74 -0
- package/src/cache/cache-lru.js +60 -5
- package/src/cache/cache-random.d.ts +20 -0
- package/src/cache/cache-random.js +17 -6
- package/src/cache/decorator.d.ts +46 -0
- package/src/cache/decorator.js +26 -2
- package/src/cache.d.ts +13 -0
- package/src/cache.js +7 -2
- package/src/ext-list.d.ts +3 -0
- package/src/ext-list.js +0 -2
- package/src/ext-slist.d.ts +3 -0
- package/src/ext-slist.js +0 -2
- package/src/ext-value-list.d.ts +3 -0
- package/src/ext-value-list.js +0 -2
- package/src/ext-value-slist.d.ts +3 -0
- package/src/ext-value-slist.js +0 -2
- package/src/heap/basics.d.ts +89 -0
- package/src/heap/basics.js +42 -5
- package/src/heap/leftist-heap.d.ts +107 -0
- package/src/heap/leftist-heap.js +54 -2
- package/src/heap/min-heap.d.ts +270 -0
- package/src/heap/min-heap.js +186 -2
- package/src/heap/skew-heap.d.ts +105 -0
- package/src/heap/skew-heap.js +54 -2
- package/src/heap.d.ts +3 -0
- package/src/heap.js +0 -2
- package/src/list/basics.d.ts +43 -0
- package/src/list/basics.js +26 -8
- package/src/list/core.d.ts +271 -0
- package/src/list/core.js +162 -7
- package/src/list/ext-value.d.ts +253 -0
- package/src/list/ext-value.js +40 -6
- package/src/list/ext.d.ts +242 -0
- package/src/list/ext.js +148 -10
- package/src/list/nodes.d.ts +336 -0
- package/src/list/nodes.js +141 -3
- package/src/list/ptr.d.ts +72 -0
- package/src/list/ptr.js +44 -2
- package/src/list/value.d.ts +292 -0
- package/src/list/value.js +47 -6
- package/src/list-helpers.d.ts +44 -0
- package/src/list-helpers.js +36 -3
- package/src/list-utils.d.ts +141 -0
- package/src/list-utils.js +89 -3
- package/src/list.d.ts +3 -0
- package/src/list.js +0 -2
- package/src/meta-utils.d.ts +212 -0
- package/src/meta-utils.js +152 -1
- package/src/nt-utils.d.ts +91 -0
- package/src/nt-utils.js +65 -4
- package/src/queue.d.ts +74 -0
- package/src/queue.js +28 -2
- package/src/slist/basics.d.ts +47 -0
- package/src/slist/basics.js +23 -8
- package/src/slist/core.d.ts +251 -0
- package/src/slist/core.js +151 -6
- package/src/slist/ext-value.d.ts +188 -0
- package/src/slist/ext-value.js +35 -6
- package/src/slist/ext.d.ts +182 -0
- package/src/slist/ext.js +114 -12
- package/src/slist/nodes.d.ts +361 -0
- package/src/slist/nodes.js +156 -3
- package/src/slist/ptr.d.ts +73 -0
- package/src/slist/ptr.js +45 -2
- package/src/slist/value.d.ts +246 -0
- package/src/slist/value.js +38 -6
- package/src/slist.d.ts +3 -0
- package/src/slist.js +0 -2
- package/src/stack.d.ts +59 -0
- package/src/stack.js +29 -3
- package/src/tree/splay-tree.d.ts +151 -0
- package/src/tree/splay-tree.js +94 -3
- package/src/value-list.d.ts +3 -0
- package/src/value-list.js +0 -2
- package/src/value-slist.d.ts +3 -0
- package/src/value-slist.js +0 -2
- package/cjs/cache/cache-fifo.js +0 -37
- package/cjs/cache/cache-lfu.js +0 -76
- package/cjs/cache/cache-lru.js +0 -100
- package/cjs/cache/cache-random.js +0 -77
- package/cjs/cache/decorator.js +0 -47
- package/cjs/cache.js +0 -27
- package/cjs/ext-list.js +0 -21
- package/cjs/ext-slist.js +0 -21
- package/cjs/ext-value-list.js +0 -21
- package/cjs/ext-value-slist.js +0 -21
- package/cjs/heap/basics.js +0 -63
- package/cjs/heap/leftist-heap.js +0 -124
- package/cjs/heap/min-heap.js +0 -294
- package/cjs/heap/skew-heap.js +0 -114
- package/cjs/heap.js +0 -21
- package/cjs/list/basics.js +0 -88
- package/cjs/list/core.js +0 -305
- package/cjs/list/ext-value.js +0 -88
- package/cjs/list/ext.js +0 -356
- package/cjs/list/nodes.js +0 -240
- package/cjs/list/ptr.js +0 -61
- package/cjs/list/value.js +0 -99
- package/cjs/list-helpers.js +0 -91
- package/cjs/list-utils.js +0 -141
- package/cjs/list.js +0 -21
- package/cjs/meta-utils.js +0 -171
- package/cjs/nt-utils.js +0 -132
- package/cjs/package.json +0 -1
- package/cjs/queue.js +0 -58
- package/cjs/slist/basics.js +0 -71
- package/cjs/slist/core.js +0 -362
- package/cjs/slist/ext-value.js +0 -82
- package/cjs/slist/ext.js +0 -336
- package/cjs/slist/nodes.js +0 -276
- package/cjs/slist/ptr.js +0 -87
- package/cjs/slist/value.js +0 -90
- package/cjs/slist.js +0 -21
- package/cjs/stack.js +0 -55
- package/cjs/tree/splay-tree.js +0 -362
- package/cjs/value-list.js +0 -21
- package/cjs/value-slist.js +0 -21
package/cjs/slist/ext.js
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = exports.Ptr = exports.ExtSList = void 0;
|
|
7
|
-
var _nodes = require("./nodes.js");
|
|
8
|
-
var _basics = require("./basics.js");
|
|
9
|
-
var _metaUtils = require("../meta-utils.js");
|
|
10
|
-
class Ptr extends _nodes.PtrBase {
|
|
11
|
-
constructor(list, node, prev) {
|
|
12
|
-
super(list, node, prev, ExtSList);
|
|
13
|
-
}
|
|
14
|
-
clone() {
|
|
15
|
-
return new Ptr(this);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
exports.Ptr = Ptr;
|
|
19
|
-
class ExtSList extends _nodes.ExtListBase {
|
|
20
|
-
get ptrRange() {
|
|
21
|
-
return this.head ? {
|
|
22
|
-
from: this.makePtr(),
|
|
23
|
-
to: this.head,
|
|
24
|
-
list: this.head
|
|
25
|
-
} : null;
|
|
26
|
-
}
|
|
27
|
-
makePtr(node) {
|
|
28
|
-
if (node && !this.isNodeLike(node)) throw new Error('"node" is not a compatible node');
|
|
29
|
-
return new Ptr(this, node);
|
|
30
|
-
}
|
|
31
|
-
makePtrFromPrev(prev) {
|
|
32
|
-
if (prev && !this.isNodeLike(prev)) throw new Error('"prev" is not a compatible node');
|
|
33
|
-
return new Ptr(this, null, prev || this.head);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Ptr API
|
|
37
|
-
|
|
38
|
-
removeNodeAfter() {
|
|
39
|
-
return this.head ? this.removeNode(this.makePtr()) : null;
|
|
40
|
-
}
|
|
41
|
-
addAfter(value) {
|
|
42
|
-
const node = this.adoptValue(value);
|
|
43
|
-
if (this.head) {
|
|
44
|
-
(0, _basics.splice)(this, this.head, {
|
|
45
|
-
prevFrom: node
|
|
46
|
-
});
|
|
47
|
-
} else {
|
|
48
|
-
this.head = node;
|
|
49
|
-
}
|
|
50
|
-
return this.makePtr();
|
|
51
|
-
}
|
|
52
|
-
addNodeAfter(node) {
|
|
53
|
-
node = this.adoptNode(node);
|
|
54
|
-
if (this.head) {
|
|
55
|
-
(0, _basics.splice)(this, this.head, {
|
|
56
|
-
prevFrom: node
|
|
57
|
-
});
|
|
58
|
-
} else {
|
|
59
|
-
this.head = node;
|
|
60
|
-
}
|
|
61
|
-
return this.makePtr();
|
|
62
|
-
}
|
|
63
|
-
insertAfter(extList) {
|
|
64
|
-
if (!this.isCompatible(extList)) throw new Error('Incompatible lists');
|
|
65
|
-
const head = extList.head;
|
|
66
|
-
if (head) {
|
|
67
|
-
(0, _basics.splice)(this, this.head, {
|
|
68
|
-
prevFrom: head,
|
|
69
|
-
to: head
|
|
70
|
-
});
|
|
71
|
-
extList.head = null;
|
|
72
|
-
}
|
|
73
|
-
return this.makePtr();
|
|
74
|
-
}
|
|
75
|
-
moveAfter(ptr) {
|
|
76
|
-
if (!this.isCompatiblePtr(ptr)) throw new Error('Incompatible pointer');
|
|
77
|
-
ptr.list = this;
|
|
78
|
-
if (!this.head) {
|
|
79
|
-
this.head = (0, _basics.pop)(this, ptr.prevNode).extracted.to;
|
|
80
|
-
return this;
|
|
81
|
-
}
|
|
82
|
-
if (this.head === ptr.prevNode) return this;
|
|
83
|
-
if (this.head === ptr.prevNode[this.nextName]) {
|
|
84
|
-
if (this.head === this.head[this.nextName]) return this;
|
|
85
|
-
this.head = this.head[this.nextName];
|
|
86
|
-
}
|
|
87
|
-
ptr.prevNode = (0, _basics.splice)(this, this.head, {
|
|
88
|
-
prevFrom: (0, _basics.pop)(this, ptr.prevNode).extracted.to
|
|
89
|
-
});
|
|
90
|
-
return ptr.clone();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// List API
|
|
94
|
-
|
|
95
|
-
clear(drop) {
|
|
96
|
-
if (drop) {
|
|
97
|
-
for (const current of this.getNodeIterator()) {
|
|
98
|
-
current[this.nextName] = current; // make stand-alone
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
this.head = null;
|
|
102
|
-
return this;
|
|
103
|
-
}
|
|
104
|
-
removeNode(ptr) {
|
|
105
|
-
if (!this.head) return null;
|
|
106
|
-
if (!this.isCompatiblePtr(ptr)) throw new Error('Incompatible pointer');
|
|
107
|
-
if (this.head === ptr.prevNode[this.nextName]) {
|
|
108
|
-
if (this.head === this.head[this.nextName]) {
|
|
109
|
-
this.head = null;
|
|
110
|
-
return ptr.prevNode[this.nextName];
|
|
111
|
-
}
|
|
112
|
-
this.head = this.head[this.nextName];
|
|
113
|
-
}
|
|
114
|
-
return (0, _basics.pop)(this, ptr.prevNode).extracted.to;
|
|
115
|
-
}
|
|
116
|
-
removeRange(ptrRange, drop) {
|
|
117
|
-
return this.extractRange(ptrRange).clear(drop);
|
|
118
|
-
}
|
|
119
|
-
extractRange(ptrRange = {}) {
|
|
120
|
-
ptrRange = this.normalizePtrRange(ptrRange.from ? ptrRange : {
|
|
121
|
-
...ptrRange,
|
|
122
|
-
from: this.makePtr()
|
|
123
|
-
});
|
|
124
|
-
ptrRange.to ||= this.head;
|
|
125
|
-
const prevFrom = ptrRange.from.prevNode,
|
|
126
|
-
to = ptrRange.to,
|
|
127
|
-
extracted = this.make();
|
|
128
|
-
if (!this.head) return extracted;
|
|
129
|
-
if (this.head === prevFrom[this.nextName] || this.head === to) this.head = to[this.nextName];
|
|
130
|
-
if (this.head === prevFrom[this.nextName]) this.head = null;
|
|
131
|
-
extracted.head = (0, _basics.extract)(this, {
|
|
132
|
-
prevFrom,
|
|
133
|
-
to
|
|
134
|
-
}).extracted.prevFrom[this.nextName];
|
|
135
|
-
return extracted;
|
|
136
|
-
}
|
|
137
|
-
extractBy(condition) {
|
|
138
|
-
const extracted = this.make();
|
|
139
|
-
if (this.isEmpty) return extracted;
|
|
140
|
-
const rest = this.make();
|
|
141
|
-
for (const current of this.getNodeIterator()) {
|
|
142
|
-
current[this.nextName] = current; // make stand-alone
|
|
143
|
-
if (condition(current)) {
|
|
144
|
-
extracted.addAfter(current);
|
|
145
|
-
extracted.next();
|
|
146
|
-
} else {
|
|
147
|
-
rest.addAfter(current);
|
|
148
|
-
rest.next();
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
extracted.next();
|
|
152
|
-
rest.next();
|
|
153
|
-
this.head = rest.head;
|
|
154
|
-
return extracted;
|
|
155
|
-
}
|
|
156
|
-
reverse() {
|
|
157
|
-
if (this.isOneOrEmpty) return this;
|
|
158
|
-
let prev = this.head,
|
|
159
|
-
current = prev[this.nextName];
|
|
160
|
-
do {
|
|
161
|
-
const next = current[this.nextName];
|
|
162
|
-
current[this.nextName] = prev;
|
|
163
|
-
prev = current;
|
|
164
|
-
current = next;
|
|
165
|
-
} while (current !== this.head);
|
|
166
|
-
this.head[this.nextName] = prev;
|
|
167
|
-
this.head = this.head[this.nextName];
|
|
168
|
-
return this;
|
|
169
|
-
}
|
|
170
|
-
sort(lessFn) {
|
|
171
|
-
if (this.isOneOrEmpty) return this;
|
|
172
|
-
const leftHead = {},
|
|
173
|
-
rightHead = {};
|
|
174
|
-
leftHead[this.nextName] = leftHead;
|
|
175
|
-
rightHead[this.nextName] = rightHead;
|
|
176
|
-
const left = this.make(leftHead),
|
|
177
|
-
right = this.make(rightHead);
|
|
178
|
-
|
|
179
|
-
// split into two sublists
|
|
180
|
-
let isLeft = true;
|
|
181
|
-
for (const current of this.getNodeIterator()) {
|
|
182
|
-
current[this.nextName] = current; // make stand-alone
|
|
183
|
-
if (isLeft) {
|
|
184
|
-
left.addNodeAfter(current);
|
|
185
|
-
left.next();
|
|
186
|
-
} else {
|
|
187
|
-
right.addNodeAfter(current);
|
|
188
|
-
right.next();
|
|
189
|
-
}
|
|
190
|
-
isLeft = !isLeft;
|
|
191
|
-
}
|
|
192
|
-
left.removeNodeAfter(); // remove the head node
|
|
193
|
-
right.removeNodeAfter(); // remove the head node
|
|
194
|
-
this.clear();
|
|
195
|
-
// the list is empty now
|
|
196
|
-
|
|
197
|
-
// sort sublists
|
|
198
|
-
left.next().sort(lessFn);
|
|
199
|
-
right.next().sort(lessFn);
|
|
200
|
-
|
|
201
|
-
// merge sublists
|
|
202
|
-
const leftIterator = left.getNodeIterator()[Symbol.iterator](),
|
|
203
|
-
rightIterator = right.getNodeIterator()[Symbol.iterator]();
|
|
204
|
-
let leftItem = leftIterator.next(),
|
|
205
|
-
rightItem = rightIterator.next();
|
|
206
|
-
while (!leftItem.done && !rightItem.done) {
|
|
207
|
-
let node;
|
|
208
|
-
if (lessFn(leftItem.value, rightItem.value)) {
|
|
209
|
-
node = leftItem.value;
|
|
210
|
-
leftItem = leftIterator.next();
|
|
211
|
-
} else {
|
|
212
|
-
node = rightItem.value;
|
|
213
|
-
rightItem = rightIterator.next();
|
|
214
|
-
}
|
|
215
|
-
node[this.nextName] = node; // make stand-alone
|
|
216
|
-
this.addNodeAfter(node);
|
|
217
|
-
this.next();
|
|
218
|
-
}
|
|
219
|
-
for (; !leftItem.done; this.next(), leftItem = leftIterator.next()) {
|
|
220
|
-
const node = leftItem.value;
|
|
221
|
-
node[this.nextName] = node; // make stand-alone
|
|
222
|
-
this.addNodeAfter(node);
|
|
223
|
-
}
|
|
224
|
-
for (; !rightItem.done; this.next(), rightItem = rightIterator.next()) {
|
|
225
|
-
const node = rightItem.value;
|
|
226
|
-
node[this.nextName] = node; // make stand-alone
|
|
227
|
-
this.addNodeAfter(node);
|
|
228
|
-
}
|
|
229
|
-
return this.next();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// iterators
|
|
233
|
-
|
|
234
|
-
[Symbol.iterator]() {
|
|
235
|
-
let current = this.head,
|
|
236
|
-
readyToStop = this.isEmpty;
|
|
237
|
-
return (0, _metaUtils.normalizeIterator)({
|
|
238
|
-
next: () => {
|
|
239
|
-
if (readyToStop && current === this.head) return {
|
|
240
|
-
done: true
|
|
241
|
-
};
|
|
242
|
-
readyToStop = true;
|
|
243
|
-
const value = current;
|
|
244
|
-
current = current[this.nextName];
|
|
245
|
-
return {
|
|
246
|
-
value
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
getNodeIterator(range = {}) {
|
|
252
|
-
range = this.normalizeRange(range);
|
|
253
|
-
const {
|
|
254
|
-
from,
|
|
255
|
-
to
|
|
256
|
-
} = range;
|
|
257
|
-
return {
|
|
258
|
-
[Symbol.iterator]: () => {
|
|
259
|
-
let readyToStop = this.isEmpty,
|
|
260
|
-
current = readyToStop ? null : from || this.head;
|
|
261
|
-
const stop = readyToStop ? null : to ? to[this.nextName] : this.head;
|
|
262
|
-
return (0, _metaUtils.normalizeIterator)({
|
|
263
|
-
next: () => {
|
|
264
|
-
if (readyToStop && current === stop) return {
|
|
265
|
-
done: true
|
|
266
|
-
};
|
|
267
|
-
readyToStop = true;
|
|
268
|
-
const value = current;
|
|
269
|
-
current = current[this.nextName];
|
|
270
|
-
return {
|
|
271
|
-
value
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
getPtrIterator(range) {
|
|
279
|
-
if (!ptrRange.from) ptrRange = Object.assign({
|
|
280
|
-
from: this.frontPtr
|
|
281
|
-
}, ptrRange);
|
|
282
|
-
ptrRange = this.normalizePtrRange(ptrRange);
|
|
283
|
-
const {
|
|
284
|
-
from: fromPtr,
|
|
285
|
-
to
|
|
286
|
-
} = ptrRange;
|
|
287
|
-
return {
|
|
288
|
-
[Symbol.iterator]: () => {
|
|
289
|
-
let current = fromPtr.clone(),
|
|
290
|
-
readyToStop = this.isEmpty;
|
|
291
|
-
const stop = to ? to[this.nextName] : this;
|
|
292
|
-
return (0, _metaUtils.normalizeIterator)({
|
|
293
|
-
next: () => {
|
|
294
|
-
if (readyToStop && current.node === stop) return {
|
|
295
|
-
done: true
|
|
296
|
-
};
|
|
297
|
-
readyToStop = true;
|
|
298
|
-
const value = current.clone();
|
|
299
|
-
current = current.next();
|
|
300
|
-
return {
|
|
301
|
-
value
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// meta helpers
|
|
310
|
-
|
|
311
|
-
clone() {
|
|
312
|
-
return new ExtSList(this);
|
|
313
|
-
}
|
|
314
|
-
make(head = null) {
|
|
315
|
-
return new ExtSList(head, this);
|
|
316
|
-
}
|
|
317
|
-
makeFrom(values) {
|
|
318
|
-
return ExtSList.from(values, this);
|
|
319
|
-
}
|
|
320
|
-
static from(values, options) {
|
|
321
|
-
const list = new ExtSList(null, options);
|
|
322
|
-
for (const value of values) {
|
|
323
|
-
list.addNodeAfter(value);
|
|
324
|
-
list.next();
|
|
325
|
-
}
|
|
326
|
-
return list.next();
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
exports.ExtSList = ExtSList;
|
|
330
|
-
ExtSList.Ptr = Ptr;
|
|
331
|
-
(0, _metaUtils.addAliases)(ExtSList.prototype, {
|
|
332
|
-
addAfter: 'add',
|
|
333
|
-
removeNodeAfter: 'removeAfter',
|
|
334
|
-
getNodeIterator: 'getIterator'
|
|
335
|
-
});
|
|
336
|
-
var _default = exports.default = ExtSList;
|
package/cjs/slist/nodes.js
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.isStandAlone = exports.isNodeLike = exports.isCompatible = exports.ValueNode = exports.PtrBase = exports.Node = exports.HeadNode = exports.ExtListBase = void 0;
|
|
7
|
-
var _listHelpers = require("../list-helpers.js");
|
|
8
|
-
var _metaUtils = require("../meta-utils.js");
|
|
9
|
-
const isNodeLike = ({
|
|
10
|
-
nextName
|
|
11
|
-
}, node) => node && node[nextName];
|
|
12
|
-
exports.isNodeLike = isNodeLike;
|
|
13
|
-
const isStandAlone = ({
|
|
14
|
-
nextName
|
|
15
|
-
}, node) => node && node[nextName] === node;
|
|
16
|
-
exports.isStandAlone = isStandAlone;
|
|
17
|
-
const isCompatible = (options1, options2) => options1.nextName === options2.nextName;
|
|
18
|
-
exports.isCompatible = isCompatible;
|
|
19
|
-
class Node {
|
|
20
|
-
constructor({
|
|
21
|
-
nextName = 'next'
|
|
22
|
-
} = {}) {
|
|
23
|
-
this.nextName = nextName;
|
|
24
|
-
this[nextName] = this;
|
|
25
|
-
}
|
|
26
|
-
get isStandAlone() {
|
|
27
|
-
return this[this.nextName] === this;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.Node = Node;
|
|
31
|
-
class HeadNode extends Node {
|
|
32
|
-
constructor(options) {
|
|
33
|
-
super(options);
|
|
34
|
-
this.last = this;
|
|
35
|
-
}
|
|
36
|
-
isNodeLike(node) {
|
|
37
|
-
if (!node) return false;
|
|
38
|
-
const next = node[this.nextName];
|
|
39
|
-
return next && _metaUtils.canHaveProps[typeof next] === 1;
|
|
40
|
-
}
|
|
41
|
-
isCompatibleNames({
|
|
42
|
-
nextName
|
|
43
|
-
}) {
|
|
44
|
-
return this.nextName === nextName;
|
|
45
|
-
}
|
|
46
|
-
isCompatible(list) {
|
|
47
|
-
return list === this || list instanceof HeadNode && this.nextName === list.nextName;
|
|
48
|
-
}
|
|
49
|
-
isCompatiblePtr(ptr) {
|
|
50
|
-
return ptr instanceof PtrBase && (ptr.list === this || ptr.list instanceof HeadNode && this.nextName === ptr.list.nextName);
|
|
51
|
-
}
|
|
52
|
-
isCompatibleRange(range) {
|
|
53
|
-
return (0, _listHelpers.isRangeLike)(this, range);
|
|
54
|
-
}
|
|
55
|
-
get isEmpty() {
|
|
56
|
-
return this[this.nextName] === this;
|
|
57
|
-
}
|
|
58
|
-
get isOne() {
|
|
59
|
-
return this[this.nextName] !== this && this[this.nextName][this.nextName] === this;
|
|
60
|
-
}
|
|
61
|
-
get isOneOrEmpty() {
|
|
62
|
-
return this[this.nextName][this.nextName] === this;
|
|
63
|
-
}
|
|
64
|
-
get head() {
|
|
65
|
-
return this;
|
|
66
|
-
}
|
|
67
|
-
get front() {
|
|
68
|
-
return this[this.nextName];
|
|
69
|
-
}
|
|
70
|
-
get back() {
|
|
71
|
-
return this.last;
|
|
72
|
-
}
|
|
73
|
-
get range() {
|
|
74
|
-
return this[this.nextName] === this ? null : {
|
|
75
|
-
from: this[this.nextName],
|
|
76
|
-
to: this.last,
|
|
77
|
-
list: this
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
getLength() {
|
|
81
|
-
let n = 0;
|
|
82
|
-
for (let p = this[this.nextName]; p !== this; ++n, p = p[this.nextName]);
|
|
83
|
-
return n;
|
|
84
|
-
}
|
|
85
|
-
adoptNode(nodeOrPtr) {
|
|
86
|
-
const isPtr = nodeOrPtr instanceof PtrBase;
|
|
87
|
-
if (isPtr && !this.isCompatiblePtr(nodeOrPtr)) throw new Error('Incompatible pointer');
|
|
88
|
-
const node = isPtr ? nodeOrPtr.node : nodeOrPtr;
|
|
89
|
-
if (node[this.nextName]) {
|
|
90
|
-
if (node[this.nextName] === node) return node;
|
|
91
|
-
throw new Error('node is already a part of a list, or there is a name clash');
|
|
92
|
-
}
|
|
93
|
-
node[this.nextName] = node;
|
|
94
|
-
if (isPtr) {
|
|
95
|
-
nodeOrPtr.list = this;
|
|
96
|
-
nodeOrPtr.prevNode = node;
|
|
97
|
-
}
|
|
98
|
-
return node;
|
|
99
|
-
}
|
|
100
|
-
normalizeNode(nodeOrPtr) {
|
|
101
|
-
const node = (0, _listHelpers.normalizeNode)(this, nodeOrPtr, PtrBase);
|
|
102
|
-
if (nodeOrPtr instanceof PtrBase) nodeOrPtr.list = this;
|
|
103
|
-
return node;
|
|
104
|
-
}
|
|
105
|
-
normalizeRange(range) {
|
|
106
|
-
return (0, _listHelpers.normalizeRange)(this, range, PtrBase);
|
|
107
|
-
}
|
|
108
|
-
normalizePtrRange(range) {
|
|
109
|
-
return (0, _listHelpers.normalizePtrRange)(this, range, PtrBase);
|
|
110
|
-
}
|
|
111
|
-
syncLast() {
|
|
112
|
-
this.last = this;
|
|
113
|
-
while (this.last[this.nextName] !== this) this.last = this.last[this.nextName];
|
|
114
|
-
return this;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
exports.HeadNode = HeadNode;
|
|
118
|
-
(0, _metaUtils.addAlias)(HeadNode.prototype, 'adoptNode', 'adoptValue');
|
|
119
|
-
class ValueNode extends Node {
|
|
120
|
-
constructor(value, options) {
|
|
121
|
-
super(options);
|
|
122
|
-
this.value = value;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
exports.ValueNode = ValueNode;
|
|
126
|
-
class PtrBase {
|
|
127
|
-
constructor(list, node, prev, ListClass) {
|
|
128
|
-
if (list instanceof PtrBase) {
|
|
129
|
-
this.list = list.list;
|
|
130
|
-
this.node = list.node;
|
|
131
|
-
this.prevNode = list.prevNode;
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (!(list instanceof ListClass)) throw new Error('"list" is not a compatible list');
|
|
135
|
-
if (node instanceof PtrBase) {
|
|
136
|
-
if (list !== node.list) throw new Error('Node specified by a pointer must belong to the same list');
|
|
137
|
-
this.list = list;
|
|
138
|
-
this.node = node.node;
|
|
139
|
-
this.prevNode = node.prevNode;
|
|
140
|
-
} else {
|
|
141
|
-
this.list = list;
|
|
142
|
-
this.node = node;
|
|
143
|
-
this.prevNode = prev;
|
|
144
|
-
}
|
|
145
|
-
// check nodes
|
|
146
|
-
if (this.node && !isNodeLike(this.list, this.node)) throw new Error('"node" is not a compatible node');
|
|
147
|
-
if (this.prevNode && !isNodeLike(this.list, this.prevNode)) throw new Error('"prev" is not a compatible node');
|
|
148
|
-
// initialize missing nodes
|
|
149
|
-
if (this.node) {
|
|
150
|
-
if (!this.prevNode) this.prevNode = this.node;
|
|
151
|
-
} else {
|
|
152
|
-
if (!this.prevNode) this.prevNode = this.list.head;
|
|
153
|
-
if (this.prevNode) this.node = this.prevNode[this.list.nextName];
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
get nextNode() {
|
|
157
|
-
return this.node[this.list.nextName];
|
|
158
|
-
}
|
|
159
|
-
isPrevNodeValid() {
|
|
160
|
-
if (!this.prevNode) this.prevNode = this.node;
|
|
161
|
-
if (this.prevNode[this.list.nextName] === this.node) return true;
|
|
162
|
-
this.prevNode = this.node;
|
|
163
|
-
if (this.prevNode[this.list.nextName] === this.node) return true;
|
|
164
|
-
this.prevNode = this.prevNode[this.list.nextName];
|
|
165
|
-
if (this.prevNode[this.list.nextName] === this.node) return true;
|
|
166
|
-
this.prevNode = this.list.head;
|
|
167
|
-
if (this.prevNode[this.list.nextName] === this.node) return true;
|
|
168
|
-
this.prevNode = this.node;
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
next() {
|
|
172
|
-
this.prevNode = this.node;
|
|
173
|
-
this.node = this.node[this.list.nextName];
|
|
174
|
-
return this;
|
|
175
|
-
}
|
|
176
|
-
prev() {
|
|
177
|
-
if (!this.isPrevNodeValid()) throw new Error('Cannot get previous node: "prevNode" is invalid');
|
|
178
|
-
this.node = this.prevNode;
|
|
179
|
-
return this;
|
|
180
|
-
}
|
|
181
|
-
syncPrev() {
|
|
182
|
-
if (this.isPrevNodeValid()) return this;
|
|
183
|
-
this.prevNode = this.node;
|
|
184
|
-
do {
|
|
185
|
-
const next = this.prevNode[this.list.nextName];
|
|
186
|
-
if (next === this.node) break;
|
|
187
|
-
this.prevNode = next;
|
|
188
|
-
} while (this.prevNode !== this.node);
|
|
189
|
-
return this;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
exports.PtrBase = PtrBase;
|
|
193
|
-
class ExtListBase {
|
|
194
|
-
constructor(head = null, {
|
|
195
|
-
nextName = 'next'
|
|
196
|
-
} = {}) {
|
|
197
|
-
if (head instanceof ExtListBase) {
|
|
198
|
-
this.nextName = head.nextName;
|
|
199
|
-
this.attach(head.head);
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (head instanceof PtrBase) {
|
|
203
|
-
this.nextName = head.list.nextName;
|
|
204
|
-
this.attach(head.node);
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
this.nextName = nextName;
|
|
208
|
-
this.attach(head);
|
|
209
|
-
}
|
|
210
|
-
isCompatible(list) {
|
|
211
|
-
return list === this || list instanceof ExtListBase && this.nextName === list.nextName;
|
|
212
|
-
}
|
|
213
|
-
isCompatiblePtr(ptr) {
|
|
214
|
-
return ptr instanceof PtrBase && (ptr.list === this || ptr.list instanceof ExtListBase && this.nextName === ptr.list.nextName);
|
|
215
|
-
}
|
|
216
|
-
get isEmpty() {
|
|
217
|
-
return !this.head;
|
|
218
|
-
}
|
|
219
|
-
get isOne() {
|
|
220
|
-
return this.head && this.head[this.nextName] === this.head;
|
|
221
|
-
}
|
|
222
|
-
get isOneOrEmpty() {
|
|
223
|
-
return !this.head || this.head[this.nextName] === this.head;
|
|
224
|
-
}
|
|
225
|
-
get front() {
|
|
226
|
-
return this.head;
|
|
227
|
-
}
|
|
228
|
-
get range() {
|
|
229
|
-
return this.head ? {
|
|
230
|
-
from: this.head[this.nextName],
|
|
231
|
-
to: this.head,
|
|
232
|
-
list: this.head
|
|
233
|
-
} : null;
|
|
234
|
-
}
|
|
235
|
-
getLength() {
|
|
236
|
-
if (!this.head) return 0;
|
|
237
|
-
let n = 0,
|
|
238
|
-
current = this.head;
|
|
239
|
-
do {
|
|
240
|
-
current = current[this.nextName];
|
|
241
|
-
++n;
|
|
242
|
-
} while (current !== this.head);
|
|
243
|
-
return n;
|
|
244
|
-
}
|
|
245
|
-
getBack() {
|
|
246
|
-
if (!this.head) return null;
|
|
247
|
-
for (let current = this.head;;) {
|
|
248
|
-
const next = current[this.nextName];
|
|
249
|
-
if (next === this.head) return current;
|
|
250
|
-
current = next;
|
|
251
|
-
}
|
|
252
|
-
// unreachable
|
|
253
|
-
}
|
|
254
|
-
attach(head = null) {
|
|
255
|
-
const oldHead = this.head;
|
|
256
|
-
if (head instanceof PtrBase) {
|
|
257
|
-
if (!this.isCompatible(head.list)) throw new Error('Incompatible lists');
|
|
258
|
-
this.head = head.node;
|
|
259
|
-
} else {
|
|
260
|
-
if (head && !this.isNodeLike(head)) throw new Error('"head" is not a compatible node');
|
|
261
|
-
this.head = head;
|
|
262
|
-
}
|
|
263
|
-
return oldHead;
|
|
264
|
-
}
|
|
265
|
-
detach() {
|
|
266
|
-
const oldHead = this.head;
|
|
267
|
-
this.head = null;
|
|
268
|
-
return oldHead;
|
|
269
|
-
}
|
|
270
|
-
next() {
|
|
271
|
-
if (this.head) this.head = this.head[this.nextName];
|
|
272
|
-
return this;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
exports.ExtListBase = ExtListBase;
|
|
276
|
-
(0, _metaUtils.copyDescriptors)(ExtListBase.prototype, HeadNode.prototype, ['isNodeLike', 'isCompatibleNames', 'isCompatibleRange', 'normalizeNode', 'normalizeRange', 'normalizePtrRange', 'adoptNode', 'adoptValue']);
|
package/cjs/slist/ptr.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = exports.Ptr = void 0;
|
|
7
|
-
var _nodes = require("./nodes.js");
|
|
8
|
-
var _basics = require("./basics.js");
|
|
9
|
-
class Ptr extends _nodes.PtrBase {
|
|
10
|
-
constructor(list, node, prev) {
|
|
11
|
-
super(list, node, prev, _nodes.HeadNode);
|
|
12
|
-
}
|
|
13
|
-
get isHead() {
|
|
14
|
-
return this.node === this.list;
|
|
15
|
-
}
|
|
16
|
-
clone() {
|
|
17
|
-
return new Ptr(this);
|
|
18
|
-
}
|
|
19
|
-
removeCurrent() {
|
|
20
|
-
if (!this.isPrevNodeValid()) throw new Error('Current node cannot be removed: "prevNode" is invalid');
|
|
21
|
-
if (this.node === this.list || this.node === this.prevNode) return null;
|
|
22
|
-
if (this.list.last === this.node) this.list.last = this.prevNode;
|
|
23
|
-
const node = (0, _basics.pop)(this.list, this.prevNode).extracted.to;
|
|
24
|
-
this.node = this.prevNode[this.list.nextName];
|
|
25
|
-
return node;
|
|
26
|
-
}
|
|
27
|
-
addBefore(value) {
|
|
28
|
-
if (!this.isPrevNodeValid()) throw new Error('Cannot be added before: "prevNode" is invalid');
|
|
29
|
-
const node = this.list.adoptValue(value),
|
|
30
|
-
prev = (0, _basics.splice)(this.list, this.prevNode, {
|
|
31
|
-
prevFrom: node
|
|
32
|
-
});
|
|
33
|
-
this.prevNode = node;
|
|
34
|
-
if (this.list.last === this.list) this.list.last = node;
|
|
35
|
-
return this.list.makePtr(prev);
|
|
36
|
-
}
|
|
37
|
-
addNodeBefore(node) {
|
|
38
|
-
if (!this.isPrevNodeValid()) throw new Error('Cannot be added before: "prevNode" is invalid');
|
|
39
|
-
node = this.list.adoptNode(node);
|
|
40
|
-
const prev = (0, _basics.splice)(this.list, this.prevNode, {
|
|
41
|
-
prevFrom: node
|
|
42
|
-
});
|
|
43
|
-
this.prevNode = node;
|
|
44
|
-
if (this.list.last === this.list) this.list.last = node;
|
|
45
|
-
return this.list.makePtr(prev);
|
|
46
|
-
}
|
|
47
|
-
addAfter(value) {
|
|
48
|
-
const node = this.list.adoptValue(value),
|
|
49
|
-
prev = (0, _basics.splice)(this.list, this.node, {
|
|
50
|
-
prevFrom: node
|
|
51
|
-
});
|
|
52
|
-
return this.list.makePtr(prev);
|
|
53
|
-
}
|
|
54
|
-
addNodeAfter(node) {
|
|
55
|
-
node = this.list.adoptNode(node);
|
|
56
|
-
const prev = (0, _basics.splice)(this.list, this.node, {
|
|
57
|
-
prevFrom: node
|
|
58
|
-
});
|
|
59
|
-
return this.list.makePtr(prev);
|
|
60
|
-
}
|
|
61
|
-
insertBefore(list) {
|
|
62
|
-
if (!this.isPrevNodeValid()) throw new Error('Cannot be inserted before: "prevNode" is invalid');
|
|
63
|
-
if (!this.list.isCompatible(list)) throw new Error('Incompatible lists');
|
|
64
|
-
if (list.isEmpty) return this;
|
|
65
|
-
const prev = (0, _basics.splice)(this.list, this.prevNode, {
|
|
66
|
-
prevFrom: list,
|
|
67
|
-
to: list.last
|
|
68
|
-
});
|
|
69
|
-
if (this.list.last === this.list) this.list.last = list.last;
|
|
70
|
-
this.prevNode = list.last;
|
|
71
|
-
list.last = list;
|
|
72
|
-
return this.list.makePtr(prev);
|
|
73
|
-
}
|
|
74
|
-
insertAfter(list) {
|
|
75
|
-
if (!this.list.isCompatible(list)) throw new Error('Incompatible lists');
|
|
76
|
-
if (list.isEmpty) return this;
|
|
77
|
-
const prev = (0, _basics.splice)(this.list, this.prevNode[this.list.nextName], {
|
|
78
|
-
prevFrom: list,
|
|
79
|
-
to: list.last
|
|
80
|
-
});
|
|
81
|
-
if (this.list.last === this.prevNode) this.list.last = list.last;
|
|
82
|
-
list.last = list;
|
|
83
|
-
return this.list.makePtr(prev);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
exports.Ptr = Ptr;
|
|
87
|
-
var _default = exports.default = Ptr;
|