2009-05-02 05:43:58 -04:00
|
|
|
template<typename T> CELL array_capacity(T *array)
|
|
|
|
{
|
|
|
|
#ifdef FACTOR_DEBUG
|
2009-05-04 02:00:30 -04:00
|
|
|
assert(array->header.hi_tag() == T::type_number);
|
2009-05-02 05:43:58 -04:00
|
|
|
#endif
|
|
|
|
return array->capacity >> TAG_BITS;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> CELL array_size(CELL capacity)
|
|
|
|
{
|
|
|
|
return sizeof(T) + capacity * T::element_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> CELL array_size(T *array)
|
|
|
|
{
|
|
|
|
return array_size<T>(array_capacity(array));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> T *allot_array_internal(CELL capacity)
|
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
T *array = allot<T>(array_size<T>(capacity));
|
2009-05-02 05:43:58 -04:00
|
|
|
array->capacity = tag_fixnum(capacity);
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> bool reallot_array_in_place_p(T *array, CELL capacity)
|
|
|
|
{
|
2009-05-04 02:00:30 -04:00
|
|
|
return in_zone(&nursery,array) && capacity <= array_capacity(array);
|
2009-05-02 05:43:58 -04:00
|
|
|
}
|
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
template <typename T> T *reallot_array(T *array_, CELL capacity)
|
2009-05-02 05:43:58 -04:00
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
gc_root<T> array(array_);
|
2009-05-02 05:43:58 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
if(reallot_array_in_place_p(array.untagged(),capacity))
|
2009-05-02 05:43:58 -04:00
|
|
|
{
|
|
|
|
array->capacity = tag_fixnum(capacity);
|
2009-05-02 10:19:09 -04:00
|
|
|
return array.untagged();
|
2009-05-02 05:43:58 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
CELL to_copy = array_capacity(array.untagged());
|
2009-05-02 05:43:58 -04:00
|
|
|
if(capacity < to_copy)
|
|
|
|
to_copy = capacity;
|
|
|
|
|
|
|
|
T *new_array = allot_array_internal<T>(capacity);
|
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
memcpy(new_array + 1,array.untagged() + 1,to_copy * T::element_size);
|
2009-05-02 05:43:58 -04:00
|
|
|
memset((char *)(new_array + 1) + to_copy * T::element_size,
|
|
|
|
0,(capacity - to_copy) * T::element_size);
|
|
|
|
|
|
|
|
return new_array;
|
|
|
|
}
|
|
|
|
}
|