69 lines
1.6 KiB
Plaintext
69 lines
1.6 KiB
Plaintext
ns std::core
|
|
|
|
use std::unsafe::Pointer
|
|
use std::unsafe::mem::{alloc, pointer_of)
|
|
|
|
pub int Array<T> : Monad + Default + Empty {
|
|
const default = array::empty<Self>
|
|
const empty = array::empty<Self>
|
|
|
|
length: Int
|
|
}
|
|
|
|
impl ArrayImpl<T> : Array<T> {
|
|
|
|
fld pointer: Pointer
|
|
fld length: Int
|
|
|
|
pub unsafe ctor(length: Int) {
|
|
self.pointer = alloc(length * T::size())
|
|
self.length = length
|
|
}
|
|
|
|
pub ctor(pointer: Pointer, length: Int) {
|
|
self.pointer = pointer
|
|
self.length = length
|
|
}
|
|
|
|
pub unsafe fn set(index: Int, item: Pointer) {
|
|
pointer.offset(index * T::size()).write(item.read())
|
|
}
|
|
|
|
}
|
|
|
|
pub mod array {
|
|
|
|
// Usage:
|
|
// let int_array = array::of(1, 2, 3)
|
|
// assert_eq(3, int_array.length)
|
|
pub fn of<T>(ts: ...T): Array<T> {
|
|
unsafe {
|
|
let array = ArrayImpl<T>(ts.length)
|
|
for (i, t) in ts.enumerate() {
|
|
let t_pointer = pointer_of(t)
|
|
array.set(i, t_pointer)
|
|
}
|
|
array
|
|
}
|
|
}
|
|
|
|
pub extern fn of_length<T>(length: Int, init_value: T): Array<T>
|
|
|
|
pub extern fn empty<T>(): Array<T>
|
|
|
|
pub fn flatten<T>(ats: Array<Array<T>>): Array<T> {
|
|
let total_ts = ats.map { ts -> ts.length }
|
|
.reduce { acc, current -> acc + current }
|
|
let result: mut Array<T> = of_length(total_ts, std::reflect::default_or_empty<T>)
|
|
let i: mut Int = 0
|
|
for a in ats {
|
|
for element in a {
|
|
result[i] = element
|
|
i++
|
|
}
|
|
}
|
|
result
|
|
}
|
|
|
|
}
|