interface/isl_test_cpp-noexceptions: abort on isl error
[isl.git] / interface / isl_test_cpp-noexceptions.cc
blobd468b17307308ecdf9be48b9071339fc77403840
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
6 */
8 #include <vector>
9 #include <string>
10 #include <limits.h>
11 #include <stdio.h>
12 #include <stdlib.h>
14 #include <isl/options.h>
15 #include <isl-noexceptions.h>
17 static void assert_impl(bool condition, const char *file, int line,
18 const char *message)
20 if (condition)
21 return;
23 fprintf(stderr, "Assertion failed in %s:%d %s\n", file, line, message);
24 exit(EXIT_FAILURE);
27 static void assert_impl(isl::boolean condition, const char *file, int line,
28 const char *message)
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.
37 * This tests:
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
41 * methods
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
44 * pointer.
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.
65 * This tests:
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
76 * works as expected.
78 * Construction from an isl C pointer is tested in test_pointer.
80 void test_constructors(isl::ctx ctx)
82 isl::val null;
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] }");
96 isl::set s = bs;
97 assert(s.is_equal(result));
98 isl::set s2(bs);
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
165 * returned.
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,
196 * respectively
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, "{ : }");
207 isl::set null;
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);
228 assert(b_true);
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
326 * This includes:
327 * - The isl C <-> C++ pointer interface
328 * - Object construction
329 * - Different parameter types
330 * - Different return types
331 * - Foreach functions
333 int main()
335 isl_ctx *ctx = isl_ctx_alloc();
337 isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
339 test_pointer(ctx);
340 test_constructors(ctx);
341 test_parameters(ctx);
342 test_return(ctx);
343 test_foreach(ctx);
345 isl_ctx_free(ctx);