template CELL array_capacity(T *array) { #ifdef FACTOR_DEBUG CELL header = untag_header(array->header); assert(header == T::type_number); #endif return array->capacity >> TAG_BITS; } #define AREF(array,index) ((CELL)(array) + sizeof(F_ARRAY) + (index) * CELLS) #define UNAREF(array,ptr) (((CELL)(ptr)-(CELL)(array)-sizeof(F_ARRAY)) / CELLS) template CELL array_nth(T *array, CELL slot) { #ifdef FACTOR_DEBUG assert(slot < array_capacity(array)); assert(untag_header(array->header) == T::type_number); #endif return get(AREF(array,slot)); } template void set_array_nth(T *array, CELL slot, CELL value) { #ifdef FACTOR_DEBUG assert(slot < array_capacity(array)); assert(untag_header(array->header) == T::type_number); #endif put(AREF(array,slot),value); write_barrier((CELL)array); } template CELL array_size(CELL capacity) { return sizeof(T) + capacity * T::element_size; } template CELL array_size(T *array) { return array_size(array_capacity(array)); } template T *allot_array_internal(CELL capacity) { T *array = allot(array_size(capacity)); array->capacity = tag_fixnum(capacity); return array; } template bool reallot_array_in_place_p(T *array, CELL capacity) { return in_zone(&nursery,(CELL)array) && capacity <= array_capacity(array); } template T *reallot_array(T *array_, CELL capacity) { gc_root array(array_); if(reallot_array_in_place_p(array.untagged(),capacity)) { array->capacity = tag_fixnum(capacity); return array.untagged(); } else { CELL to_copy = array_capacity(array.untagged()); if(capacity < to_copy) to_copy = capacity; T *new_array = allot_array_internal(capacity); memcpy(new_array + 1,array.untagged() + 1,to_copy * T::element_size); memset((char *)(new_array + 1) + to_copy * T::element_size, 0,(capacity - to_copy) * T::element_size); return new_array; } }