291
/* Internal data structure for isl_*_list_sort.
293
* "cmp" is the original comparison function.
294
* "user" is a user provided pointer that should be passed to "cmp".
296
S(LIST(EL),sort_data) {
297
int (*cmp)(__isl_keep EL *a, __isl_keep EL *b, void *user);
301
/* Compare two entries of an isl_*_list based on the user provided
302
* comparison function on pairs of isl_* objects.
304
static int FN(LIST(EL),cmp)(const void *a, const void *b, void *user)
306
S(LIST(EL),sort_data) *data = user;
310
return data->cmp(*el1, *el2, data->user);
313
/* Sort the elements of "list" in ascending order according to
314
* comparison function "cmp".
316
__isl_give LIST(EL) *FN(LIST(EL),sort)(__isl_take LIST(EL) *list,
317
int (*cmp)(__isl_keep EL *a, __isl_keep EL *b, void *user), void *user)
319
S(LIST(EL),sort_data) data = { cmp, user };
325
list = FN(LIST(EL),cow)(list);
329
if (isl_sort(list->p, list->n, sizeof(list->p[0]),
330
&FN(LIST(EL),cmp), &data) < 0)
331
return FN(LIST(EL),free)(list);
336
/* Internal data structure for isl_*_list_foreach_scc.
338
* "list" is the original list.
339
* "follows" is the user provided callback that defines the edges of the graph.
341
S(LIST(EL),foreach_scc_data) {
343
int (*follows)(__isl_keep EL *a, __isl_keep EL *b, void *user);
347
/* Does element i of data->list follow element j?
349
* Use the user provided callback to find out.
351
static int FN(LIST(EL),follows)(int i, int j, void *user)
353
S(LIST(EL),foreach_scc_data) *data = user;
355
return data->follows(data->list->p[i], data->list->p[j],
359
/* Call "fn" on the sublist of "list" that consists of the elements
360
* with indices specified by the "n" elements of "pos".
362
static int FN(LIST(EL),call_on_scc)(__isl_keep LIST(EL) *list, int *pos, int n,
363
int (*fn)(__isl_take LIST(EL) *scc, void *user), void *user)
369
ctx = FN(LIST(EL),get_ctx)(list);
370
slice = FN(LIST(EL),alloc)(ctx, n);
371
for (i = 0; i < n; ++i) {
374
el = FN(EL,copy)(list->p[pos[i]]);
375
slice = FN(LIST(EL),add)(slice, el);
378
return fn(slice, user);
381
/* Call "fn" on each of the strongly connected components (SCCs) of
382
* the graph with as vertices the elements of "list" and
383
* a directed edge from node b to node a iff follows(a, b)
384
* returns 1. follows should return -1 on error.
386
* If SCC a contains a node i that follows a node j in another SCC b
387
* (i.e., follows(i, j, user) returns 1), then fn will be called on SCC a
388
* after being called on SCC b.
390
* We simply call isl_tarjan_graph_init, extract the SCCs from the result and
391
* call fn on each of them.
393
int FN(LIST(EL),foreach_scc)(__isl_keep LIST(EL) *list,
394
int (*follows)(__isl_keep EL *a, __isl_keep EL *b, void *user),
396
int (*fn)(__isl_take LIST(EL) *scc, void *user), void *fn_user)
398
S(LIST(EL),foreach_scc_data) data = { list, follows, follows_user };
401
struct isl_tarjan_graph *g;
408
return fn(FN(LIST(EL),copy)(list), fn_user);
410
ctx = FN(LIST(EL),get_ctx)(list);
412
g = isl_tarjan_graph_init(ctx, n, &FN(LIST(EL),follows), &data);
420
if (g->order[i] == -1)
421
isl_die(ctx, isl_error_internal, "cannot happen",
424
while (g->order[i] != -1) {
427
if (first == 0 && n == 0) {
428
isl_tarjan_graph_free(g);
429
return fn(FN(LIST(EL),copy)(list), fn_user);
431
if (FN(LIST(EL),call_on_scc)(list, g->order + first, i - first,
437
isl_tarjan_graph_free(g);
439
return n > 0 ? -1 : 0;
286
442
__isl_give LIST(EL) *FN(FN(LIST(EL),from),BASE)(__isl_take EL *el)