astl
Version:
AssemblyScript-STL (Standard Template Library, migrated from the C++)
392 lines (353 loc) • 11 kB
text/typescript
import { advance } from "../iterator/global";
import { randint } from "./random";
/* =========================================================
MODIFIERS (MODIFYING SEQUENCE)
- FILL
- REMOVE
- REPLACE & SWAP
- RE-ARRANGEMENT
============================================================
FILL
--------------------------------------------------------- */
export function copy<InputIterator, OutputIterator>
(first: InputIterator, last: InputIterator, output: OutputIterator): OutputIterator
{
for (; first != last; first = first.next())
{
output.value = first.value;
output = output.next();
}
return output;
}
export function copy_n<InputIterator, OutputIterator>
(first: InputIterator, n: usize, output: OutputIterator): OutputIterator
{
for (let i: usize = 0; i < n; ++i)
{
output.value = first.value;
output.value = first.value;
output = output.next();
}
return output;
}
export function copy_if<InputIterator, OutputIterator, UnaryPredicator>
(
first: InputIterator, last: InputIterator,
output: OutputIterator,
pred: UnaryPredicator
): OutputIterator
{
for (; first != last; first = first.next())
{
if (pred(first.value) === false)
continue;
output.value = first.value;
output = output.next();
}
return output;
}
export function copy_backward<InputIterator, OutputIterator>
(first: InputIterator, last: InputIterator, output: OutputIterator): OutputIterator
{
last = last.prev();
while (last != first)
{
last = last.prev();
output = output.prev();
output.value = last.value;
}
return output;
}
export function fill<ForwardIterator, T>
(first: ForwardIterator, last: ForwardIterator, val: T): void
{
for (; first != last; first = first.next())
first.value = val;
}
export function fill_n<OutputIterator, T>
(first: OutputIterator, n: usize, val: T): OutputIterator
{
for (let i: usize = 0; i < n; ++i)
{
first.value = val;
first = first.next();
}
return first;
}
export function transform<InputIterator, OutputIterator, UnaryOperator>
(
first: InputIterator, last: InputIterator,
result: OutputIterator,
op: UnaryOperator
): OutputIterator
{
for (; first != last; first = first.next())
{
result.value = op(first.value);
result = result.next();
}
return result;
}
export function transform_binary<InputIterator1, InputIterator2, OutputIterator, BinaryOperator>
(
first1: InputIterator1, last1: InputIterator1,
first2: InputIterator2,
result: OutputIterator,
op: BinaryOperator
): OutputIterator
{
for (; first1 != last1; first1 = first1.next())
{
result.value = op(first1.value, first2.value);
first2 = first2.next();
result = result.next();
}
return result;
}
export function generate<ForwardIterator, Generator>
(first: ForwardList, last: ForwardIterator, generator: Generator): void
{
for (; first != last; first = first.next())
first.value = generator();
}
export function generate_n<ForwardIterator, Generator>
(first: ForwardList, n: usize, generator: Generator): void
{
for (let i: usize = 0; i < n; ++i)
{
first.value = generator();
first = first.next();
}
}
/* ---------------------------------------------------------
REMOVE
--------------------------------------------------------- */
export function unique<InputIterator, BinaryPredicator>
(
first: InputIterator, last: InputIterator,
pred: BinaryPredicator
): InputIterator
{
if (first == last)
return last;
let ret: InputIterator = first;
for (first = first.next(); first != last; first = first.next())
if (pred(ret.value, first.value) === false)
{
ret = ret.next();
ret.value = first.value;
}
return ret.next();
}
export function unique_copy<InputIterator, OutputIterator, BinaryPredicator>
(
first: InputIterator, last: InputIterator, output: OutputIterator,
pred: BinaryPredicator
): OutputIterator
{
if (first == last)
return output;
output.value = first.value;
first = first.next();
for (; first != last; first = first.next())
if (pred(first.value, output.value) === false)
{
output = output.next();
output.value = first.value;
}
return output.next();
}
export function remove<InputIterator, T>
(first: InputIterator, last: InputIterator, value: T): InputIterator
{
let output: InputIterator = first;
for (; first != last; first = first.next())
{
if (first.value == value)
continue;
output.value = first.value;
output = output.next();
}
return output;
}
export function remove_if<InputIterator, UnaryPredicator>
(first: InputIterator, last: InputIterator, pred: UnaryPredicator): InputIterator
{
let output: InputIterator = first;
for (; first != last; first = first.next())
if (pred(first.value) === false)
{
output.value = first.value;
output = output.next();
}
return output;
}
export function remove_copy<InputIterator, OutputIterator, T>
(
first: InputIterator, last: InputIterator,
output: OutputIterator,
value: T
): OutputIterator
{
for (; first != last; first = first.next())
{
if (value == first.value)
continue;
output.value = first.value;
output = output.next();
}
return output;
}
export function remove_copy_if<InputIterator, OutputIterator, UnaryPredicator>
(
first: InputIterator, last: InputIterator,
output: OutputIterator,
pred: UnaryPredicator
): OutputIterator
{
for (; first != last; first = first.next())
if (pred(first.value) === false)
{
output.value = first.value;
output = output.next();
}
return output;
}
/* ---------------------------------------------------------
REPLACE & SWAP
--------------------------------------------------------- */
export function replace<InputIterator, T>
(
first: InputIterator, last: InputIterator,
oldVal: T,
newVal: T
): void
{
for (; first != last; first = first.next())
if (first.value == oldVal)
first.value = newVal;
}
export function replace_if<InputIterator, UnaryPredicator, T>
(
first: InputIterator, last: InputIterator,
pred: UnaryPredicator,
newVal: T
): void
{
for (; first != last; first = first.next())
if (pred(first.value) === true)
first.value = newVal;
}
export function replace_copy<InputIterator, OutputIterator, T>
(
first: InputIterator, last: InputIterator,
output: OutputIterator,
oldVal: T,
newVal: T
): OutputIterator
{
for (; first != last; first = first.next())
{
output.value = (first.value == oldVal)
? newVal
: first.value;
output = output.next();
}
return output;
}
export function replace_copy_if<InputIterator, OutputIterator, UnaryPredicator, T>
(
first: InputIterator, last: InputIterator,
output: OutputIterator,
pred: UnaryPredicator,
newVal: T
): OutputIterator
{
for (; first != last; first = first.next())
{
output.value = (pred(first.value) === true)
? newVal
: first.value;
output = output.next();
}
return output;
}
export function iter_swap<ForwardIterator1, ForwardIterator2>
(x: ForwardIterator1, y: ForwardIterator2): void
{
const value = x.value;
x.value = y.value;
y.value = value;
}
export function swap_ranges<ForwardIterator1, ForwardIterator2>
(first1: ForwardIterator2, last1: ForwardIterator2, first2: ForwardIterator2): ForwardIterator2
{
for (; first1 != last1; first1 = first1.next())
{
iter_swap<ForwardIterator1, ForwardIterator2>(first1, first2);
first2 = first2.next();
}
return first2;
}
/* ---------------------------------------------------------
RE-ARRANGEMENT
--------------------------------------------------------- */
export function reverse<BidirectionalIterator>
(first: BidirectionalIterator, last: BidirectionalIterator): void
{
while (first != last && first != (last = last.prev()))
{
iter_swap<BidirectionalIterator, BidirectionalIterator>(first, last);
first = first.next();
}
}
export function reverse_copy<BidirectionalIterator, OutputIterator>
(first: BidirectionalIterator, last: BidirectionalIterator, output: OutputIterator): OutputIterator
{
while (last != first)
{
last = last.prev();
output.value = last.value;
output = output.next();
}
return output;
}
export function shift_left<ForwardIterator>
(first: ForwardIterator, last: ForwardIterator, n: usize): ForwardIterator
{
const mid: ForwardIterator = advance(first, n);
return copy(mid, last, first);
}
export function shift_right<ForwardIterator>
(first: ForwardIterator, last: ForwardIterator, n: usize): ForwardIterator
{
const mid: ForwardIterator = advance(last, -n);
return copy(first, mid, last);
}
export function rotate<InputIterator>
(first: InputIterator, middle: InputIterator, last: InputIterator): InputIterator
{
while (first != middle && middle != last)
{
iter_swap<InputIterator, InputIterator>(first, middle);
first = first.next();
middle = middle.next();
}
return first;
}
export function rotate_copy<ForwardIterator, OutputIterator>
(first: ForwardIterator, middle: ForwardIterator, last: ForwardIterator, output: OutputIterator): OutputIterator
{
output = copy(middle, last, output);
return copy(first, middle, output);
}
export function shuffle<RandomAccessIterator>
(first: RandomAccessIterator, last: RandomAccessIterator): void
{
for (let it = first; it != last; it = it.next())
{
const index: usize = randint<usize>(first.index(), last.index() - 1);
if (it.index() !== index)
iter_swap<RandomAccessIterator, RandomAccessIterator>(it, first.advance(index));
}
}