1 /*
2  * Copyright 2011      Sven Verdoolaege
3  * Copyright 2012-2013 Ecole Normale Superieure
4  *
5  * Use of this software is governed by the MIT license
6  *
7  * Written by Sven Verdoolaege,
8  * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
9  */
10 
11 #include <isl_multi_macro.h>
12 
13 /* Transform the elements of "multi" by applying "fn" to them
14  * with extra argument "set".
15  *
16  * The parameters of "multi" and "set" are assumed to have been aligned.
17  */
MULTI(BASE)18 __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)(
19 	__isl_take MULTI(BASE) *multi, __isl_take APPLY_DOM *set,
20 	__isl_give EL *(*fn)(EL *el, __isl_take APPLY_DOM *set))
21 {
22 	int i;
23 
24 	if (!multi || !set)
25 		goto error;
26 
27 	if (multi->n == 0) {
28 		FN(APPLY_DOM,free)(set);
29 		return multi;
30 	}
31 
32 	multi = FN(MULTI(BASE),cow)(multi);
33 	if (!multi)
34 		goto error;
35 
36 	for (i = 0; i < multi->n; ++i) {
37 		multi->u.p[i] = fn(multi->u.p[i], FN(APPLY_DOM,copy)(set));
38 		if (!multi->u.p[i])
39 			goto error;
40 	}
41 
42 	FN(APPLY_DOM,free)(set);
43 	return multi;
44 error:
45 	FN(APPLY_DOM,free)(set);
46 	FN(MULTI(BASE),free)(multi);
47 	return NULL;
48 }
49 
50 /* Transform the elements of "multi" by applying "fn" to them
51  * with extra argument "set".
52  *
53  * Align the parameters if needed and call apply_set_aligned.
54  */
MULTI(BASE)55 static __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply),APPLY_DOMBASE)(
56 	__isl_take MULTI(BASE) *multi, __isl_take APPLY_DOM *set,
57 	__isl_give EL *(*fn)(EL *el, __isl_take APPLY_DOM *set))
58 {
59 	isl_bool aligned;
60 	isl_ctx *ctx;
61 
62 	if (!multi || !set)
63 		goto error;
64 
65 	aligned = FN(APPLY_DOM,space_has_equal_params)(set, multi->space);
66 	if (aligned < 0)
67 		goto error;
68 	if (aligned)
69 		return FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)(multi,
70 								    set, fn);
71 	ctx = FN(MULTI(BASE),get_ctx)(multi);
72 	if (!isl_space_has_named_params(multi->space) ||
73 	    !isl_space_has_named_params(set->dim))
74 		isl_die(ctx, isl_error_invalid,
75 			"unaligned unnamed parameters", goto error);
76 	multi = FN(MULTI(BASE),align_params)(multi,
77 						FN(APPLY_DOM,get_space)(set));
78 	set = FN(APPLY_DOM,align_params)(set, FN(MULTI(BASE),get_space)(multi));
79 	return FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)(multi, set, fn);
80 error:
81 	FN(MULTI(BASE),free)(multi);
82 	FN(APPLY_DOM,free)(set);
83 	return NULL;
84 }
85