isl_polynomial.c: qpolynomial_fold_alloc: fix up condition
[isl.git] / isl_pw_templ.c
blobd585e2f550282a87cef659d94977619608de38bc
1 #define xFN(TYPE,NAME) TYPE ## _ ## NAME
2 #define FN(TYPE,NAME) xFN(TYPE,NAME)
3 #define xS(TYPE,NAME) struct TYPE ## _ ## NAME
4 #define S(TYPE,NAME) xS(TYPE,NAME)
6 static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim, int n)
8 struct PW *pw;
10 if (!dim)
11 return NULL;
12 isl_assert(dim->ctx, n >= 0, goto error);
13 pw = isl_alloc(dim->ctx, struct PW,
14 sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)));
15 if (!pw)
16 goto error;
18 pw->ref = 1;
19 pw->size = n;
20 pw->n = 0;
21 pw->dim = dim;
22 return pw;
23 error:
24 isl_dim_free(dim);
25 return NULL;
28 __isl_give PW *FN(PW,zero)(__isl_take isl_dim *dim)
30 return FN(PW,alloc_)(dim, 0);
33 __isl_give PW *FN(PW,add_piece)(__isl_take PW *pw,
34 __isl_take isl_set *set, __isl_take EL *el)
36 if (!pw || !set || !el)
37 goto error;
39 if (isl_set_fast_is_empty(set) || FN(EL,IS_ZERO)(el)) {
40 isl_set_free(set);
41 FN(EL,free)(el);
42 return pw;
45 isl_assert(set->ctx, isl_dim_equal(pw->dim, el->dim), goto error);
46 isl_assert(set->ctx, pw->n < pw->size, goto error);
48 pw->p[pw->n].set = set;
49 pw->p[pw->n].FIELD = el;
50 pw->n++;
52 return pw;
53 error:
54 FN(PW,free)(pw);
55 isl_set_free(set);
56 FN(EL,free)(el);
57 return NULL;
60 __isl_give PW *FN(PW,alloc)(__isl_take isl_set *set, __isl_take EL *el)
62 PW *pw;
64 if (!set || !el)
65 goto error;
67 pw = FN(PW,alloc_)(isl_set_get_dim(set), 1);
69 return FN(PW,add_piece)(pw, set, el);
70 error:
71 isl_set_free(set);
72 FN(EL,free)(el);
73 return NULL;
76 __isl_give PW *FN(PW,dup)(__isl_keep PW *pw)
78 int i;
79 PW *dup;
81 if (!pw)
82 return NULL;
84 dup = FN(PW,alloc_)(isl_dim_copy(pw->dim), pw->n);
85 if (!dup)
86 return NULL;
88 for (i = 0; i < pw->n; ++i)
89 dup = FN(PW,add_piece)(dup, isl_set_copy(pw->p[i].set),
90 FN(EL,copy)(pw->p[i].FIELD));
92 return dup;
93 error:
94 FN(PW,free)(dup);
95 return NULL;
98 __isl_give PW *FN(PW,copy)(__isl_keep PW *pw)
100 if (!pw)
101 return;
103 pw->ref++;
104 return pw;
107 void FN(PW,free)(__isl_take PW *pw)
109 int i;
111 if (!pw)
112 return;
113 if (--pw->ref > 0)
114 return;
116 for (i = 0; i < pw->n; ++i) {
117 isl_set_free(pw->p[i].set);
118 FN(EL,free)(pw->p[i].FIELD);
120 isl_dim_free(pw->dim);
121 free(pw);
124 int FN(PW,is_zero)(__isl_keep PW *pw)
126 if (!pw)
127 return -1;
129 return pw->n == 0;
132 __isl_give PW *FN(PW,add)(__isl_take PW *pw1, __isl_take PW *pw2)
134 int i, j, n;
135 struct PW *res;
136 isl_set *set;
138 if (!pw1 || !pw2)
139 goto error;
141 isl_assert(pw1->dim->ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error);
143 if (FN(PW,is_zero)(pw1)) {
144 FN(PW,free)(pw1);
145 return pw2;
148 if (FN(PW,is_zero)(pw2)) {
149 FN(PW,free)(pw2);
150 return pw1;
153 n = (pw1->n + 1) * (pw2->n + 1);
154 res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), n);
156 for (i = 0; i < pw1->n; ++i) {
157 set = isl_set_copy(pw1->p[i].set);
158 for (j = 0; j < pw2->n; ++j) {
159 struct isl_set *common;
160 EL *sum;
161 set = isl_set_subtract(set,
162 isl_set_copy(pw2->p[j].set));
163 common = isl_set_intersect(isl_set_copy(pw1->p[i].set),
164 isl_set_copy(pw2->p[j].set));
165 if (isl_set_fast_is_empty(common)) {
166 isl_set_free(common);
167 continue;
170 sum = FN(EL,ADD)(FN(EL,copy)(pw1->p[i].FIELD),
171 FN(EL,copy)(pw2->p[j].FIELD));
173 res = FN(PW,add_piece)(res, common, sum);
175 res = FN(PW,add_piece)(res, set, FN(EL,copy)(pw1->p[i].FIELD));
178 for (j = 0; j < pw2->n; ++j) {
179 set = isl_set_copy(pw2->p[j].set);
180 for (i = 0; i < pw1->n; ++i)
181 set = isl_set_subtract(set,
182 isl_set_copy(pw1->p[i].set));
183 res = FN(PW,add_piece)(res, set, FN(EL,copy)(pw2->p[j].FIELD));
186 FN(PW,free)(pw1);
187 FN(PW,free)(pw2);
189 return res;
190 error:
191 FN(PW,free)(pw1);
192 FN(PW,free)(pw2);
193 return NULL;
196 __isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2)
198 int i;
199 PW *res;
201 if (!pw1 || !pw2)
202 goto error;
204 isl_assert(pw1->dim->ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error);
206 if (FN(PW,is_zero)(pw1)) {
207 FN(PW,free)(pw1);
208 return pw2;
211 if (FN(PW,is_zero)(pw2)) {
212 FN(PW,free)(pw2);
213 return pw1;
216 res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->n + pw2->n);
218 for (i = 0; i < pw1->n; ++i)
219 res = FN(PW,add_piece)(res,
220 isl_set_copy(pw1->p[i].set),
221 FN(EL,copy)(pw1->p[i].FIELD));
223 for (i = 0; i < pw2->n; ++i)
224 res = FN(PW,add_piece)(res,
225 isl_set_copy(pw2->p[i].set),
226 FN(EL,copy)(pw2->p[i].FIELD));
228 FN(PW,free)(pw1);
229 FN(PW,free)(pw2);
231 return res;
232 error:
233 FN(PW,free)(pw1);
234 FN(PW,free)(pw2);
235 return NULL;
238 __isl_give isl_qpolynomial *FN(PW,eval)(__isl_take PW *pw,
239 __isl_take isl_point *pnt)
241 int i;
242 int found;
243 isl_qpolynomial *qp;
245 if (!pw || !pnt)
246 goto error;
247 isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, pw->dim), goto error);
249 for (i = 0; i < pw->n; ++i) {
250 found = isl_set_contains_point(pw->p[i].set, pnt);
251 if (found < 0)
252 goto error;
253 if (found)
254 break;
256 if (found)
257 qp = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD),
258 isl_point_copy(pnt));
259 else
260 qp = isl_qpolynomial_zero(isl_dim_copy(pw->dim));
261 FN(PW,free)(pw);
262 isl_point_free(pnt);
263 return qp;
264 error:
265 FN(PW,free)(pw);
266 isl_point_free(pnt);
267 return NULL;