Commit cdf33e55 authored by NICOLAS DENOYELLE's avatar NICOLAS DENOYELLE

add lib copy function required in user iterators to build the function table…

add lib copy function required in user iterators to build the function table which require a copy function which may have to copy an opaque excit_t
parent 9afc3893
......@@ -46,12 +46,12 @@ const char *excit_error_name(enum excit_error_e err)
int excit_set_dimension(excit_t it, ssize_t dimension)
{
if (!it)
return -EXCIT_EINVAL;
if (it->type != EXCIT_USER)
return -EXCIT_ENOTSUP;
it->dimension = dimension;
return EXCIT_SUCCESS;
if (!it)
return -EXCIT_EINVAL;
if (it->type != EXCIT_USER)
return -EXCIT_ENOTSUP;
it->dimension = dimension;
return EXCIT_SUCCESS;
}
int excit_get_data(excit_t it, void **data)
......@@ -82,77 +82,77 @@ int excit_get_func_table(excit_t it, struct excit_func_table_s **func_table)
/*--------------------------------------------------------------------*/
#define ALLOC_EXCIT(op) { \
it = malloc(sizeof(struct excit_s) + sizeof(struct op## _it_s)); \
if (!it) \
return NULL; \
it->data = (void *)((char *)it + sizeof(struct excit_s)); \
if (!excit_ ##op## _func_table.alloc) \
goto error; \
it->func_table = &excit_ ##op## _func_table; \
it->dimension = 0; \
if (excit_ ##op## _func_table.alloc(it)) \
goto error; \
}
#define ALLOC_EXCIT(op) { \
it = malloc(sizeof(struct excit_s) + sizeof(struct op## _it_s)); \
if (!it) \
return NULL; \
it->data = (void *)((char *)it + sizeof(struct excit_s)); \
if (!excit_ ##op## _func_table.alloc) \
goto error; \
it->func_table = &excit_ ##op## _func_table; \
it->dimension = 0; \
if (excit_ ##op## _func_table.alloc(it)) \
goto error; \
}
excit_t excit_alloc(enum excit_type_e type)
{
excit_t it = NULL;
switch (type) {
case EXCIT_RANGE:
ALLOC_EXCIT(range);
break;
case EXCIT_CONS:
ALLOC_EXCIT(cons);
break;
case EXCIT_REPEAT:
ALLOC_EXCIT(repeat);
break;
case EXCIT_HILBERT2D:
ALLOC_EXCIT(hilbert2d);
break;
case EXCIT_PRODUCT:
ALLOC_EXCIT(prod);
break;
case EXCIT_SLICE:
ALLOC_EXCIT(slice);
break;
case EXCIT_TLEAF:
ALLOC_EXCIT(tleaf);
break;
default:
goto error;
}
it->type = type;
return it;
excit_t it = NULL;
switch (type) {
case EXCIT_RANGE:
ALLOC_EXCIT(range);
break;
case EXCIT_CONS:
ALLOC_EXCIT(cons);
break;
case EXCIT_REPEAT:
ALLOC_EXCIT(repeat);
break;
case EXCIT_HILBERT2D:
ALLOC_EXCIT(hilbert2d);
break;
case EXCIT_PRODUCT:
ALLOC_EXCIT(prod);
break;
case EXCIT_SLICE:
ALLOC_EXCIT(slice);
break;
case EXCIT_TLEAF:
ALLOC_EXCIT(tleaf);
break;
default:
goto error;
}
it->type = type;
return it;
error:
free(it);
return NULL;
free(it);
return NULL;
}
excit_t excit_alloc_user(struct excit_func_table_s *func_table,
size_t data_size)
{
excit_t it;
if (!func_table || !data_size)
return NULL;
it = malloc(sizeof(struct excit_s) + data_size);
if (!it)
return NULL;
it->data = (void *)((char *)it + sizeof(struct excit_s));
if (!func_table->alloc)
goto error;
it->func_table = func_table;
it->dimension = 0;
it->type = EXCIT_USER;
if (func_table->alloc(it))
goto error;
return it;
excit_t it;
if (!func_table || !data_size)
return NULL;
it = malloc(sizeof(struct excit_s) + data_size);
if (!it)
return NULL;
it->data = (void *)((char *)it + sizeof(struct excit_s));
if (!func_table->alloc)
goto error;
it->func_table = func_table;
it->dimension = 0;
it->type = EXCIT_USER;
if (func_table->alloc(it))
goto error;
return it;
error:
free(it);
return NULL;
free(it);
return NULL;
}
excit_t excit_dup(excit_t it)
......@@ -169,72 +169,87 @@ excit_t excit_dup(excit_t it)
goto error;
return result;
error:
excit_free(result);
return NULL;
excit_free(result);
return NULL;
}
void excit_free(excit_t it)
{
if (!it)
return;
if (!it->func_table)
goto error;
if (it->func_table->free)
it->func_table->free(it);
if (!it)
return;
if (!it->func_table)
goto error;
if (it->func_table->free)
it->func_table->free(it);
error:
free(it);
free(it);
}
int excit_dimension(excit_t it, ssize_t *dimension)
{
if (!it || !dimension)
return -EXCIT_EINVAL;
*dimension = it->dimension;
return EXCIT_SUCCESS;
if (!it || !dimension)
return -EXCIT_EINVAL;
*dimension = it->dimension;
return EXCIT_SUCCESS;
}
int excit_type(excit_t it, enum excit_type_e *type)
{
if (!it || !type)
return -EXCIT_EINVAL;
*type = it->type;
return EXCIT_SUCCESS;
if (!it || !type)
return -EXCIT_EINVAL;
*type = it->type;
return EXCIT_SUCCESS;
}
int excit_copy(excit_t dst, const excit_t src)
{
if (!dst ||
!src ||
!src->func_table ||
src->type != dst->type ||
src->dimension != dst->dimension)
return -EXCIT_EINVAL;
if (!src->func_table->copy)
return -EXCIT_ENOTSUP;
dst->func_table = src->func_table;
dst->dimension = src->dimension;
return src->func_table->copy(dst, src);
}
int excit_next(excit_t it, ssize_t *indexes)
{
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->next)
return -EXCIT_ENOTSUP;
return it->func_table->next(it, indexes);
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->next)
return -EXCIT_ENOTSUP;
return it->func_table->next(it, indexes);
}
int excit_peek(const excit_t it, ssize_t *indexes)
{
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->peek)
return -EXCIT_ENOTSUP;
return it->func_table->peek(it, indexes);
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->peek)
return -EXCIT_ENOTSUP;
return it->func_table->peek(it, indexes);
}
int excit_size(const excit_t it, ssize_t *size)
{
if (!it || !it->func_table || !size)
return -EXCIT_EINVAL;
if (!it->func_table->size)
return -EXCIT_ENOTSUP;
return it->func_table->size(it, size);
if (!it || !it->func_table || !size)
return -EXCIT_EINVAL;
if (!it->func_table->size)
return -EXCIT_ENOTSUP;
return it->func_table->size(it, size);
}
int excit_rewind(excit_t it)
{
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->rewind)
return -EXCIT_ENOTSUP;
return it->func_table->rewind(it);
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->rewind)
return -EXCIT_ENOTSUP;
return it->func_table->rewind(it);
}
int excit_split(const excit_t it, ssize_t n, excit_t *results)
......@@ -295,65 +310,65 @@ error1:
int excit_nth(const excit_t it, ssize_t n, ssize_t *indexes)
{
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->nth)
return -EXCIT_ENOTSUP;
return it->func_table->nth(it, n, indexes);
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->nth)
return -EXCIT_ENOTSUP;
return it->func_table->nth(it, n, indexes);
}
int excit_rank(const excit_t it, const ssize_t *indexes, ssize_t *n)
{
if (!it || !it->func_table || !indexes)
return -EXCIT_EINVAL;
if (!it->func_table->rank)
return -EXCIT_ENOTSUP;
return it->func_table->rank(it, indexes, n);
if (!it || !it->func_table || !indexes)
return -EXCIT_EINVAL;
if (!it->func_table->rank)
return -EXCIT_ENOTSUP;
return it->func_table->rank(it, indexes, n);
}
int excit_pos(const excit_t it, ssize_t *n)
{
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->pos)
return -EXCIT_ENOTSUP;
return it->func_table->pos(it, n);
if (!it || !it->func_table)
return -EXCIT_EINVAL;
if (!it->func_table->pos)
return -EXCIT_ENOTSUP;
return it->func_table->pos(it, n);
}
int excit_cyclic_next(excit_t it, ssize_t *indexes, int *looped)
{
int err;
if (!it)
return -EXCIT_EINVAL;
*looped = 0;
err = excit_next(it, indexes);
switch (err) {
case EXCIT_SUCCESS:
break;
case EXCIT_STOPIT:
err = excit_rewind(it);
if (err)
return err;
*looped = 1;
err = excit_next(it, indexes);
if (err)
return err;
break;
default:
return err;
}
if (excit_peek(it, NULL) == EXCIT_STOPIT) {
err = excit_rewind(it);
if (err)
return err;
*looped = 1;
}
return EXCIT_SUCCESS;
int err;
if (!it)
return -EXCIT_EINVAL;
*looped = 0;
err = excit_next(it, indexes);
switch (err) {
case EXCIT_SUCCESS:
break;
case EXCIT_STOPIT:
err = excit_rewind(it);
if (err)
return err;
*looped = 1;
err = excit_next(it, indexes);
if (err)
return err;
break;
default:
return err;
}
if (excit_peek(it, NULL) == EXCIT_STOPIT) {
err = excit_rewind(it);
if (err)
return err;
*looped = 1;
}
return EXCIT_SUCCESS;
}
int excit_skip(excit_t it)
{
return excit_next(it, NULL);
return excit_next(it, NULL);
}
......@@ -198,6 +198,14 @@ excit_t excit_dup(const excit_t it);
*/
void excit_free(excit_t it);
/*
* Copy an iterator.
* "dst": the copy destination.
* "src": the iterator to copy
*/
int excit_copy(excit_t dst, const excit_t src);
/*
* Get the type of an iterator
* "it": an iterator.
......@@ -418,9 +426,9 @@ enum tleaf_it_policy_e {
* Initialize a tleaf iterator by giving its depth, levels arity and iteration policy.
* "it": a tleaf iterator
* "depth": the total number of levels of the tree, including leaves
* "arity": An array of size (depth-1). For each level, the number of children attached to a node. Leaves have no children, hence last level arity is ignored.
* "arity": An array of size (depth-1). For each level, the number of children attached to a node. Leaves have no children, hence last level arity is ignored. Arities are organized from root to leaves.
* "policy": A policy for iteration on leaves.
* "user_policy": If policy is TLEAF_POLICY_USER, then this argument must be an array of size (depth-1) providing the order (from 0 to (depth-2)) in wich levels are walked
* "user_policy": If policy is TLEAF_POLICY_USER, then this argument must be an array of size (depth-1) providing the order (from 0 to (depth-2)) in wich levels are walked.
* when resolving indexes. Underneath, a product iterator of range iterator returns indexes on last levels upon iterator queries. This set of indexes is then
* computed to a single leaf index. For instance TLEAF_POLICY_ROUND_ROBIN is obtained from walking from leaves to root whereas TLEAF_POLICY_SCATTER is
* obtained from walking from root to leaves.
......
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