UNPKG

astl

Version:

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

229 lines (194 loc) 6.99 kB
import { IForwardIterator } from "../iterator/IForwardIterator"; import { DomainError } from "../exception/DomainError"; import { CMath } from "../internal/numeric/CMath"; import { Repeater } from "../internal/iterator/disposable/Repeater"; import { SourcePointer } from "../internal/functional/SourcePointer"; import { distance } from "../iterator/global"; export class ForwardList<T> { private source_ptr_: SourcePointer<ForwardList<T>> = new SourcePointer(this); private end_: ForwardList.Iterator<T> = ForwardList.Iterator._Create(this.source_ptr_, null, changetype<T>(0)); private before_begin_: ForwardList.Iterator<T> = ForwardList.Iterator._Create(this.source_ptr_, this.end_, changetype<T>(0)); private size_: usize = 0; /* --------------------------------------------------------- CONSTRUCTORS --------------------------------------------------------- */ @inline public assign<InputIterator> (first: InputIterator, last: InputIterator): void { if (this.empty() === false) this.clear(); this.insert_after_range<InputIterator>(this.before_begin_, first, last); } @inline public assign_repeatedly(length: usize, value: T): void { if (this.empty() === false) this.clear(); this.insert_after_repeatedly(this.before_begin_, length, value); } @inline public clear(): void { ForwardList.Iterator._Set_next(this.before_begin_, this.end_); this.size_ = 0; } /* --------------------------------------------------------- ACCESSORS --------------------------------------------------------- */ @inline public size(): usize { return this.size_; } @inline public empty(): boolean { return this.size_ === 0; } @inline public front(): T { return this.begin().value; } @inline public before_begin(): ForwardList.Iterator<T> { return this.before_begin_; } @inline public begin(): ForwardList.Iterator<T> { return this.before_begin_.next(); } @inline public end(): ForwardList.Iterator<T> { return this.end_; } /* =============================================================== ELEMENTS I/O - INSERT - ERASE - SWAP ================================================================== INSERT --------------------------------------------------------------- */ @inline public push_front(val: T): void { this.insert_after(this.before_begin_, val); } public insert_after(pos: ForwardList.Iterator<T>, val: T): ForwardList.Iterator<T> { const it: ForwardList.Iterator<T> = ForwardList.Iterator._Create(this.source_ptr_, pos.next(), val); ForwardList.Iterator._Set_next<T>(pos, it); ++this.size_; return it; } @inline public insert_after_repeatedly(pos: ForwardList.Iterator<T>, n: usize, val: T): ForwardList.Iterator<T> { const first: Repeater<T> = new Repeater(0, val); const last: Repeater<T> = new Repeater(n, val); return this.insert_after_range(pos, first, last); } public insert_after_range<InputIterator> (pos: ForwardList.Iterator<T>, first: InputIterator, last: InputIterator): ForwardList.Iterator<T> { for (; first != last; first = first.next()) pos = this.insert_after(pos, first.value); return pos; } /* --------------------------------------------------------------- ERASE --------------------------------------------------------------- */ @inline public pop_front(): void { this.erase_after(this.before_begin()); } public erase_after(first: ForwardList.Iterator<T>, last: ForwardList.Iterator<T> = first.next().next()): ForwardList.Iterator<T> { this.size_ -= CMath.max<isize>(0, distance(first, last) - 1); ForwardList.Iterator._Set_next<T>(first, last); return last; } /* --------------------------------------------------------------- SWAP --------------------------------------------------------------- */ public swap(obj: ForwardList<T>): void { // SOURCE POINTER this.source_ptr_.value = obj; obj.source_ptr_.value = this; const source: SourcePointer<ForwardList<T>> = this.source_ptr_; this.source_ptr_ = obj.source_ptr_; obj.source_ptr_ = source; // ITERATORS const before: ForwardList.Iterator<T> = this.before_begin_; this.before_begin_ = obj.before_begin_; obj.before_begin_ = before; const end: ForwardList.Iterator<T> = this.end_; this.end_ = obj.end_; obj.end_ = end; // CONTAINER SIZE const size: usize = this.size_; this.size_ = obj.size_; obj.size_ = size; } } export namespace ForwardList { export class Iterator<T> { private source_ptr_: SourcePointer<ForwardList<T>>; private next_: Iterator<T> | null; private value_: T; /* --------------------------------------------------------------- CONSTRUCTORS --------------------------------------------------------------- */ private constructor(sourcePtr: SourcePointer<ForwardList<T>>, next: Iterator<T> | null, value: T) { this.source_ptr_ = sourcePtr; this.next_ = next; this.value_ = value; } @inline public static _Create<T>(sourcePtr: SourcePointer<ForwardList<T>>, next: Iterator<T> | null, value: T): ForwardList.Iterator<T> { return new Iterator(sourcePtr, next, value); } @inline public static _Set_next<T>(it: Iterator<T>, next: Iterator<T>): void { it.next_ = next; } @inline public next(): Iterator<T> { if (this.next_ === null) throw new DomainError("Error on ForwardList.Iterator.next(): unable to forward to the next step because it's the ForwardList.end()."); return this.next_!; } /* --------------------------------------------------------------- ACCESSORS --------------------------------------------------------------- */ @inline public source(): ForwardList<T> { return this.source_ptr_.value; } @inline public get value(): T { return this.value_; } @inline public set value(val: T) { this.value_ = val; } } }