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 } get value() { return this.deref().value } set value(value) { return this.deref().value = value } 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)