astl
Version:
AssemblyScript-STL (Standard Template Library, migrated from the C++)
229 lines (194 loc) • 6.99 kB
text/typescript
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
--------------------------------------------------------- */
public assign<InputIterator>
(first: InputIterator, last: InputIterator): void
{
if (this.empty() === false)
this.clear();
this.insert_after_range<InputIterator>(this.before_begin_, first, last);
}
public assign_repeatedly(length: usize, value: T): void
{
if (this.empty() === false)
this.clear();
this.insert_after_repeatedly(this.before_begin_, length, value);
}
public clear(): void
{
ForwardList.Iterator._Set_next(this.before_begin_, this.end_);
this.size_ = 0;
}
/* ---------------------------------------------------------
ACCESSORS
--------------------------------------------------------- */
public size(): usize
{
return this.size_;
}
public empty(): boolean
{
return this.size_ === 0;
}
public front(): T
{
return this.begin().value;
}
public before_begin(): ForwardList.Iterator<T>
{
return this.before_begin_;
}
public begin(): ForwardList.Iterator<T>
{
return this.before_begin_.next();
}
public end(): ForwardList.Iterator<T>
{
return this.end_;
}
/* ===============================================================
ELEMENTS I/O
- INSERT
- ERASE
- SWAP
==================================================================
INSERT
--------------------------------------------------------------- */
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;
}
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
--------------------------------------------------------------- */
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;
}
public static _Create<T>(sourcePtr: SourcePointer<ForwardList<T>>, next: Iterator<T> | null, value: T): ForwardList.Iterator<T>
{
return new Iterator(sourcePtr, next, value);
}
public static _Set_next<T>(it: Iterator<T>, next: Iterator<T>): void
{
it.next_ = next;
}
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
--------------------------------------------------------------- */
public source(): ForwardList<T>
{
return this.source_ptr_.value;
}
public get value(): T
{
return this.value_;
}
public set value(val: T)
{
this.value_ = val;
}
}
}