add isl_set_plain_get_val_if_fixed
[isl.git] / isl_power_templ.c
blobb9fc559d54e278896fa071f69e42ed252e15f730
1 #define xFN(TYPE,NAME) TYPE ## _ ## NAME
2 #define FN(TYPE,NAME) xFN(TYPE,NAME)
4 /* Compute the given non-zero power of "map" and return the result.
5 * If the exponent "exp" is negative, then the -exp th power of the inverse
6 * relation is computed.
7 */
8 __isl_give TYPE *FN(TYPE,fixed_power)(__isl_take TYPE *map, isl_int exp)
10 isl_ctx *ctx;
11 TYPE *res = NULL;
12 isl_int r;
14 if (!map)
15 return NULL;
17 ctx = FN(TYPE,get_ctx)(map);
18 if (isl_int_is_zero(exp))
19 isl_die(ctx, isl_error_invalid,
20 "expecting non-zero exponent", goto error);
22 if (isl_int_is_neg(exp)) {
23 isl_int_neg(exp, exp);
24 map = FN(TYPE,reverse)(map);
25 return FN(TYPE,fixed_power)(map, exp);
28 isl_int_init(r);
29 for (;;) {
30 isl_int_fdiv_r(r, exp, ctx->two);
32 if (!isl_int_is_zero(r)) {
33 if (!res)
34 res = FN(TYPE,copy)(map);
35 else {
36 res = FN(TYPE,apply_range)(res,
37 FN(TYPE,copy)(map));
38 res = FN(TYPE,coalesce)(res);
40 if (!res)
41 break;
44 isl_int_fdiv_q(exp, exp, ctx->two);
45 if (isl_int_is_zero(exp))
46 break;
48 map = FN(TYPE,apply_range)(map, FN(TYPE,copy)(map));
49 map = FN(TYPE,coalesce)(map);
51 isl_int_clear(r);
53 FN(TYPE,free)(map);
54 return res;
55 error:
56 FN(TYPE,free)(map);
57 return NULL;