cpp: add missing license to unit tests
[isl.git] / interface / isl_test_cpp.cpp
bloba6b1e631adb836b920ab63d01b293e7100d5409b
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-noexceptions.h>
16 static void assert_impl(bool condition, const char *file, int line,
17 const char *message)
19 if (condition)
20 return;
22 fprintf(stderr, "Assertion failed in %s:%d %s\n", file, line, message);
23 exit(EXIT_FAILURE);
26 static void assert_impl(isl::boolean condition, const char *file, int line,
27 const char *message)
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.
36 * This tests:
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
40 * methods
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
43 * pointer.
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.
64 * This tests:
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
75 * works as expected.
77 * Construction from an isl C pointer is tested in test_pointer.
79 void test_constructors(isl::ctx ctx)
81 isl::val null;
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] }");
95 isl::set s = bs;
96 assert(s.is_equal(result));
97 isl::set s2(bs);
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
164 * returned.
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,
195 * respectively
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, "{ : }");
206 isl::set null;
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);
227 assert(b_true);
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
319 * This includes:
320 * - The isl C <-> C++ pointer interface
321 * - Object construction
322 * - Different parameter types
323 * - Different return types
324 * - Foreach functions
326 int main()
328 isl_ctx *ctx = isl_ctx_alloc();
330 test_pointer(ctx);
331 test_constructors(ctx);
332 test_parameters(ctx);
333 test_return(ctx);
334 test_foreach(ctx);
336 isl_ctx_free(ctx);