add isl_basic_map_upper_bound_si
[isl.git] / isl_list_templ.c
blobcd6cd9eadb7045137656994453160f5b995907a6
1 /*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2011 INRIA Saclay
5 * Use of this software is governed by the MIT license
7 * Written by Sven Verdoolaege, K.U.Leuven, Departement
8 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
13 #define xCAT(A,B) A ## B
14 #define CAT(A,B) xCAT(A,B)
15 #undef EL
16 #define EL CAT(isl_,BASE)
17 #define xFN(TYPE,NAME) TYPE ## _ ## NAME
18 #define FN(TYPE,NAME) xFN(TYPE,NAME)
19 #define xLIST(EL) EL ## _list
20 #define LIST(EL) xLIST(EL)
22 isl_ctx *FN(LIST(EL),get_ctx)(__isl_keep LIST(EL) *list)
24 return list ? list->ctx : NULL;
27 __isl_give LIST(EL) *FN(LIST(EL),alloc)(isl_ctx *ctx, int n)
29 LIST(EL) *list;
31 if (n < 0)
32 isl_die(ctx, isl_error_invalid,
33 "cannot create list of negative length",
34 return NULL);
35 list = isl_alloc(ctx, LIST(EL),
36 sizeof(LIST(EL)) + (n - 1) * sizeof(struct EL *));
37 if (!list)
38 return NULL;
40 list->ctx = ctx;
41 isl_ctx_ref(ctx);
42 list->ref = 1;
43 list->size = n;
44 list->n = 0;
45 return list;
48 __isl_give LIST(EL) *FN(LIST(EL),copy)(__isl_keep LIST(EL) *list)
50 if (!list)
51 return NULL;
53 list->ref++;
54 return list;
57 __isl_give LIST(EL) *FN(LIST(EL),dup)(__isl_keep LIST(EL) *list)
59 int i;
60 LIST(EL) *dup;
62 if (!list)
63 return NULL;
65 dup = FN(LIST(EL),alloc)(FN(LIST(EL),get_ctx)(list), list->n);
66 if (!dup)
67 return NULL;
68 for (i = 0; i < list->n; ++i)
69 dup = FN(LIST(EL),add)(dup, FN(EL,copy)(list->p[i]));
70 return dup;
73 __isl_give LIST(EL) *FN(LIST(EL),cow)(__isl_take LIST(EL) *list)
75 if (!list)
76 return NULL;
78 if (list->ref == 1)
79 return list;
80 list->ref--;
81 return FN(LIST(EL),dup)(list);
84 /* Make sure "list" has room for at least "n" more pieces.
86 * If there is only one reference to list, we extend it in place.
87 * Otherwise, we create a new LIST(EL) and copy the elements.
89 static __isl_give LIST(EL) *FN(LIST(EL),grow)(__isl_take LIST(EL) *list, int n)
91 isl_ctx *ctx;
92 int i, new_size;
93 LIST(EL) *res;
95 if (!list)
96 return NULL;
97 if (list->n + n <= list->size)
98 return list;
100 ctx = FN(LIST(EL),get_ctx)(list);
101 new_size = ((list->n + n + 1) * 3) / 2;
102 if (list->ref == 1) {
103 res = isl_realloc(ctx, list, LIST(EL),
104 sizeof(LIST(EL)) + (new_size - 1) * sizeof(EL *));
105 if (!res)
106 return FN(LIST(EL),free)(list);
107 res->size = new_size;
108 return res;
111 res = FN(LIST(EL),alloc)(ctx, new_size);
112 if (!res)
113 return FN(LIST(EL),free)(list);
115 for (i = 0; i < list->n; ++i)
116 res = FN(LIST(EL),add)(res, FN(EL,copy)(list->p[i]));
118 FN(LIST(EL),free)(list);
119 return res;
122 __isl_give LIST(EL) *FN(LIST(EL),add)(__isl_take LIST(EL) *list,
123 __isl_take struct EL *el)
125 list = FN(LIST(EL),grow)(list, 1);
126 if (!list || !el)
127 goto error;
128 list->p[list->n] = el;
129 list->n++;
130 return list;
131 error:
132 FN(EL,free)(el);
133 FN(LIST(EL),free)(list);
134 return NULL;
137 /* Remove the "n" elements starting at "first" from "list".
139 __isl_give LIST(EL) *FN(LIST(EL),drop)(__isl_take LIST(EL) *list,
140 unsigned first, unsigned n)
142 int i;
144 if (!list)
145 return NULL;
146 if (first + n > list->n || first + n < first)
147 isl_die(list->ctx, isl_error_invalid,
148 "index out of bounds", return FN(LIST(EL),free)(list));
149 if (n == 0)
150 return list;
151 list = FN(LIST(EL),cow)(list);
152 if (!list)
153 return NULL;
154 for (i = 0; i < n; ++i)
155 FN(EL,free)(list->p[first + i]);
156 for (i = first; i + n < list->n; ++i)
157 list->p[i] = list->p[i + n];
158 list->n -= n;
159 return list;
162 void *FN(LIST(EL),free)(__isl_take LIST(EL) *list)
164 int i;
166 if (!list)
167 return NULL;
169 if (--list->ref > 0)
170 return NULL;
172 isl_ctx_deref(list->ctx);
173 for (i = 0; i < list->n; ++i)
174 FN(EL,free)(list->p[i]);
175 free(list);
177 return NULL;
180 int FN(FN(LIST(EL),n),BASE)(__isl_keep LIST(EL) *list)
182 return list ? list->n : 0;
185 __isl_give EL *FN(FN(LIST(EL),get),BASE)(__isl_keep LIST(EL) *list, int index)
187 if (!list)
188 return NULL;
189 if (index < 0 || index >= list->n)
190 isl_die(list->ctx, isl_error_invalid,
191 "index out of bounds", return NULL);
192 return FN(EL,copy)(list->p[index]);
195 /* Replace the element at position "index" in "list" by "el".
197 __isl_give LIST(EL) *FN(FN(LIST(EL),set),BASE)(__isl_take LIST(EL) *list,
198 int index, __isl_take EL *el)
200 if (!list || !el)
201 goto error;
202 if (index < 0 || index >= list->n)
203 isl_die(list->ctx, isl_error_invalid,
204 "index out of bounds", goto error);
205 if (list->p[index] == el) {
206 FN(EL,free)(el);
207 return list;
209 list = FN(LIST(EL),cow)(list);
210 if (!list)
211 goto error;
212 FN(EL,free)(list->p[index]);
213 list->p[index] = el;
214 return list;
215 error:
216 FN(EL,free)(el);
217 FN(LIST(EL),free)(list);
218 return NULL;
221 int FN(LIST(EL),foreach)(__isl_keep LIST(EL) *list,
222 int (*fn)(__isl_take EL *el, void *user), void *user)
224 int i;
226 if (!list)
227 return -1;
229 for (i = 0; i < list->n; ++i) {
230 EL *el = FN(EL,copy(list->p[i]));
231 if (!el)
232 return -1;
233 if (fn(el, user) < 0)
234 return -1;
237 return 0;
240 __isl_give LIST(EL) *FN(FN(LIST(EL),from),BASE)(__isl_take EL *el)
242 isl_ctx *ctx;
243 LIST(EL) *list;
245 if (!el)
246 return NULL;
247 ctx = FN(EL,get_ctx)(el);
248 list = FN(LIST(EL),alloc)(ctx, 1);
249 if (!list)
250 goto error;
251 list = FN(LIST(EL),add)(list, el);
252 return list;
253 error:
254 FN(EL,free)(el);
255 return NULL;
258 __isl_give LIST(EL) *FN(LIST(EL),concat)(__isl_take LIST(EL) *list1,
259 __isl_take LIST(EL) *list2)
261 int i;
262 isl_ctx *ctx;
263 LIST(EL) *res;
265 if (!list1 || !list2)
266 goto error;
268 ctx = FN(LIST(EL),get_ctx)(list1);
269 res = FN(LIST(EL),alloc)(ctx, list1->n + list2->n);
270 for (i = 0; i < list1->n; ++i)
271 res = FN(LIST(EL),add)(res, FN(EL,copy)(list1->p[i]));
272 for (i = 0; i < list2->n; ++i)
273 res = FN(LIST(EL),add)(res, FN(EL,copy)(list2->p[i]));
275 FN(LIST(EL),free)(list1);
276 FN(LIST(EL),free)(list2);
277 return res;
278 error:
279 FN(LIST(EL),free)(list1);
280 FN(LIST(EL),free)(list2);
281 return NULL;
284 __isl_give isl_printer *CAT(isl_printer_print_,LIST(BASE))(
285 __isl_take isl_printer *p, __isl_keep LIST(EL) *list)
287 int i;
289 if (!p || !list)
290 goto error;
291 p = isl_printer_print_str(p, "(");
292 for (i = 0; i < list->n; ++i) {
293 if (i)
294 p = isl_printer_print_str(p, ",");
295 p = CAT(isl_printer_print_,BASE)(p, list->p[i]);
297 p = isl_printer_print_str(p, ")");
298 return p;
299 error:
300 isl_printer_free(p);
301 return NULL;
304 void FN(LIST(EL),dump)(__isl_keep LIST(EL) *list)
306 isl_printer *printer;
308 if (!list)
309 return;
311 printer = isl_printer_to_file(FN(LIST(EL),get_ctx)(list), stderr);
312 printer = CAT(isl_printer_print_,LIST(BASE))(printer, list);
313 printer = isl_printer_end_line(printer);
315 isl_printer_free(printer);