// Construction syntax
syntax array_initialization from "<" Arg(<type>, type) ">[" [{Arg(<expr>, elems) "," [s]} Arg(<expr>, elems)] "]" {
let res = arr<$type>();
@elems.i {
res.push($elems.i);
}
return move(res);
}
syntax list_comprehension from "[" [s] Arg(<expr>, map) s "for" s Arg(<ident>, it) [s] ":" [s] Arg(<type>, type) s "in" s Arg(<expr>, container) [s] "]" {
let res = arr<$type>();
let func = ($it: $type) -> $type $map;
for _it_ in $container {
res.push(func(*_it_));
\}
return move(res);
}
// Algorithms
fn<T> arr_with_capacity(size: Int) -> Array<'T> {
let res = arr<'T>();
res.reserve(move(size));
return move(res);
}
fn<T> fill(array: @Array<'T>, value: 'T) -> @Array<'T> {
while array.capacity() > array.len() {
array.push(*value);
}
return array;
}
fn<T> fill_with(array: @Array<'T>, f: Int => 'T) -> @Array<'T> {
let idx = array.len();
while array.capacity() > array.len() {
array.push(f(*idx));
idx.inc();
}
return array;
}
fn<T, G> transform(array: @Array<'T>, f: 'T => 'G) -> Array<'G> {
let res = arr_with_capacity<'G>(array.len());
for i in array {
res.push(f(*i));
}
return move(res);
}
fn<T> transform_inplace(array: @Array<'T>, f: 'T => 'T) -> @Array<'T> {
for i in array {
i := f(*i);
}
return array;
}
fn<T> reverse(array: @Array<'T>) -> @Array<'T> {
let length = array.len();
let half = length / 2;
let i = 0;
while i < half {
swap(array[*i], array[length - i - 1]);
i.inc();
}
return array;
}
fn<T> reduce(array: @Array<'T>, base: 'T, op: ('T, 'T) => 'T) -> 'T {
for i in array {
base := op(*base, *i);
}
return move(base);
}
// Printable interface
fn<T> print(array: Array<'T [Printable]>) {
let idx = 0;
print("[");
for i in array {
print(*i);
idx.inc();
if idx < array.len() {
print(", ");
}
}
print("]");
}
implement<T> Printable for Array<'T [Printable]>;