Commit 4fbca5f8 authored by Brice Videau's avatar Brice Videau

Merge branch 'split' into 'master'

Split refactoring

See merge request !4
parents 2f228ce7 17132c39
...@@ -84,57 +84,6 @@ static int cons_it_size(const excit_t data, ssize_t *size) ...@@ -84,57 +84,6 @@ static int cons_it_size(const excit_t data, ssize_t *size)
return EXCIT_SUCCESS; return EXCIT_SUCCESS;
} }
static int cons_it_split(const excit_t data, ssize_t n, excit_t *results)
{
ssize_t size;
int err = cons_it_size(data, &size);
if (err)
return err;
if (size < n)
return -EXCIT_EDOM;
if (!results)
return EXCIT_SUCCESS;
excit_t range = excit_alloc(EXCIT_RANGE);
if (!range)
return -EXCIT_ENOMEM;
err = excit_range_init(range, 0, size - 1, 1);
if (err)
goto error1;
err = excit_split(range, n, results);
if (err)
goto error1;
int i;
for (i = 0; i < n; i++) {
excit_t tmp, tmp2;
tmp = excit_dup(data);
if (!tmp)
goto error2;
tmp2 = results[i];
results[i] = excit_alloc(EXCIT_SLICE);
if (!results[i]) {
excit_free(tmp2);
goto error2;
}
err = excit_slice_init(results[i], tmp, tmp2);
if (err) {
excit_free(tmp2);
goto error2;
}
}
excit_free(range);
return EXCIT_SUCCESS;
error2:
for (; i >= 0; i--)
excit_free(results[i]);
error1:
excit_free(range);
return err;
}
static int cons_it_nth(const excit_t data, ssize_t n, ssize_t *indexes) static int cons_it_nth(const excit_t data, ssize_t n, ssize_t *indexes)
{ {
ssize_t size; ssize_t size;
...@@ -295,7 +244,7 @@ struct excit_func_table_s excit_cons_func_table = { ...@@ -295,7 +244,7 @@ struct excit_func_table_s excit_cons_func_table = {
cons_it_peek, cons_it_peek,
cons_it_size, cons_it_size,
cons_it_rewind, cons_it_rewind,
cons_it_split, NULL,
cons_it_nth, cons_it_nth,
cons_it_rank, cons_it_rank,
cons_it_pos cons_it_pos
......
...@@ -239,8 +239,53 @@ int excit_split(const excit_t it, ssize_t n, excit_t *results) ...@@ -239,8 +239,53 @@ int excit_split(const excit_t it, ssize_t n, excit_t *results)
return -EXCIT_EINVAL; return -EXCIT_EINVAL;
if (n <= 0) if (n <= 0)
return -EXCIT_EDOM; return -EXCIT_EDOM;
if (!it->func_table->split) if (!it->func_table->split) {
return -EXCIT_ENOTSUP; ssize_t size;
int err = excit_size(it, &size);
if (err)
return err;
if (size < n)
return -EXCIT_EDOM;
if (!results)
return EXCIT_SUCCESS;
excit_t range = excit_alloc(EXCIT_RANGE);
if (!range)
return -EXCIT_ENOMEM;
err = excit_range_init(range, 0, size - 1, 1);
if (err)
goto error1;
err = excit_split(range, n, results);
if (err)
goto error1;
for (int i = 0; i < n; i++) {
excit_t tmp, tmp2;
tmp = excit_dup(it);
if (!tmp)
goto error2;
tmp2 = results[i];
results[i] = excit_alloc(EXCIT_SLICE);
if (!results[i]) {
excit_free(tmp2);
goto error2;
}
err = excit_slice_init(results[i], tmp, tmp2);
if (err) {
excit_free(tmp2);
goto error2;
}
}
excit_free(range);
return EXCIT_SUCCESS;
error2:
for (int i = 0; i < n; i++)
excit_free(results[i]);
error1:
excit_free(range);
return err;
} else
return it->func_table->split(it, n, results); return it->func_table->split(it, n, results);
} }
......
...@@ -79,66 +79,66 @@ struct excit_func_table_s { ...@@ -79,66 +79,66 @@ struct excit_func_table_s {
* allocation, the inner data pointer will already be set. * allocation, the inner data pointer will already be set.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int (*alloc) (excit_t it); int (*alloc)(excit_t it);
/* /*
* This function is called during excit_free. After this function is * This function is called during excit_free. After this function is
* called the iterator and the data will be freed. * called the iterator and the data will be freed.
*/ */
void (*free) (excit_t it); void (*free)(excit_t it);
/* /*
* This funciton is called during excit_dup. It is responsible for * This funciton is called during excit_dup. It is responsible for
* duplicating the content of the inner data between src_it and dst_it. * duplicating the content of the inner data between src_it and dst_it.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int (*copy) (excit_t dst_it, const excit_t src_it); int (*copy)(excit_t dst_it, const excit_t src_it);
/* /*
* This function is responsible for implementing the next functionality * This function is responsible for implementing the next functionality
* of the iterator. * of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code. * Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/ */
int (*next) (excit_t it, ssize_t * indexes); int (*next)(excit_t it, ssize_t *indexes);
/* /*
* This function is responsible for implementing the peek functionality * This function is responsible for implementing the peek functionality
* of the iterator. * of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code. * Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/ */
int (*peek) (const excit_t it, ssize_t * indexes); int (*peek)(const excit_t it, ssize_t *indexes);
/* /*
* This function is responsible for implementing the size functionality * This function is responsible for implementing the size functionality
* of the iterator. * of the iterator.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int (*size) (const excit_t it, ssize_t * size); int (*size)(const excit_t it, ssize_t *size);
/* /*
* This function is responsible for implementing the rewind * This function is responsible for implementing the rewind
* functionality of the iterator. * functionality of the iterator.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int (*rewind) (excit_t it); int (*rewind)(excit_t it);
/* /*
* This function is responsible for implementing the split * This function is responsible for implementing the split
* functionality of the iterator. * functionality of the iterator.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int (*split) (const excit_t it, ssize_t n, excit_t * results); int (*split)(const excit_t it, ssize_t n, excit_t *results);
/* /*
* This function is responsible for implementing the nth functionality * This function is responsible for implementing the nth functionality
* of the iterator. * of the iterator.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int (*nth) (const excit_t it, ssize_t n, ssize_t * indexes); int (*nth)(const excit_t it, ssize_t n, ssize_t *indexes);
/* /*
* This function is responsible for implementing the rank functionality * This function is responsible for implementing the rank functionality
* of the iterator. * of the iterator.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int (*rank) (const excit_t it, const ssize_t * indexes, ssize_t * n); int (*rank)(const excit_t it, const ssize_t *indexes, ssize_t *n);
/* /*
* This function is responsible for implementing the pos functionality * This function is responsible for implementing the pos functionality
* of the iterator. * of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code. * Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/ */
int (*pos) (const excit_t it, ssize_t * n); int (*pos)(const excit_t it, ssize_t *n);
}; };
/* /*
...@@ -205,7 +205,7 @@ int excit_type(excit_t it, enum excit_type_e *type); ...@@ -205,7 +205,7 @@ int excit_type(excit_t it, enum excit_type_e *type);
* "dimension": a pointer where the result will be written. * "dimension": a pointer where the result will be written.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int excit_dimension(excit_t it, ssize_t * dimension); int excit_dimension(excit_t it, ssize_t *dimension);
/* /*
* Gets the current element of an iterator and increments it. * Gets the current element of an iterator and increments it.
...@@ -215,7 +215,7 @@ int excit_dimension(excit_t it, ssize_t * dimension); ...@@ -215,7 +215,7 @@ int excit_dimension(excit_t it, ssize_t * dimension);
* Returns EXCIT_SUCCESS if a valid element was retured or EXCIT_STOPIT if the * Returns EXCIT_SUCCESS if a valid element was retured or EXCIT_STOPIT if the
* iterator is depleted or an error code. * iterator is depleted or an error code.
*/ */
int excit_next(excit_t it, ssize_t * indexes); int excit_next(excit_t it, ssize_t *indexes);
/* /*
* Gets the current element of an iterator. * Gets the current element of an iterator.
...@@ -225,7 +225,7 @@ int excit_next(excit_t it, ssize_t * indexes); ...@@ -225,7 +225,7 @@ int excit_next(excit_t it, ssize_t * indexes);
* Returns EXCIT_SUCCESS if a valid element was retured or EXCIT_STOPIT if the * Returns EXCIT_SUCCESS if a valid element was retured or EXCIT_STOPIT if the
* iterator is depleted or an error code. * iterator is depleted or an error code.
*/ */
int excit_peek(const excit_t it, ssize_t * indexes); int excit_peek(const excit_t it, ssize_t *indexes);
/* /*
* Rewinds an iterator to its initial state. * Rewinds an iterator to its initial state.
...@@ -240,7 +240,7 @@ int excit_rewind(excit_t it); ...@@ -240,7 +240,7 @@ int excit_rewind(excit_t it);
* "size": an pointer to the variable where the result will be stored. * "size": an pointer to the variable where the result will be stored.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int excit_size(const excit_t it, ssize_t * size); int excit_size(const excit_t it, ssize_t *size);
/* /*
* Splits an iterator envenly into several suub iterators. * Splits an iterator envenly into several suub iterators.
...@@ -251,7 +251,7 @@ int excit_size(const excit_t it, ssize_t * size); ...@@ -251,7 +251,7 @@ int excit_size(const excit_t it, ssize_t * size);
* Returns EXCIT_SUCCESS, -EXCIT_EDOM if the source iterator is too small to be * Returns EXCIT_SUCCESS, -EXCIT_EDOM if the source iterator is too small to be
* subdivised in the wanted number or an error code. * subdivised in the wanted number or an error code.
*/ */
int excit_split(const excit_t it, ssize_t n, excit_t * results); int excit_split(const excit_t it, ssize_t n, excit_t *results);
/* /*
* Gets the nth element of an iterator. * Gets the nth element of an iterator.
...@@ -262,7 +262,7 @@ int excit_split(const excit_t it, ssize_t n, excit_t * results); ...@@ -262,7 +262,7 @@ int excit_split(const excit_t it, ssize_t n, excit_t * results);
* iterator, no results is returned if NULL. * iterator, no results is returned if NULL.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int excit_nth(const excit_t it, ssize_t rank, ssize_t * indexes); int excit_nth(const excit_t it, ssize_t rank, ssize_t *indexes);
/* /*
* Gets the rank of an element of an iterator. * Gets the rank of an element of an iterator.
...@@ -272,7 +272,7 @@ int excit_nth(const excit_t it, ssize_t rank, ssize_t * indexes); ...@@ -272,7 +272,7 @@ int excit_nth(const excit_t it, ssize_t rank, ssize_t * indexes);
* returned if NULL. * returned if NULL.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int excit_rank(const excit_t it, const ssize_t * indexes, ssize_t * rank); int excit_rank(const excit_t it, const ssize_t *indexes, ssize_t *rank);
/* /*
* Gets the position of the iterator. * Gets the position of the iterator.
...@@ -282,7 +282,7 @@ int excit_rank(const excit_t it, const ssize_t * indexes, ssize_t * rank); ...@@ -282,7 +282,7 @@ int excit_rank(const excit_t it, const ssize_t * indexes, ssize_t * rank);
* Returns EXCIT_SUCCESS or EXCIT_STOPIT if the iterator is depleted or an error * Returns EXCIT_SUCCESS or EXCIT_STOPIT if the iterator is depleted or an error
* code. * code.
*/ */
int excit_pos(const excit_t it, ssize_t * rank); int excit_pos(const excit_t it, ssize_t *rank);
/* /*
* Increments the iterator. * Increments the iterator.
...@@ -300,7 +300,7 @@ int excit_skip(excit_t it); ...@@ -300,7 +300,7 @@ int excit_skip(excit_t it);
* iterator, no results is returned if NULL. * iterator, no results is returned if NULL.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int excit_cyclic_next(excit_t it, ssize_t * indexes, int *looped); int excit_cyclic_next(excit_t it, ssize_t *indexes, int *looped);
/* /*
* Initializes a range iterator to iterate from first to last (included) by sep. * Initializes a range iterator to iterate from first to last (included) by sep.
...@@ -331,6 +331,17 @@ int excit_cons_init(excit_t it, excit_t src, ssize_t n); ...@@ -331,6 +331,17 @@ int excit_cons_init(excit_t it, excit_t src, ssize_t n);
*/ */
int excit_repeat_init(excit_t it, excit_t src, ssize_t n); int excit_repeat_init(excit_t it, excit_t src, ssize_t n);
/*
* Splits a repeat iterator between repetitions.
* "it": a product iterator.
* "n": number of iterators desired.
* "results": an array of at least n excit_t, or NULL in which case no iterator
* is created.
* Returns EXCIT_SUCCESS, -EXCIT_EDOM if the selected iterator is too small to
* be subdivised in the wanted number or an error code.
*/
int excit_repeat_split(const excit_t it, ssize_t n, excit_t *results);
/* /*
* Creates a two dimensional Hilbert space-filling curve iterator. * Creates a two dimensional Hilbert space-filling curve iterator.
* "it": an hilbert2d iterator. * "it": an hilbert2d iterator.
...@@ -362,7 +373,7 @@ int excit_product_add_copy(excit_t it, excit_t added_it); ...@@ -362,7 +373,7 @@ int excit_product_add_copy(excit_t it, excit_t added_it);
* "count": a pointer to a variable where the result will be stored. * "count": a pointer to a variable where the result will be stored.
* Returns EXCIT_SUCCESS or an error code. * Returns EXCIT_SUCCESS or an error code.
*/ */
int excit_product_count(const excit_t it, ssize_t * count); int excit_product_count(const excit_t it, ssize_t *count);
/* /*
* Splits a product iterator along the nth iterator. * Splits a product iterator along the nth iterator.
...@@ -376,7 +387,7 @@ int excit_product_count(const excit_t it, ssize_t * count); ...@@ -376,7 +387,7 @@ int excit_product_count(const excit_t it, ssize_t * count);
* be subdivised in the wanted number or an error code. * be subdivised in the wanted number or an error code.
*/ */
int excit_product_split_dim(const excit_t it, ssize_t dim, ssize_t n, int excit_product_split_dim(const excit_t it, ssize_t dim, ssize_t n,
excit_t * results); excit_t *results);
/* /*
* Initializes a slice iterator by giving asrc iterator and an indexer iterator. * Initializes a slice iterator by giving asrc iterator and an indexer iterator.
......
...@@ -221,55 +221,6 @@ static int prod_it_next(excit_t data, ssize_t *indexes) ...@@ -221,55 +221,6 @@ static int prod_it_next(excit_t data, ssize_t *indexes)
return prod_it_peeknext_helper(data, indexes, 1); return prod_it_peeknext_helper(data, indexes, 1);
} }
static int prod_it_split(const excit_t data, ssize_t n, excit_t *results)
{
ssize_t size;
int err = prod_it_size(data, &size);
if (err)
return err;
if (size < n)
return -EXCIT_EDOM;
if (!results)
return EXCIT_SUCCESS;
excit_t range = excit_alloc(EXCIT_RANGE);
if (!range)
return -EXCIT_ENOMEM;
err = excit_range_init(range, 0, size - 1, 1);
if (err)
goto error1;
err = excit_split(range, n, results);
if (err)
goto error1;
for (int i = 0; i < n; i++) {
excit_t tmp, tmp2;
tmp = excit_dup(data);
if (!tmp)
goto error2;
tmp2 = results[i];
results[i] = excit_alloc(EXCIT_SLICE);
if (!results[i]) {
excit_free(tmp2);
goto error2;
}
err = excit_slice_init(results[i], tmp, tmp2);
if (err) {
excit_free(tmp2);
goto error2;
}
}
excit_free(range);
return EXCIT_SUCCESS;
error2:
for (int i = 0; i < n; i++)
excit_free(results[i]);
error1:
excit_free(range);
return err;
}
int excit_product_count(const excit_t it, ssize_t *count) int excit_product_count(const excit_t it, ssize_t *count)
{ {
if (!it || it->type != EXCIT_PRODUCT || !count) if (!it || it->type != EXCIT_PRODUCT || !count)
...@@ -362,7 +313,7 @@ struct excit_func_table_s excit_prod_func_table = { ...@@ -362,7 +313,7 @@ struct excit_func_table_s excit_prod_func_table = {
prod_it_peek, prod_it_peek,
prod_it_size, prod_it_size,
prod_it_rewind, prod_it_rewind,
prod_it_split, NULL,
prod_it_nth, prod_it_nth,
prod_it_rank, prod_it_rank,
prod_it_pos prod_it_pos
......
...@@ -96,7 +96,34 @@ static int repeat_it_pos(const excit_t data, ssize_t *n) ...@@ -96,7 +96,34 @@ static int repeat_it_pos(const excit_t data, ssize_t *n)
return EXCIT_SUCCESS; return EXCIT_SUCCESS;
} }
static int repeat_it_split(const excit_t data, ssize_t n, excit_t *results) struct excit_func_table_s excit_repeat_func_table = {
repeat_it_alloc,
repeat_it_free,
repeat_it_copy,
repeat_it_next,
repeat_it_peek,
repeat_it_size,
repeat_it_rewind,
NULL,
repeat_it_nth,
NULL,
repeat_it_pos
};
int excit_repeat_init(excit_t it, excit_t src, ssize_t n)
{
if (!it || it->type != EXCIT_REPEAT || !src || n <= 0)
return -EXCIT_EINVAL;
struct repeat_it_s *repeat_it = (struct repeat_it_s *)it->data;
excit_free(repeat_it->it);
it->dimension = src->dimension;
repeat_it->it = src;
repeat_it->n = n;
repeat_it->counter = 0;
return EXCIT_SUCCESS;
}
int excit_repeat_split(const excit_t data, ssize_t n, excit_t *results)
{ {
const struct repeat_it_s *it = (const struct repeat_it_s *)data->data; const struct repeat_it_s *it = (const struct repeat_it_s *)data->data;
int err = excit_split(it->it, n, results); int err = excit_split(it->it, n, results);
...@@ -125,30 +152,3 @@ error: ...@@ -125,30 +152,3 @@ error:
excit_free(results[i]); excit_free(results[i]);
return err; return err;
} }
struct excit_func_table_s excit_repeat_func_table = {
repeat_it_alloc,
repeat_it_free,
repeat_it_copy,
repeat_it_next,
repeat_it_peek,
repeat_it_size,
repeat_it_rewind,
repeat_it_split,
repeat_it_nth,
NULL,
repeat_it_pos
};
int excit_repeat_init(excit_t it, excit_t src, ssize_t n)
{
if (!it || it->type != EXCIT_REPEAT || !src || n <= 0)
return -EXCIT_EINVAL;
struct repeat_it_s *repeat_it = (struct repeat_it_s *)it->data;
excit_free(repeat_it->it);
it->dimension = src->dimension;
repeat_it->it = src;
repeat_it->n = n;
repeat_it->counter = 0;
return EXCIT_SUCCESS;
}
...@@ -372,7 +372,7 @@ void test_repeat_iterator(void) ...@@ -372,7 +372,7 @@ void test_repeat_iterator(void)
assert(excit_peek(it, indexes) == EXCIT_STOPIT); assert(excit_peek(it, indexes) == EXCIT_STOPIT);
assert(excit_next(it, indexes) == EXCIT_STOPIT); assert(excit_next(it, indexes) == EXCIT_STOPIT);
assert(excit_split(it, 2, its) == ES); assert(excit_repeat_split(it, 2, its) == ES);
for (int i = 0; i <= 1; i++) { for (int i = 0; i <= 1; i++) {
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
assert(excit_peek(its[0], indexes) == ES); assert(excit_peek(its[0], indexes) == ES);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment