diff --git a/src/c/array.d b/src/c/array.d index 797495c2a..93ea441ce 100644 --- a/src/c/array.d +++ b/src/c/array.d @@ -231,6 +231,33 @@ ecl_aref1(cl_object x, cl_index index) return ecl_aref_unsafe(x, index); } +void * +ecl_row_major_ptr(cl_object x, cl_index index, cl_index bytes) +{ + cl_index idx, elt_size, offset; + cl_elttype elt_type; + + if (ecl_unlikely(!ECL_ARRAYP(x))) { + FEwrong_type_nth_arg(@[aref], 1, x, @[array]); + } + + elt_type = x->array.elttype; + if (ecl_unlikely(elt_type == aet_bit || elt_type == aet_object)) + FEerror("In ecl_row_major_ptr: Specialized array expected, element type ~S found.", + 1,ecl_elttype_to_symbol(elt_type)); + + elt_size = ecl_aet_size[elt_type]; + offset = index*elt_size; + + /* don't check bounds if bytes == 0 */ + if (ecl_unlikely(bytes > 0 && offset + bytes > x->array.dim*elt_size)) { + FEwrong_index(@[row-major-aref], x, -1, MAKE_FIXNUM(index), + x->array.dim); + } + + return x->array.self.b8 + offset; +} + /* Internal function for setting array elements: diff --git a/src/h/external.h b/src/h/external.h index 7c4f3adf1..4fafefed2 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -324,6 +324,10 @@ extern ECL_API cl_object APPLY(cl_narg n, cl_objectfn, cl_object *x); extern ECL_API cl_object cl_row_major_aref(cl_object x, cl_object i); extern ECL_API cl_object si_row_major_aset(cl_object x, cl_object i, cl_object v); extern ECL_API cl_object si_make_vector(cl_object etype, cl_object dim, cl_object adj, cl_object fillp, cl_object displ, cl_object disploff); + +/* for open-coding the access while preserving the bounds and type check: */ +extern ECL_API void *ecl_row_major_ptr(cl_object arr, cl_index index, cl_index bytes); + extern ECL_API cl_object cl_array_element_type(cl_object a); extern ECL_API cl_object cl_array_rank(cl_object a); extern ECL_API cl_object cl_array_dimension(cl_object a, cl_object index);