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/options.h>
15 #include <isl-noexceptions.h>
17 static void assert_impl(bool condition
, const char *file
, int line
,
23 fprintf(stderr
, "Assertion failed in %s:%d %s\n", file
, line
, message
);
27 static void assert_impl(isl::boolean condition
, const char *file
, int line
,
30 assert_impl(bool(condition
), file
, line
, message
);
33 #define assert(exp) assert_impl(exp, __FILE__, __LINE__, #exp)
35 /* Test the pointer interface for interaction between isl C and C++ types.
38 * - construction from an isl C object
39 * - check that constructed objects are non-null
40 * - get a non-owned C pointer from an isl C++ object usable in __isl_keep
42 * - use copy to get an owned C pointer from an isl C++ object which is usable
43 * in __isl_take methods. Verify that the original C++ object retains a valid
45 * - use release to get an owned C pointer from an isl C++ object which is
46 * usable in __isl_take methods. Verify that the original C++ object gave up
47 * its pointer and now is null.
49 void test_pointer(isl::ctx ctx
)
51 isl_set
*c_empty
= isl_set_read_from_str(ctx
.get(), "{ : false }");
52 isl::set empty
= isl::manage(c_empty
);
53 assert(empty
.is_empty());
54 assert(isl_set_is_empty(empty
.get()));
56 assert(!empty
.is_null());
57 isl_set_free(empty
.copy());
58 assert(!empty
.is_null());
59 isl_set_free(empty
.release());
60 assert(empty
.is_null());
63 /* Test that isl objects can be constructed.
66 * - construction of a null object
67 * - construction from a string
68 * - construction from an integer
69 * - static constructor without a parameter
70 * - conversion construction (implicit)
71 * - conversion construction (explicit)
73 * The tests to construct from integers and strings cover functionality that
74 * is also tested in the parameter type tests, but here we verify that
75 * multiple overloaded constructors are available and that overload resolution
78 * Construction from an isl C pointer is tested in test_pointer.
80 void test_constructors(isl::ctx ctx
)
83 assert(null
.is_null());
85 isl::val zero_from_str
= isl::val(ctx
, "0");
86 assert(zero_from_str
.is_zero());
88 isl::val zero_int_con
= isl::val(ctx
, 0);
89 assert(zero_int_con
.is_zero());
91 isl::val zero_static_con
= isl::val::zero(ctx
);
92 assert(zero_static_con
.is_zero());
94 isl::basic_set
bs(ctx
, "{ [1] }");
95 isl::set
result(ctx
, "{ [1] }");
97 assert(s
.is_equal(result
));
99 assert(s
.unite(s2
).is_equal(result
));
102 /* Test integer function parameters.
104 * Verify that extreme values and zero work.
106 void test_parameters_int(isl::ctx ctx
)
108 isl::val
long_max_str(ctx
, std::to_string(LONG_MAX
));
109 isl::val
long_max_int(ctx
, LONG_MAX
);
110 assert(long_max_str
.eq(long_max_int
));
112 isl::val
long_min_str(ctx
, std::to_string(LONG_MIN
));
113 isl::val
long_min_int(ctx
, LONG_MIN
);
114 assert(long_min_str
.eq(long_min_int
));
116 isl::val long_zero_str
= isl::val(ctx
, std::to_string(0));
117 isl::val long_zero_int
= isl::val(ctx
, 0);
118 assert(long_zero_str
.eq(long_zero_int
));
121 /* Test isl objects parameters.
123 * Verify that isl objects can be passed as lvalue and rvalue parameters.
124 * Also verify that isl object parameters are automatically type converted if
125 * there is an inheritance relation. Finally, test function calls without
126 * any additional parameters, apart from the isl object on which
127 * the method is called.
129 void test_parameters_obj(isl::ctx ctx
)
131 isl::set
a(ctx
, "{ [0] }");
132 isl::set
b(ctx
, "{ [1] }");
133 isl::set
c(ctx
, "{ [2] }");
134 isl::set
expected(ctx
, "{ [i] : 0 <= i <= 2 }");
136 isl::set tmp
= a
.unite(b
);
137 isl::set res_lvalue_param
= tmp
.unite(c
);
138 assert(res_lvalue_param
.is_equal(expected
));
140 isl::set res_rvalue_param
= a
.unite(b
).unite(c
);
141 assert(res_rvalue_param
.is_equal(expected
));
143 isl::basic_set
a2(ctx
, "{ [0] }");
144 assert(a
.is_equal(a2
));
146 isl::val
two(ctx
, 2);
147 isl::val
half(ctx
, "1/2");
148 isl::val res_only_this_param
= two
.inv();
149 assert(res_only_this_param
.eq(half
));
152 /* Test different kinds of parameters to be passed to functions.
154 * This includes integer and isl C++ object parameters.
156 void test_parameters(isl::ctx ctx
)
158 test_parameters_int(ctx
);
159 test_parameters_obj(ctx
);
162 /* Test that isl objects are returned correctly.
164 * This only tests that after combining two objects, the result is successfully
167 void test_return_obj(isl::ctx ctx
)
169 isl::val
one(ctx
, "1");
170 isl::val
two(ctx
, "2");
171 isl::val
three(ctx
, "3");
173 isl::val res
= one
.add(two
);
175 assert(res
.eq(three
));
178 /* Test that integer values are returned correctly.
180 void test_return_int(isl::ctx ctx
)
182 isl::val
one(ctx
, "1");
183 isl::val
neg_one(ctx
, "-1");
184 isl::val
zero(ctx
, "0");
186 assert(one
.sgn() > 0);
187 assert(neg_one
.sgn() < 0);
188 assert(zero
.sgn() == 0);
191 /* Test that isl_bool values are returned correctly.
193 * We check in detail the following parts of the isl::boolean class:
194 * - The is_true, is_false, and is_error functions return true in case they
195 * are called on a true, false, or error instance of isl::boolean,
197 * - Explicit conversion to 'bool'
198 * - Implicit conversion to 'bool'
199 * - The complement operator
200 * - Explicit construction from 'true' and 'false'
201 * - Explicit construction form isl_bool
203 void test_return_bool(isl::ctx ctx
)
205 isl::set
empty(ctx
, "{ : false }");
206 isl::set
univ(ctx
, "{ : }");
209 isl::boolean b_true
= empty
.is_empty();
210 isl::boolean b_false
= univ
.is_empty();
211 isl::boolean b_error
= null
.is_empty();
213 assert(b_true
.is_true());
214 assert(!b_true
.is_false());
215 assert(!b_true
.is_error());
217 assert(!b_false
.is_true());
218 assert(b_false
.is_false());
219 assert(!b_false
.is_error());
221 assert(!b_error
.is_true());
222 assert(!b_error
.is_false());
223 assert(b_error
.is_error());
225 assert(bool(b_true
) == true);
226 assert(bool(b_false
) == false);
230 assert((!b_false
).is_true());
231 assert((!b_true
).is_false());
232 assert((!b_error
).is_error());
234 assert(isl::boolean(true).is_true());
235 assert(!isl::boolean(true).is_false());
236 assert(!isl::boolean(true).is_error());
238 assert(isl::boolean(false).is_false());
239 assert(!isl::boolean(false).is_true());
240 assert(!isl::boolean(false).is_error());
242 assert(isl::manage(isl_bool_true
).is_true());
243 assert(!isl::manage(isl_bool_true
).is_false());
244 assert(!isl::manage(isl_bool_true
).is_error());
246 assert(isl::manage(isl_bool_false
).is_false());
247 assert(!isl::manage(isl_bool_false
).is_true());
248 assert(!isl::manage(isl_bool_false
).is_error());
250 assert(isl::manage(isl_bool_error
).is_error());
251 assert(!isl::manage(isl_bool_error
).is_true());
252 assert(!isl::manage(isl_bool_error
).is_false());
255 /* Test that strings are returned correctly.
256 * Do so by calling overloaded isl::ast_build::from_expr methods.
258 void test_return_string(isl::ctx ctx
)
260 isl::set
context(ctx
, "[n] -> { : }");
261 isl::ast_build build
= isl::ast_build::from_context(context
);
262 isl::pw_aff
pw_aff(ctx
, "[n] -> { [n] }");
263 isl::set
set(ctx
, "[n] -> { : n >= 0 }");
265 isl::ast_expr expr
= build
.expr_from(pw_aff
);
266 const char *expected_string
= "n";
267 assert(expected_string
== expr
.to_C_str());
269 expr
= build
.expr_from(set
);
270 expected_string
= "n >= 0";
271 assert(expected_string
== expr
.to_C_str());
274 /* Test that return values are handled correctly.
276 * Test that isl C++ objects, integers, boolean values, and strings are
277 * returned correctly.
279 void test_return(isl::ctx ctx
)
281 test_return_obj(ctx
);
282 test_return_int(ctx
);
283 test_return_bool(ctx
);
284 test_return_string(ctx
);
287 /* Test that foreach functions are modeled correctly.
289 * Verify that lambdas are correctly called as callback of a 'foreach'
290 * function and that variables captured by the lambda work correctly. Also
291 * check that the foreach function takes account of the return value of the
292 * lambda and aborts in case isl::stat::error is returned and then returns
293 * isl::stat::error itself.
295 void test_foreach(isl::ctx ctx
)
297 isl::set
s(ctx
, "{ [0]; [1]; [2] }");
299 std::vector
<isl::basic_set
> basic_sets
;
301 auto add_to_vector
= [&] (isl::basic_set bs
) {
302 basic_sets
.push_back(bs
);
303 return isl::stat::ok
;
306 isl::stat ret1
= s
.foreach_basic_set(add_to_vector
);
308 assert(ret1
== isl::stat::ok
);
309 assert(basic_sets
.size() == 3);
310 assert(isl::set(basic_sets
[0]).is_subset(s
));
311 assert(isl::set(basic_sets
[1]).is_subset(s
));
312 assert(isl::set(basic_sets
[2]).is_subset(s
));
313 assert(!basic_sets
[0].is_equal(basic_sets
[1]));
315 auto fail
= [&] (isl::basic_set bs
) {
316 return isl::stat::error
;
319 isl::stat ret2
= s
.foreach_basic_set(fail
);
321 assert(ret2
== isl::stat::error
);
324 /* Test the isl C++ interface
327 * - The isl C <-> C++ pointer interface
328 * - Object construction
329 * - Different parameter types
330 * - Different return types
331 * - Foreach functions
335 isl_ctx
*ctx
= isl_ctx_alloc();
337 isl_options_set_on_error(ctx
, ISL_ON_ERROR_ABORT
);
340 test_constructors(ctx
);
341 test_parameters(ctx
);