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)
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
)
32 isl_die(ctx
, isl_error_invalid
,
33 "cannot create list of negative length",
35 list
= isl_alloc(ctx
, LIST(EL
),
36 sizeof(LIST(EL
)) + (n
- 1) * sizeof(struct EL
*));
48 __isl_give
LIST(EL
) *FN(LIST(EL
),copy
)(__isl_keep
LIST(EL
) *list
)
57 __isl_give
LIST(EL
) *FN(LIST(EL
),dup
)(__isl_keep
LIST(EL
) *list
)
65 dup
= FN(LIST(EL
),alloc
)(FN(LIST(EL
),get_ctx
)(list
), list
->n
);
68 for (i
= 0; i
< list
->n
; ++i
)
69 dup
= FN(LIST(EL
),add
)(dup
, FN(EL
,copy
)(list
->p
[i
]));
73 __isl_give
LIST(EL
) *FN(LIST(EL
),cow
)(__isl_take
LIST(EL
) *list
)
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
)
97 if (list
->n
+ n
<= list
->size
)
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
*));
106 return FN(LIST(EL
),free
)(list
);
107 res
->size
= new_size
;
111 res
= FN(LIST(EL
),alloc
)(ctx
, new_size
);
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
);
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);
128 list
->p
[list
->n
] = el
;
133 FN(LIST(EL
),free
)(list
);
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
)
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
));
151 list
= FN(LIST(EL
),cow
)(list
);
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
];
162 void *FN(LIST(EL
),free
)(__isl_take
LIST(EL
) *list
)
172 isl_ctx_deref(list
->ctx
);
173 for (i
= 0; i
< list
->n
; ++i
)
174 FN(EL
,free
)(list
->p
[i
]);
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
)
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
)
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
) {
209 list
= FN(LIST(EL
),cow
)(list
);
212 FN(EL
,free
)(list
->p
[index
]);
217 FN(LIST(EL
),free
)(list
);
221 int FN(LIST(EL
),foreach
)(__isl_keep
LIST(EL
) *list
,
222 int (*fn
)(__isl_take EL
*el
, void *user
), void *user
)
229 for (i
= 0; i
< list
->n
; ++i
) {
230 EL
*el
= FN(EL
,copy(list
->p
[i
]));
233 if (fn(el
, user
) < 0)
240 __isl_give
LIST(EL
) *FN(FN(LIST(EL
),from
),BASE
)(__isl_take EL
*el
)
247 ctx
= FN(EL
,get_ctx
)(el
);
248 list
= FN(LIST(EL
),alloc
)(ctx
, 1);
251 list
= FN(LIST(EL
),add
)(list
, el
);
258 __isl_give
LIST(EL
) *FN(LIST(EL
),concat
)(__isl_take
LIST(EL
) *list1
,
259 __isl_take
LIST(EL
) *list2
)
265 if (!list1
|| !list2
)
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
);
279 FN(LIST(EL
),free
)(list1
);
280 FN(LIST(EL
),free
)(list2
);
284 __isl_give isl_printer
*CAT(isl_printer_print_
,LIST(BASE
))(
285 __isl_take isl_printer
*p
, __isl_keep
LIST(EL
) *list
)
291 p
= isl_printer_print_str(p
, "(");
292 for (i
= 0; i
< list
->n
; ++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
, ")");
304 void FN(LIST(EL
),dump
)(__isl_keep
LIST(EL
) *list
)
306 isl_printer
*printer
;
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
);