Skip to content

Instantly share code, notes, and snippets.

@dinosaure
Created April 1, 2019 14:37
Show Gist options
  • Save dinosaure/306e64b4b0d6fd1de8e32f9c3b23cf00 to your computer and use it in GitHub Desktop.
Save dinosaure/306e64b4b0d6fd1de8e32f9c3b23cf00 to your computer and use it in GitHub Desktop.
CAMLprim value caml_ba_overlap(value va, value vb)
{
CAMLparam2 (va, vb);
CAMLlocal1 (res);
struct caml_ba_array * a = Caml_ba_array_val(va);
struct caml_ba_array * b = Caml_ba_array_val(vb);
void *src_a = a->data;
void *src_b = b->data;
intnat len;
intnat a_bytes;
intnat b_bytes;
intnat dim_a[CAML_BA_MAX_NUM_DIMS];
intnat dim_b[CAML_BA_MAX_NUM_DIMS];
intnat offset;
a_bytes = caml_ba_num_elts(a) * caml_ba_element_size[a->flags & CAML_BA_KIND_MASK];
b_bytes = caml_ba_num_elts(b) * caml_ba_element_size[b->flags & CAML_BA_KIND_MASK];
if (a->num_dims != b->num_dims)
caml_invalid_argument("Bigarray.overlap: dimensions mistmatch");
// [--b--[--]--a--] || [--b--[-a-]--]
if (a_src >= b_src && a_src < b_src + b_bytes)
{
len = MIN(a_bytes, b_bytes) - (a_src - b_src);
memset(a_dim, 0, sizeof(intnat) * CAML_BA_MAX_NUM_DIMS);
offset = b_src + (a_src - b_src);
for (i = b->num_dims - 1; i >= 0; i--)
{
b_dim[i] = offset % b->dims[i];
offset = offset / b->dims[i];
}
}
// [--a--[--]--b--] || [--[-b-]--a--]
else if (b_src >= a_src && b_src < a_src + a_bytes)
{
len = MIN(a_bytes, b_bytes) - (b_src - a_src);
memset(b_dim, 0, sizeof(intnat) * CAML_BA_MAX_NUM_DIMS);
offset = a_src + (b_src - a_src);
for (i = a->num_dims; i >= 0; i--)
{
a_dim[i] = offset % a->dims[i];
offset = offset / a->dims[i];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment