1 /* Copyright 2016-2017 Tobias Grosser
3 * Use of this software is governed by the MIT license
5 * Written by Tobias Grosser, Weststrasse 47, CH-8003, Zurich
14 #include <isl-noexceptions.h>
16 static void assert_impl(bool condition
, const char *file
, int line
,
22 fprintf(stderr
, "Assertion failed in %s:%d %s\n", file
, line
, message
);
26 static void assert_impl(isl::boolean condition
, const char *file
, int line
,
29 assert_impl(bool(condition
), file
, line
, message
);
32 #define assert(exp) assert_impl(exp, __FILE__, __LINE__, #exp)
34 /* Test the pointer interface for interaction between isl C and C++ types.
37 * - construction from an isl C object
38 * - check that constructed objects are non-null
39 * - get a non-owned C pointer from an isl C++ object usable in __isl_keep
41 * - use copy to get an owned C pointer from an isl C++ object which is usable
42 * in __isl_take methods. Verify that the original C++ object retains a valid
44 * - use release to get an owned C pointer from an isl C++ object which is
45 * usable in __isl_take methods. Verify that the original C++ object gave up
46 * its pointer and now is null.
48 void test_pointer(isl::ctx ctx
)
50 isl_set
*c_empty
= isl_set_read_from_str(ctx
.get(), "{ : false }");
51 isl::set empty
= isl::manage(c_empty
);
52 assert(empty
.is_empty());
53 assert(isl_set_is_empty(empty
.get()));
55 assert(!empty
.is_null());
56 isl_set_free(empty
.copy());
57 assert(!empty
.is_null());
58 isl_set_free(empty
.release());
59 assert(empty
.is_null());
62 /* Test that isl objects can be constructed.
65 * - construction of a null object
66 * - construction from a string
67 * - construction from an integer
68 * - static constructor without a parameter
69 * - conversion construction (implicit)
70 * - conversion construction (explicit)
72 * The tests to construct from integers and strings cover functionality that
73 * is also tested in the parameter type tests, but here we verify that
74 * multiple overloaded constructors are available and that overload resolution
77 * Construction from an isl C pointer is tested in test_pointer.
79 void test_constructors(isl::ctx ctx
)
82 assert(null
.is_null());
84 isl::val zero_from_str
= isl::val(ctx
, "0");
85 assert(zero_from_str
.is_zero());
87 isl::val zero_int_con
= isl::val(ctx
, 0);
88 assert(zero_int_con
.is_zero());
90 isl::val zero_static_con
= isl::val::zero(ctx
);
91 assert(zero_static_con
.is_zero());
93 isl::basic_set
bs(ctx
, "{ [1] }");
94 isl::set
result(ctx
, "{ [1] }");
96 assert(s
.is_equal(result
));
98 assert(s
.unite(s2
).is_equal(result
));
101 /* Test integer function parameters.
103 * Verify that extreme values and zero work.
105 void test_parameters_int(isl::ctx ctx
)
107 isl::val
long_max_str(ctx
, std::to_string(LONG_MAX
));
108 isl::val
long_max_int(ctx
, LONG_MAX
);
109 assert(long_max_str
.eq(long_max_int
));
111 isl::val
long_min_str(ctx
, std::to_string(LONG_MIN
));
112 isl::val
long_min_int(ctx
, LONG_MIN
);
113 assert(long_min_str
.eq(long_min_int
));
115 isl::val long_zero_str
= isl::val(ctx
, std::to_string(0));
116 isl::val long_zero_int
= isl::val(ctx
, 0);
117 assert(long_zero_str
.eq(long_zero_int
));
120 /* Test isl objects parameters.
122 * Verify that isl objects can be passed as lvalue and rvalue parameters.
123 * Also verify that isl object parameters are automatically type converted if
124 * there is an inheritance relation. Finally, test function calls without
125 * any additional parameters, apart from the isl object on which
126 * the method is called.
128 void test_parameters_obj(isl::ctx ctx
)
130 isl::set
a(ctx
, "{ [0] }");
131 isl::set
b(ctx
, "{ [1] }");
132 isl::set
c(ctx
, "{ [2] }");
133 isl::set
expected(ctx
, "{ [i] : 0 <= i <= 2 }");
135 isl::set tmp
= a
.unite(b
);
136 isl::set res_lvalue_param
= tmp
.unite(c
);
137 assert(res_lvalue_param
.is_equal(expected
));
139 isl::set res_rvalue_param
= a
.unite(b
).unite(c
);
140 assert(res_rvalue_param
.is_equal(expected
));
142 isl::basic_set
a2(ctx
, "{ [0] }");
143 assert(a
.is_equal(a2
));
145 isl::val
two(ctx
, 2);
146 isl::val
half(ctx
, "1/2");
147 isl::val res_only_this_param
= two
.inv();
148 assert(res_only_this_param
.eq(half
));
151 /* Test different kinds of parameters to be passed to functions.
153 * This includes integer and isl C++ object parameters.
155 void test_parameters(isl::ctx ctx
)
157 test_parameters_int(ctx
);
158 test_parameters_obj(ctx
);
161 /* Test that isl objects are returned correctly.
163 * This only tests that after combining two objects, the result is successfully
166 void test_return_obj(isl::ctx ctx
)
168 isl::val
one(ctx
, "1");
169 isl::val
two(ctx
, "2");
170 isl::val
three(ctx
, "3");
172 isl::val res
= one
.add(two
);
174 assert(res
.eq(three
));
177 /* Test that integer values are returned correctly.
179 void test_return_int(isl::ctx ctx
)
181 isl::val
one(ctx
, "1");
182 isl::val
neg_one(ctx
, "-1");
183 isl::val
zero(ctx
, "0");
185 assert(one
.sgn() > 0);
186 assert(neg_one
.sgn() < 0);
187 assert(zero
.sgn() == 0);
190 /* Test that isl_bool values are returned correctly.
192 * We check in detail the following parts of the isl::boolean class:
193 * - The is_true, is_false, and is_error functions return true in case they
194 * are called on a true, false, or error instance of isl::boolean,
196 * - Explicit conversion to 'bool'
197 * - Implicit conversion to 'bool'
198 * - The complement operator
199 * - Explicit construction from 'true' and 'false'
200 * - Explicit construction form isl_bool
202 void test_return_bool(isl::ctx ctx
)
204 isl::set
empty(ctx
, "{ : false }");
205 isl::set
univ(ctx
, "{ : }");
208 isl::boolean b_true
= empty
.is_empty();
209 isl::boolean b_false
= univ
.is_empty();
210 isl::boolean b_error
= null
.is_empty();
212 assert(b_true
.is_true());
213 assert(!b_true
.is_false());
214 assert(!b_true
.is_error());
216 assert(!b_false
.is_true());
217 assert(b_false
.is_false());
218 assert(!b_false
.is_error());
220 assert(!b_error
.is_true());
221 assert(!b_error
.is_false());
222 assert(b_error
.is_error());
224 assert(bool(b_true
) == true);
225 assert(bool(b_false
) == false);
229 assert((!b_false
).is_true());
230 assert((!b_true
).is_false());
231 assert((!b_error
).is_error());
233 assert(isl::boolean(true).is_true());
234 assert(!isl::boolean(true).is_false());
235 assert(!isl::boolean(true).is_error());
237 assert(isl::boolean(false).is_false());
238 assert(!isl::boolean(false).is_true());
239 assert(!isl::boolean(false).is_error());
241 assert(isl::manage(isl_bool_true
).is_true());
242 assert(!isl::manage(isl_bool_true
).is_false());
243 assert(!isl::manage(isl_bool_true
).is_error());
245 assert(isl::manage(isl_bool_false
).is_false());
246 assert(!isl::manage(isl_bool_false
).is_true());
247 assert(!isl::manage(isl_bool_false
).is_error());
249 assert(isl::manage(isl_bool_error
).is_error());
250 assert(!isl::manage(isl_bool_error
).is_true());
251 assert(!isl::manage(isl_bool_error
).is_false());
254 /* Test that strings are returned correctly.
256 void test_return_string(isl::ctx ctx
)
258 isl::set
context(ctx
, "[n] -> { : }");
259 isl::ast_build build
= isl::ast_build::from_context(context
);
260 isl::pw_aff
pw_aff(ctx
, "[n] -> { [n] }");
262 isl::ast_expr expr
= build
.expr_from(pw_aff
);
263 const char *expected_string
= "n";
264 assert(expected_string
== expr
.to_C_str());
267 /* Test that return values are handled correctly.
269 * Test that isl C++ objects, integers, boolean values, and strings are
270 * returned correctly.
272 void test_return(isl::ctx ctx
)
274 test_return_obj(ctx
);
275 test_return_int(ctx
);
276 test_return_bool(ctx
);
277 test_return_string(ctx
);
280 /* Test that foreach functions are modeled correctly.
282 * Verify that lambdas are correctly called as callback of a 'foreach'
283 * function and that variables captured by the lambda work correctly. Also
284 * check that the foreach function takes account of the return value of the
285 * lambda and aborts in case isl::stat::error is returned and then returns
286 * isl::stat::error itself.
288 void test_foreach(isl::ctx ctx
)
290 isl::set
s(ctx
, "{ [0]; [1]; [2] }");
292 std::vector
<isl::basic_set
> basic_sets
;
294 auto add_to_vector
= [&] (isl::basic_set bs
) {
295 basic_sets
.push_back(bs
);
296 return isl::stat::ok
;
299 isl::stat ret1
= s
.foreach_basic_set(add_to_vector
);
301 assert(ret1
== isl::stat::ok
);
302 assert(basic_sets
.size() == 3);
303 assert(isl::set(basic_sets
[0]).is_subset(s
));
304 assert(isl::set(basic_sets
[1]).is_subset(s
));
305 assert(isl::set(basic_sets
[2]).is_subset(s
));
306 assert(!basic_sets
[0].is_equal(basic_sets
[1]));
308 auto fail
= [&] (isl::basic_set bs
) {
309 return isl::stat::error
;
312 isl::stat ret2
= s
.foreach_basic_set(fail
);
314 assert(ret2
== isl::stat::error
);
317 /* Test the isl C++ interface
320 * - The isl C <-> C++ pointer interface
321 * - Object construction
322 * - Different parameter types
323 * - Different return types
324 * - Foreach functions
328 isl_ctx
*ctx
= isl_ctx_alloc();
331 test_constructors(ctx
);
332 test_parameters(ctx
);