// undefined in the type system; similar to null // `*und T` var Undefined = class |Undefined| { .ptr :*mut T, .:init = fn | ptr :*mut T | :$Undefined { // XXX return $new .( .ptr = ptr, ); }, .:assign = fn | und :$Undefined, val :T | :*mut T { und.ptr.* = val; $del und; return und.ptr; }, }; // `[]und T` // created from static arrays or malloc // .:push :fn( []und T, []T, T ):[]mut T // .:pushSlice :fn( []und T, []T, []T ):[]mut T // // items = capacity.push( items, val ); // var UndefinedSlice = class |US| { .slc :[]mut T, .:init = fn | all :Allocator, T :type, count :usize | :$US { var slc :[]mut T = all.malloc( T, count ).!; return $new .( .slc = slc, ); }, // take the undefined allocated slice, // the subslice of valid values in the memory, // and the next value to append. // return the new slice of values, one longer than the parameter slice. // the undefined allocated slice must have space for more values. .:push = fn | us :US, // $ valid :[]mut T, val :T, | :[]mut T { assert( valid.ptr == us.slc.ptr ); assert( valid.len < us.slc.len ); us.slc[ valid.len ] = val; return us.slc[ 0..valid.len+1 ]; }, .:pushSlice = fn | us :US, // $ valid :[]mut T, vals :[]T, | :[]mut T { assert( valid.ptr == us.slc.ptr ); assert( valid.len + vals.len <= us.slc.len ); for( 0..vals.len ) |i| { us.slc[ valid.len + i ] = vals[ i ]; // XXX TODO syntax for iterating over slice of mutable elements via ptr ? } return us.slc[ 0..{ valid.len + vals.len } ]; }, }; var create :fn( #T :type ) :$Undefined ; var destroy :fn( $Undefined ) :void ; var malloc :fn( #T :type, count :usize ) :$UndefinedSlice ; var free :fn( $UndefinedSlice ) :void ;