static ERL_NIF_TERM max_merge()

in c_src/hyper_carray.c [162:213]


static ERL_NIF_TERM max_merge(ErlNifEnv * env, int argc,
			      const ERL_NIF_TERM argv[])
{
	unsigned int narrays = 0;
	ERL_NIF_TERM head;
	ERL_NIF_TERM tail;

	if (!enif_get_list_length(env, argv[0], &narrays)
	    || !enif_get_list_cell(env, argv[0], &head, &tail))
		return enif_make_badarg(env);

	if (narrays < 1)
		return enif_make_badarg(env);

	carray_ptr first = NULL;
	HYPER_CARRAY_OR_BADARG(head, first);
	const unsigned int nitems = first->size;

	carray_ptr acc = NULL;
	carray_alloc(first->precision, &acc);
	memcpy(acc->items, first->items, acc->size);

	// Merge arrays
	for (int i = 1; i < narrays; ++i) {
		carray_ptr curr = NULL;

		if (!enif_get_list_cell(env, tail, &head, &tail)
		    || !enif_get_resource(env, head, carray_resource,
					  (void *) &curr))
			goto dealloc_and_badarg;

		// Require uniform precision.
		if (curr->precision != acc->precision)
			goto dealloc_and_badarg;

		for (uint8_t * accitem = acc->items, *item = curr->items,
		     *enditem = curr->items + nitems;
		     item != enditem; ++item, ++accitem) {
			*accitem = (*item > *accitem) ? *item : *accitem;
		}

		continue;

	      dealloc_and_badarg:
		dtor(env, acc);
		return enif_make_badarg(env);
	}

	ERL_NIF_TERM erl_res = enif_make_resource(env, acc);
	enif_release_resource(acc);
	return erl_res;
}