UNPKG

astl

Version:

AssemblyScript-STL (Standard Template Library, migrated from the C++)

414 lines (355 loc) 13.6 kB
import { IMapContainer } from "./IMapContainer"; import { IForwardIterator } from "../../../iterator/IForwardIterator"; import { ReverseIteratorBase as ReverseBase } from "../../iterator/ReverseIteratorBase"; import { IPair } from "../../../utility/IPair"; import { Entry } from "../../../utility/Entry"; import { Repeater } from "../../iterator/disposable/Repeater"; import { distance } from "../../../iterator/global"; export class MapElementList<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, MapElementList.Iterator<Key, T, Unique, SourceT>, MapElementList.ReverseIterator<Key, T, Unique, SourceT>>> { private size_: usize = 0; private sequence_: usize = 0; private source_: SourceT; private end_: MapElementList.Iterator<Key, T, Unique, SourceT> = MapElementList.Iterator._Create(this, this.sequence_++, null, null, changetype<Entry<Key, T>>(0)); private begin_: MapElementList.Iterator<Key, T, Unique, SourceT> = this.end_; /* --------------------------------------------------------- CONSTRUCTORS --------------------------------------------------------- */ public constructor(source: SourceT) { this.source_ = source; } public clear(): void { MapElementList.Iterator._Set_prev<Key, T, Unique, SourceT>(this.end_, this.end_); MapElementList.Iterator._Set_next<Key, T, Unique, SourceT>(this.end_, this.end_); this.begin_ = this.end_; this.size_ = 0; } /* --------------------------------------------------------- ACCCESSORS --------------------------------------------------------- */ @inline public source(): SourceT { return this.source_; } @inline public size(): usize { return this.size_; } @inline public empty(): boolean { return this.size() === 0; } @inline public begin(): MapElementList.Iterator<Key, T, Unique, SourceT> { return this.begin_; } @inline public end(): MapElementList.Iterator<Key, T, Unique, SourceT> { return this.end_; } @inline public rbegin(): MapElementList.ReverseIterator<Key, T, Unique, SourceT> { return this.end().reverse(); } @inline public rend(): MapElementList.ReverseIterator<Key, T, Unique, SourceT> { return this.begin().reverse(); } @inline public front(): Entry<Key, T> { return this.begin().value; } @inline public back(): Entry<Key, T> { return this.end().prev().value; } /* =============================================================== ELEMENTS I/O - INSERT - ERASE - SWAP ================================================================== INSERT --------------------------------------------------------------- */ @inline public push_front(val: Entry<Key, T>): void { this.insert(this.begin(), val); } @inline public push_back(val: Entry<Key, T>): void { this.insert(this.end(), val); } public insert(pos: MapElementList.Iterator<Key, T, Unique, SourceT>, value: Entry<Key, T>): MapElementList.Iterator<Key, T, Unique, SourceT> { const prev: MapElementList.Iterator<Key, T, Unique, SourceT> = pos.prev(); const it: MapElementList.Iterator<Key, T, Unique, SourceT> = MapElementList.Iterator._Create(this, this.sequence_++, prev, pos, value); MapElementList.Iterator._Set_next<Key, T, Unique, SourceT>(prev, it); MapElementList.Iterator._Set_prev<Key, T, Unique, SourceT>(pos, it); if (pos === this.begin_) this.begin_ = it; ++this.size_; return it; } public insert_repeatedly<InputT extends IPair<Key, T>> (pos: MapElementList.Iterator<Key, T, Unique, SourceT>, n: usize, val: InputT): MapElementList.Iterator<Key, T, Unique, SourceT> { const first: Repeater<InputT> = new Repeater(0, val); const last: Repeater<InputT> = new Repeater(n, null!); return this.insert_range(pos, first, last); } public insert_range<InputIterator extends IForwardIterator<IPair<Key, T>, InputIterator>> (pos: MapElementList.Iterator<Key, T, Unique, SourceT>, first: InputIterator, last: InputIterator): MapElementList.Iterator<Key, T, Unique, SourceT> { // PREPARE ASSETS let prev: MapElementList.Iterator<Key, T, Unique, SourceT> = pos.prev(); let top: MapElementList.Iterator<Key, T, Unique, SourceT> | null = null; let size: usize = 0; // ITERATE THE NEW ELEMENTS for (; first != last; first = first.next()) { const entry: Entry<Key, T> = new Entry(first.value.first, first.value.second); const it: MapElementList.Iterator<Key, T, Unique, SourceT> = MapElementList.Iterator._Create(this, this.sequence_++, prev, null, entry); if (top === null) top = it; MapElementList.Iterator._Set_next(prev, it); prev = it; ++size; } if (size === 0) return pos; // RETURNS WITH FINALIZATION MapElementList.Iterator._Set_next(prev, top!); MapElementList.Iterator._Set_prev(pos, top!); if (pos === this.begin_) this.begin_ = top!; this.size_ += size; return top!; } /* --------------------------------------------------------------- ERASE --------------------------------------------------------------- */ @inline public pop_front(): void { this.erase(this.begin()); } @inline public pop_back(): void { this.erase(this.end().prev()); } public erase(first: MapElementList.Iterator<Key, T, Unique, SourceT>, last: MapElementList.Iterator<Key, T, Unique, SourceT> = first.next()): MapElementList.Iterator<Key, T, Unique, SourceT> { const prev: MapElementList.Iterator<Key, T, Unique, SourceT> = first.prev(); const length: usize = distance(first, last); MapElementList.Iterator._Set_next<Key, T, Unique, SourceT>(prev, last); MapElementList.Iterator._Set_prev<Key, T, Unique, SourceT>(last, prev); this.size_ -= length; return last; } /* --------------------------------------------------------------- SWAP --------------------------------------------------------------- */ public swap(obj: MapElementList<Key, T, Unique, SourceT>): void { const source: SourceT = this.source_; this.source_ = obj.source_; obj.source_ = source; } } export namespace MapElementList { export class Iterator<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>>> { private readonly container_: MapElementList<Key, T, Unique, SourceT>; private readonly uid_: usize; private erased_: boolean; private prev_: Iterator<Key, T, Unique, SourceT> | null; private next_: Iterator<Key, T, Unique, SourceT> | null; private readonly value_: Entry<Key, T>; /* --------------------------------------------------------------- CONSTRUCTORS --------------------------------------------------------------- */ private constructor ( container: MapElementList<Key, T, Unique, SourceT>, uid: usize, prev: Iterator<Key, T, Unique, SourceT> | null, next: Iterator<Key, T, Unique, SourceT> | null, value: Entry<Key, T> ) { this.container_ = container; this.uid_ = uid; this.erased_ = false; this.prev_ = prev; this.next_ = next; this.value_ = value; } @inline public static _Create<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>>> ( container: MapElementList<Key, T, Unique, SourceT>, uid: usize, prev: Iterator<Key, T, Unique, SourceT> | null, next: Iterator<Key, T, Unique, SourceT> | null, value: Entry<Key, T> ): Iterator<Key, T, Unique, SourceT> { return new Iterator(container, uid, prev, next, value); } @inline public static _Set_prev<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>>> (it: Iterator<Key, T, Unique, SourceT>, prev: Iterator<Key, T, Unique, SourceT>): void { it.prev_ = prev; } @inline public static _Set_next<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>>> (it: Iterator<Key, T, Unique, SourceT>, next: Iterator<Key, T, Unique, SourceT>): void { it.next_ = next; } /* --------------------------------------------------------------- ITERATORS --------------------------------------------------------------- */ @inline public reverse(): ReverseIterator<Key, T, Unique, SourceT> { return new ReverseIterator(this); } @inline public prev(): Iterator<Key, T, Unique, SourceT> { return this.prev_ ? this.prev_! : this; } @inline public next(): Iterator<Key, T, Unique, SourceT> { return this.next_ ? this.next_! : this; } /* --------------------------------------------------------------- ACCESSORS --------------------------------------------------------------- */ @inline public source(): SourceT { return this.container_.source(); } @inline public get value(): Entry<Key, T> { return this.value_; } @inline public get first(): Key { return this.value.first; } @inline public get second(): T { return this.value.second; } @inline public set second(val: T) { this.value.second = val; } @inline public static _Is_erased<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>>> (it: Iterator<Key, T, Unique, SourceT>): boolean { return it.erased_; } @inline public static _Set_erased<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>>> (it: Iterator<Key, T, Unique, SourceT>): void { it.erased_ = true; } @inline public static _Compare_uid<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>>> (x: Iterator<Key, T, Unique, SourceT>, y: Iterator<Key, T, Unique, SourceT>): boolean { return x.uid_ < y.uid_; } } export class ReverseIterator<Key, T, Unique extends boolean, SourceT extends IMapContainer<Key, T, Unique, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>>> extends ReverseBase<Entry<Key, T>, SourceT, Iterator<Key, T, Unique, SourceT>, ReverseIterator<Key, T, Unique, SourceT>, IPair<Key, T>> { @inline public get value(): Entry<Key, T> { return this.base_.value; } @inline public get first(): Key { return this.value.first; } @inline public get second(): T { return this.value.second; } @inline public set second(val: T) { this.value.second = val; } } }