Merge branch 'maint'
[platform/upstream/isl.git] / isl_list_templ.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2011      INRIA Saclay
4  *
5  * Use of this software is governed by the GNU LGPLv2.1 license
6  *
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
11  */
12
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)
21
22 isl_ctx *FN(LIST(EL),get_ctx)(__isl_keep LIST(EL) *list)
23 {
24         return list ? list->ctx : NULL;
25 }
26
27 __isl_give LIST(EL) *FN(LIST(EL),alloc)(isl_ctx *ctx, int n)
28 {
29         LIST(EL) *list;
30
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;
39
40         list->ctx = ctx;
41         isl_ctx_ref(ctx);
42         list->ref = 1;
43         list->size = n;
44         list->n = 0;
45         return list;
46 }
47
48 __isl_give LIST(EL) *FN(LIST(EL),copy)(__isl_keep LIST(EL) *list)
49 {
50         if (!list)
51                 return NULL;
52
53         list->ref++;
54         return list;
55 }
56
57 __isl_give LIST(EL) *FN(LIST(EL),dup)(__isl_keep LIST(EL) *list)
58 {
59         int i;
60         LIST(EL) *dup;
61
62         if (!list)
63                 return NULL;
64
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;
71 }
72
73 __isl_give LIST(EL) *FN(LIST(EL),add)(__isl_take LIST(EL) *list,
74         __isl_take struct EL *el)
75 {
76         if (!list || !el)
77                 goto error;
78         isl_assert(list->ctx, list->n < list->size, goto error);
79         list->p[list->n] = el;
80         list->n++;
81         return list;
82 error:
83         FN(EL,free)(el);
84         FN(LIST(EL),free)(list);
85         return NULL;
86 }
87
88 void *FN(LIST(EL),free)(__isl_take LIST(EL) *list)
89 {
90         int i;
91
92         if (!list)
93                 return NULL;
94
95         if (--list->ref > 0)
96                 return NULL;
97
98         isl_ctx_deref(list->ctx);
99         for (i = 0; i < list->n; ++i)
100                 FN(EL,free)(list->p[i]);
101         free(list);
102
103         return NULL;
104 }
105
106 int FN(FN(LIST(EL),n),BASE)(__isl_keep LIST(EL) *list)
107 {
108         return list ? list->n : 0;
109 }
110
111 __isl_give EL *FN(FN(LIST(EL),get),BASE)(__isl_keep LIST(EL) *list, int index)
112 {
113         if (!list)
114                 return NULL;
115         if (index < 0 || index >= list->n)
116                 isl_die(list->ctx, isl_error_invalid,
117                         "index out of bounds", return NULL);
118         return FN(EL,copy)(list->p[index]);
119 }
120
121 int FN(LIST(EL),foreach)(__isl_keep LIST(EL) *list,
122         int (*fn)(__isl_take EL *el, void *user), void *user)
123 {
124         int i;
125
126         if (!list)
127                 return -1;
128
129         for (i = 0; i < list->n; ++i) {
130                 EL *el = FN(EL,copy(list->p[i]));
131                 if (!el)
132                         return -1;
133                 if (fn(el, user) < 0)
134                         return -1;
135         }
136
137         return 0;
138 }
139
140 __isl_give LIST(EL) *FN(FN(LIST(EL),from),BASE)(__isl_take EL *el)
141 {
142         isl_ctx *ctx;
143         LIST(EL) *list;
144
145         if (!el)
146                 return NULL;
147         ctx = FN(EL,get_ctx)(el);
148         list = FN(LIST(EL),alloc)(ctx, 1);
149         if (!list)
150                 goto error;
151         list = FN(LIST(EL),add)(list, el);
152         return list;
153 error:
154         FN(EL,free)(el);
155         return NULL;
156 }
157
158 __isl_give LIST(EL) *FN(LIST(EL),concat)(__isl_take LIST(EL) *list1,
159         __isl_take LIST(EL) *list2)
160 {
161         int i;
162         isl_ctx *ctx;
163         LIST(EL) *res;
164
165         if (!list1 || !list2)
166                 goto error;
167
168         ctx = FN(LIST(EL),get_ctx)(list1);
169         res = FN(LIST(EL),alloc)(ctx, list1->n + list2->n);
170         for (i = 0; i < list1->n; ++i)
171                 res = FN(LIST(EL),add)(res, FN(EL,copy)(list1->p[i]));
172         for (i = 0; i < list2->n; ++i)
173                 res = FN(LIST(EL),add)(res, FN(EL,copy)(list2->p[i]));
174
175         FN(LIST(EL),free)(list1);
176         FN(LIST(EL),free)(list2);
177         return res;
178 error:
179         FN(LIST(EL),free)(list1);
180         FN(LIST(EL),free)(list2);
181         return NULL;
182 }
183
184 __isl_give isl_printer *CAT(isl_printer_print_,LIST(BASE))(
185         __isl_take isl_printer *p, __isl_keep LIST(EL) *list)
186 {
187         int i;
188
189         if (!p || !list)
190                 goto error;
191         p = isl_printer_print_str(p, "(");
192         for (i = 0; i < list->n; ++i) {
193                 if (i)
194                         p = isl_printer_print_str(p, ",");
195                 p = CAT(isl_printer_print_,BASE)(p, list->p[i]);
196         }
197         p = isl_printer_print_str(p, ")");
198         return p;
199 error:
200         isl_printer_free(p);
201         return NULL;
202 }
203
204 void FN(LIST(EL),dump)(__isl_keep LIST(EL) *list)
205 {
206         isl_printer *printer;
207
208         if (!list)
209                 return;
210
211         printer = isl_printer_to_file(FN(LIST(EL),get_ctx)(list), stderr);
212         printer = CAT(isl_printer_print_,LIST(BASE))(printer, list);
213         printer = isl_printer_end_line(printer);
214
215         isl_printer_free(printer);
216 }