145 lines
2.5 KiB
JavaScript
145 lines
2.5 KiB
JavaScript
import { SequenceContainer } from "./containers/Sequence"
|
|
import { BidirectionalIterator } from "./iterators/Bidirectional"
|
|
import { mixinClasses } from "./utils/mixin"
|
|
|
|
export class List {
|
|
|
|
constructor(...args) {
|
|
this._end = new ListIterator(new ListItem())
|
|
this._begin = this._end
|
|
this._size = 0
|
|
if (args.length >= 1) {
|
|
this.assign(...args)
|
|
}
|
|
}
|
|
|
|
move(rhs) {
|
|
this._begin = rhs._begin
|
|
this._end = rhs._end
|
|
this._size = rhs._size
|
|
rhs._begin = undefined
|
|
rhs._end = undefined
|
|
rhs._size = 0
|
|
return this
|
|
}
|
|
|
|
size() {
|
|
return this._size
|
|
}
|
|
|
|
begin() {
|
|
return this._begin.clone()
|
|
}
|
|
|
|
end() {
|
|
return this._end.clone()
|
|
}
|
|
|
|
resize(size, value) {
|
|
if (this._size > size)
|
|
while (this._size !== size)
|
|
this.popBack()
|
|
|
|
else
|
|
while (this._size !== size)
|
|
this.pushBack(value)
|
|
}
|
|
|
|
_shiftRight(dest, generator) {
|
|
let prev, res, new_item, item = dest.deref()
|
|
|
|
for (const value of generator) {
|
|
prev = item._prev
|
|
new_item = new ListItem(value)
|
|
res = res ?? new_item
|
|
|
|
item._prev = new_item
|
|
new_item._next = item
|
|
new_item._prev = prev
|
|
if (prev) {
|
|
prev._next = new_item
|
|
} else {
|
|
this._begin = new ListIterator(res)
|
|
}
|
|
this._size++
|
|
}
|
|
|
|
return new ListIterator(res ?? dest.deref())
|
|
}
|
|
|
|
_shiftLeft(dest, generator) {
|
|
let item = dest.deref(), start_item = item
|
|
|
|
for (const _ of generator) {
|
|
item = item._prev
|
|
this._size--
|
|
}
|
|
if (item._prev) {
|
|
item._prev._next = start_item
|
|
} else {
|
|
this._begin = new ListIterator(start_item)
|
|
}
|
|
start_item._prev = item._prev
|
|
|
|
return dest
|
|
}
|
|
}
|
|
|
|
List.from = function(obj) {
|
|
const list = new List()
|
|
for (const value of obj) {
|
|
list.pushBack(value)
|
|
}
|
|
return list
|
|
}
|
|
|
|
mixinClasses(List, SequenceContainer)
|
|
|
|
export class ListItem {
|
|
|
|
constructor(value) {
|
|
this.value = value
|
|
this._next = undefined
|
|
this._prev = undefined
|
|
}
|
|
|
|
get next() { return this._next }
|
|
get prev() { return this._prev }
|
|
}
|
|
|
|
export class ListIterator {
|
|
|
|
constructor(item) {
|
|
this._item = item
|
|
}
|
|
|
|
clone() {
|
|
return new ListIterator(this._item)
|
|
}
|
|
|
|
copy(rhs) {
|
|
this._item = rhs._item
|
|
return this
|
|
}
|
|
|
|
deref() {
|
|
return this._item
|
|
}
|
|
|
|
eq(rhs) {
|
|
return this._item == rhs._item
|
|
}
|
|
|
|
inc() {
|
|
this._item = this._item.next
|
|
return this
|
|
}
|
|
|
|
dec() {
|
|
this._item = this._item.prev
|
|
return this
|
|
}
|
|
}
|
|
|
|
mixinClasses(ListIterator, BidirectionalIterator)
|