#ifndef VECTOR_H #define VECTOR_H template struct PGF_INTERNAL Vector { size_t len; A data[]; public: static void release(ref vec) { PgfDB::free(vec, vec->len*sizeof(A)); } }; template inline PGF_INTERNAL ref> vector_new(size_t len) { ref> res = PgfDB::malloc>(len*sizeof(A)); res->len = len; return res; } template inline PGF_INTERNAL ref vector_new(Vector C::* field, size_t len) { ref res = PgfDB::malloc(len*sizeof(A)).as_object(); (res->*field).len = len; return res; } PGF_INTERNAL_DECL size_t get_next_padovan(size_t min); /* Resize a vector by creating a new one and copying the old content. * The new vector is now also safe to update */ template inline PGF_INTERNAL ref> vector_copy(ref> vec, size_t len) { size_t size = len*sizeof(A); ref> res = PgfDB::malloc>(size); res->len = len; memcpy(res->data, vec->data, size); return res; } /* Resize a vector by changing its length. If there is no enough space * the implementation will create a copy, but whenever possible it will * return the reference of the original vector. In the later case, it * changes the length in-place which means that the function is safe * only if the vector was created during the current transaction. */ template inline PGF_INTERNAL ref> vector_unsafe_resize(ref> vec, size_t len) { size_t old_len = get_next_padovan(vec->len); size_t new_len = get_next_padovan(len); if (old_len == new_len) return vec; ref> res = PgfDB::realloc>(vec,old_len*sizeof(A),new_len*sizeof(A)).as_object(); res->len = len; return res; } /* Resize a vector embedded in another structure, by changing its length. * If there is no enough space the implementation will copy the structure, * but whenever possible it will return a reference to * the original structure. In the later case, it changes * the vector's length in-place which means that the function is safe * only if the structure was created during the current transaction. */ template inline PGF_INTERNAL ref vector_unsafe_resize(ref r, Vector C::* field, size_t len) { size_t old_len = get_next_padovan((r->*field).len); size_t new_len = get_next_padovan(len); if (old_len == new_len) return r; ref res = PgfDB::realloc(r,old_len*sizeof(A),new_len*sizeof(A)).as_object(); (res->*field).len = len; return res; } template inline PGF_INTERNAL ref vector_elem(ref> v, size_t index) { return ref::from_ptr(&v->data[index]); } template inline PGF_INTERNAL A *vector_elem(Vector *v, size_t index) { return &v->data[index]; } #endif // VECTOR_H