add isl_flow application
[isl.git] / interface / isl_test_cpp.cpp
blob6059208d0b36d41f7dd816ea51878ad110e49d04
1 #include <vector>
2 #include <string>
3 #include <limits.h>
4 #include <stdio.h>
5 #include <stdlib.h>
7 #include <isl-noexceptions.h>
9 static void assert_impl(bool condition, const char *file, int line,
10 const char *message)
12 if (condition)
13 return;
15 fprintf(stderr, "Assertion failed in %s:%d %s\n", file, line, message);
16 exit(EXIT_FAILURE);
19 static void assert_impl(isl::boolean condition, const char *file, int line,
20 const char *message)
22 assert_impl(bool(condition), file, line, message);
25 #define assert(exp) assert_impl(exp, __FILE__, __LINE__, #exp)
27 /* Test the pointer interface for interaction between isl C and C++ types.
29 * This tests:
30 * - construction from an isl C object
31 * - check that constructed objects are non-null
32 * - get a non-owned C pointer from an isl C++ object usable in __isl_keep
33 * methods
34 * - use copy to get an owned C pointer from an isl C++ object which is usable
35 * in __isl_take methods. Verify that the original C++ object retains a valid
36 * pointer.
37 * - use release to get an owned C pointer from an isl C++ object which is
38 * usable in __isl_take methods. Verify that the original C++ object gave up
39 * its pointer and now is null.
41 void test_pointer(isl::ctx ctx)
43 isl_set *c_empty = isl_set_read_from_str(ctx.get(), "{ : false }");
44 isl::set empty = isl::manage(c_empty);
45 assert(empty.is_empty());
46 assert(isl_set_is_empty(empty.get()));
48 assert(!empty.is_null());
49 isl_set_free(empty.copy());
50 assert(!empty.is_null());
51 isl_set_free(empty.release());
52 assert(empty.is_null());
55 /* Test that isl objects can be constructed.
57 * This tests:
58 * - construction of a null object
59 * - construction from a string
60 * - construction from an integer
61 * - static constructor without a parameter
62 * - conversion construction (implicit)
63 * - conversion construction (explicit)
65 * The tests to construct from integers and strings cover functionality that
66 * is also tested in the parameter type tests, but here we verify that
67 * multiple overloaded constructors are available and that overload resolution
68 * works as expected.
70 * Construction from an isl C pointer is tested in test_pointer.
72 void test_constructors(isl::ctx ctx)
74 isl::val null;
75 assert(null.is_null());
77 isl::val zero_from_str = isl::val(ctx, "0");
78 assert(zero_from_str.is_zero());
80 isl::val zero_int_con = isl::val(ctx, 0);
81 assert(zero_int_con.is_zero());
83 isl::val zero_static_con = isl::val::zero(ctx);
84 assert(zero_static_con.is_zero());
86 isl::basic_set bs(ctx, "{ [1] }");
87 isl::set result(ctx, "{ [1] }");
88 isl::set s = bs;
89 assert(s.is_equal(result));
90 isl::set s2(bs);
91 assert(s.unite(s2).is_equal(result));
94 /* Test integer function parameters.
96 * Verify that extreme values and zero work.
98 void test_parameters_int(isl::ctx ctx)
100 isl::val long_max_str(ctx, std::to_string(LONG_MAX));
101 isl::val long_max_int(ctx, LONG_MAX);
102 assert(long_max_str.eq(long_max_int));
104 isl::val long_min_str(ctx, std::to_string(LONG_MIN));
105 isl::val long_min_int(ctx, LONG_MIN);
106 assert(long_min_str.eq(long_min_int));
108 isl::val long_zero_str = isl::val(ctx, std::to_string(0));
109 isl::val long_zero_int = isl::val(ctx, 0);
110 assert(long_zero_str.eq(long_zero_int));
113 /* Test isl objects parameters.
115 * Verify that isl objects can be passed as lvalue and rvalue parameters.
116 * Also verify that isl object parameters are automatically type converted if
117 * there is an inheritance relation. Finally, test function calls without
118 * any additional parameters, apart from the isl object on which
119 * the method is called.
121 void test_parameters_obj(isl::ctx ctx)
123 isl::set a(ctx, "{ [0] }");
124 isl::set b(ctx, "{ [1] }");
125 isl::set c(ctx, "{ [2] }");
126 isl::set expected(ctx, "{ [i] : 0 <= i <= 2 }");
128 isl::set tmp = a.unite(b);
129 isl::set res_lvalue_param = tmp.unite(c);
130 assert(res_lvalue_param.is_equal(expected));
132 isl::set res_rvalue_param = a.unite(b).unite(c);
133 assert(res_rvalue_param.is_equal(expected));
135 isl::basic_set a2(ctx, "{ [0] }");
136 assert(a.is_equal(a2));
138 isl::val two(ctx, 2);
139 isl::val half(ctx, "1/2");
140 isl::val res_only_this_param = two.inv();
141 assert(res_only_this_param.eq(half));
144 /* Test different kinds of parameters to be passed to functions.
146 * This includes integer and isl C++ object parameters.
148 void test_parameters(isl::ctx ctx)
150 test_parameters_int(ctx);
151 test_parameters_obj(ctx);
154 /* Test that isl objects are returned correctly.
156 * This only tests that after combining two objects, the result is successfully
157 * returned.
159 void test_return_obj(isl::ctx ctx)
161 isl::val one(ctx, "1");
162 isl::val two(ctx, "2");
163 isl::val three(ctx, "3");
165 isl::val res = one.add(two);
167 assert(res.eq(three));
170 /* Test that integer values are returned correctly.
172 void test_return_int(isl::ctx ctx)
174 isl::val one(ctx, "1");
175 isl::val neg_one(ctx, "-1");
176 isl::val zero(ctx, "0");
178 assert(one.sgn() > 0);
179 assert(neg_one.sgn() < 0);
180 assert(zero.sgn() == 0);
183 /* Test that isl_bool values are returned correctly.
185 * We check in detail the following parts of the isl::boolean class:
186 * - The is_true, is_false, and is_error functions return true in case they
187 * are called on a true, false, or error instance of isl::boolean,
188 * respectively
189 * - Explicit conversion to 'bool'
190 * - Implicit conversion to 'bool'
191 * - The complement operator
192 * - Explicit construction from 'true' and 'false'
193 * - Explicit construction form isl_bool
195 void test_return_bool(isl::ctx ctx)
197 isl::set empty(ctx, "{ : false }");
198 isl::set univ(ctx, "{ : }");
199 isl::set null;
201 isl::boolean b_true = empty.is_empty();
202 isl::boolean b_false = univ.is_empty();
203 isl::boolean b_error = null.is_empty();
205 assert(b_true.is_true());
206 assert(!b_true.is_false());
207 assert(!b_true.is_error());
209 assert(!b_false.is_true());
210 assert(b_false.is_false());
211 assert(!b_false.is_error());
213 assert(!b_error.is_true());
214 assert(!b_error.is_false());
215 assert(b_error.is_error());
217 assert(bool(b_true) == true);
218 assert(bool(b_false) == false);
220 assert(b_true);
222 assert((!b_false).is_true());
223 assert((!b_true).is_false());
224 assert((!b_error).is_error());
226 assert(isl::boolean(true).is_true());
227 assert(!isl::boolean(true).is_false());
228 assert(!isl::boolean(true).is_error());
230 assert(isl::boolean(false).is_false());
231 assert(!isl::boolean(false).is_true());
232 assert(!isl::boolean(false).is_error());
234 assert(isl::manage(isl_bool_true).is_true());
235 assert(!isl::manage(isl_bool_true).is_false());
236 assert(!isl::manage(isl_bool_true).is_error());
238 assert(isl::manage(isl_bool_false).is_false());
239 assert(!isl::manage(isl_bool_false).is_true());
240 assert(!isl::manage(isl_bool_false).is_error());
242 assert(isl::manage(isl_bool_error).is_error());
243 assert(!isl::manage(isl_bool_error).is_true());
244 assert(!isl::manage(isl_bool_error).is_false());
247 /* Test that strings are returned correctly.
249 void test_return_string(isl::ctx ctx)
251 isl::set context(ctx, "[n] -> { : }");
252 isl::ast_build build = isl::ast_build::from_context(context);
253 isl::pw_aff pw_aff(ctx, "[n] -> { [n] }");
255 isl::ast_expr expr = build.expr_from(pw_aff);
256 const char *expected_string = "n";
257 assert(expected_string == expr.to_C_str());
260 /* Test that return values are handled correctly.
262 * Test that isl C++ objects, integers, boolean values, and strings are
263 * returned correctly.
265 void test_return(isl::ctx ctx)
267 test_return_obj(ctx);
268 test_return_int(ctx);
269 test_return_bool(ctx);
270 test_return_string(ctx);
273 /* Test that foreach functions are modeled correctly.
275 * Verify that lambdas are correctly called as callback of a 'foreach'
276 * function and that variables captured by the lambda work correctly. Also
277 * check that the foreach function takes account of the return value of the
278 * lambda and aborts in case isl::stat::error is returned and then returns
279 * isl::stat::error itself.
281 void test_foreach(isl::ctx ctx)
283 isl::set s(ctx, "{ [0]; [1]; [2] }");
285 std::vector<isl::basic_set> basic_sets;
287 auto add_to_vector = [&] (isl::basic_set bs) {
288 basic_sets.push_back(bs);
289 return isl::stat::ok;
292 isl::stat ret1 = s.foreach_basic_set(add_to_vector);
294 assert(ret1 == isl::stat::ok);
295 assert(basic_sets.size() == 3);
296 assert(isl::set(basic_sets[0]).is_subset(s));
297 assert(isl::set(basic_sets[1]).is_subset(s));
298 assert(isl::set(basic_sets[2]).is_subset(s));
299 assert(!basic_sets[0].is_equal(basic_sets[1]));
301 auto fail = [&] (isl::basic_set bs) {
302 return isl::stat::error;
305 isl::stat ret2 = s.foreach_basic_set(fail);
307 assert(ret2 == isl::stat::error);
310 /* Test the isl C++ interface
312 * This includes:
313 * - The isl C <-> C++ pointer interface
314 * - Object construction
315 * - Different parameter types
316 * - Different return types
317 * - Foreach functions
319 int main()
321 isl_ctx *ctx = isl_ctx_alloc();
323 test_pointer(ctx);
324 test_constructors(ctx);
325 test_parameters(ctx);
326 test_return(ctx);
327 test_foreach(ctx);
329 isl_ctx_free(ctx);