isl_test_cpp17-generic.cc: work around std::optional::value issue in older macOS
[isl.git] / isl_power_templ.c
blob26f0fe5573bf1c59bc4eead90dbcb0e1c2788b5a
1 #include <isl_val_private.h>
3 #define xFN(TYPE,NAME) TYPE ## _ ## NAME
4 #define FN(TYPE,NAME) xFN(TYPE,NAME)
6 /* Helper function for isl_*_fixed_power that applies (a copy of) "map2"
7 * to the range of "map1" and returns the result.
9 * The result is coalesced in an attempt to reduce the number of disjuncts
10 * that result from repeated applications.
11 * Similarly, look for implicit equality constraints in an attempt
12 * to reduce the number of local variables that get introduced
13 * during the repeated applications.
15 static __isl_give TYPE *FN(TYPE,fixed_power_apply)(__isl_take TYPE *map1,
16 __isl_keep TYPE *map2)
18 TYPE *res;
20 res = FN(TYPE,apply_range)(map1, FN(TYPE,copy)(map2));
21 res = FN(TYPE,detect_equalities)(res);
22 res = FN(TYPE,coalesce)(res);
24 return res;
27 /* Compute the given non-zero power of "map" and return the result.
28 * If the exponent "exp" is negative, then the -exp th power of the inverse
29 * relation is computed.
31 __isl_give TYPE *FN(TYPE,fixed_power)(__isl_take TYPE *map, isl_int exp)
33 isl_ctx *ctx;
34 TYPE *res = NULL;
35 isl_int r;
37 if (!map)
38 return NULL;
40 ctx = FN(TYPE,get_ctx)(map);
41 if (isl_int_is_zero(exp))
42 isl_die(ctx, isl_error_invalid,
43 "expecting non-zero exponent", goto error);
45 if (isl_int_is_neg(exp)) {
46 isl_int_neg(exp, exp);
47 map = FN(TYPE,reverse)(map);
48 return FN(TYPE,fixed_power)(map, exp);
51 isl_int_init(r);
52 for (;;) {
53 isl_int_fdiv_r(r, exp, ctx->two);
55 if (!isl_int_is_zero(r)) {
56 if (!res)
57 res = FN(TYPE,copy)(map);
58 else
59 res = FN(TYPE,fixed_power_apply)(res, map);
60 if (!res)
61 break;
64 isl_int_fdiv_q(exp, exp, ctx->two);
65 if (isl_int_is_zero(exp))
66 break;
68 map = FN(TYPE,fixed_power_apply)(map, map);
70 isl_int_clear(r);
72 FN(TYPE,free)(map);
73 return res;
74 error:
75 FN(TYPE,free)(map);
76 return NULL;
79 /* Compute the given non-zero power of "map" and return the result.
80 * If the exponent "exp" is negative, then the -exp th power of the inverse
81 * relation is computed.
83 __isl_give TYPE *FN(TYPE,fixed_power_val)(__isl_take TYPE *map,
84 __isl_take isl_val *exp)
86 if (!map || !exp)
87 goto error;
88 if (!isl_val_is_int(exp))
89 isl_die(FN(TYPE,get_ctx)(map), isl_error_invalid,
90 "expecting integer exponent", goto error);
91 map = FN(TYPE,fixed_power)(map, exp->n);
92 isl_val_free(exp);
93 return map;
94 error:
95 FN(TYPE,free)(map);
96 isl_val_free(exp);
97 return NULL;