1use super::{Aff, ConstraintList, Context, DimType, Error, LibISLError, LocalSpace, Space, Val};
5use libc::uintptr_t;
6use std::ffi::CStr;
7use std::os::raw::c_char;
8
9pub struct Constraint {
11 pub ptr: uintptr_t,
12 pub should_free_on_drop: bool,
13}
14
15extern "C" {
16
17 fn isl_constraint_alloc_equality(ls: uintptr_t) -> uintptr_t;
18
19 fn isl_constraint_alloc_inequality(ls: uintptr_t) -> uintptr_t;
20
21 fn isl_constraint_cmp_last_non_zero(c1: uintptr_t, c2: uintptr_t) -> i32;
22
23 fn isl_constraint_copy(c: uintptr_t) -> uintptr_t;
24
25 fn isl_constraint_dim(constraint: uintptr_t, type_: i32) -> i32;
26
27 fn isl_constraint_dump(c: uintptr_t) -> ();
28
29 fn isl_constraint_free(c: uintptr_t) -> uintptr_t;
30
31 fn isl_constraint_get_aff(constraint: uintptr_t) -> uintptr_t;
32
33 fn isl_constraint_get_bound(constraint: uintptr_t, type_: i32, pos: i32) -> uintptr_t;
34
35 fn isl_constraint_get_coefficient_val(constraint: uintptr_t, type_: i32, pos: i32)
36 -> uintptr_t;
37
38 fn isl_constraint_get_constant_val(constraint: uintptr_t) -> uintptr_t;
39
40 fn isl_constraint_get_ctx(c: uintptr_t) -> uintptr_t;
41
42 fn isl_constraint_get_dim_name(constraint: uintptr_t, type_: i32, pos: u32) -> *const c_char;
43
44 fn isl_constraint_get_div(constraint: uintptr_t, pos: i32) -> uintptr_t;
45
46 fn isl_constraint_get_local_space(constraint: uintptr_t) -> uintptr_t;
47
48 fn isl_constraint_get_space(constraint: uintptr_t) -> uintptr_t;
49
50 fn isl_constraint_involves_dims(constraint: uintptr_t, type_: i32, first: u32, n: u32) -> i32;
51
52 fn isl_constraint_is_div_constraint(constraint: uintptr_t) -> i32;
53
54 fn isl_constraint_is_equal(constraint1: uintptr_t, constraint2: uintptr_t) -> i32;
55
56 fn isl_constraint_is_equality(constraint: uintptr_t) -> i32;
57
58 fn isl_constraint_is_lower_bound(constraint: uintptr_t, type_: i32, pos: u32) -> i32;
59
60 fn isl_constraint_is_upper_bound(constraint: uintptr_t, type_: i32, pos: u32) -> i32;
61
62 fn isl_constraint_negate(constraint: uintptr_t) -> uintptr_t;
63
64 fn isl_constraint_plain_cmp(c1: uintptr_t, c2: uintptr_t) -> i32;
65
66 fn isl_constraint_set_coefficient_si(constraint: uintptr_t, type_: i32, pos: i32, v: i32)
67 -> uintptr_t;
68
69 fn isl_constraint_set_coefficient_val(constraint: uintptr_t, type_: i32, pos: i32,
70 v: uintptr_t)
71 -> uintptr_t;
72
73 fn isl_constraint_set_constant_si(constraint: uintptr_t, v: i32) -> uintptr_t;
74
75 fn isl_constraint_set_constant_val(constraint: uintptr_t, v: uintptr_t) -> uintptr_t;
76
77 fn isl_constraint_to_list(el: uintptr_t) -> uintptr_t;
78
79}
80
81impl Constraint {
82 pub fn alloc_equality(ls: LocalSpace) -> Result<Constraint, LibISLError> {
84 let isl_rs_ctx = ls.get_ctx();
85 let mut ls = ls;
86 ls.do_not_free_on_drop();
87 let ls = ls.ptr;
88 let isl_rs_result = unsafe { isl_constraint_alloc_equality(ls) };
89 let isl_rs_result = Constraint { ptr: isl_rs_result,
90 should_free_on_drop: true };
91 let err = isl_rs_ctx.last_error();
92 if err != Error::None_ {
93 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
94 }
95 Ok(isl_rs_result)
96 }
97
98 pub fn alloc_inequality(ls: LocalSpace) -> Result<Constraint, LibISLError> {
100 let isl_rs_ctx = ls.get_ctx();
101 let mut ls = ls;
102 ls.do_not_free_on_drop();
103 let ls = ls.ptr;
104 let isl_rs_result = unsafe { isl_constraint_alloc_inequality(ls) };
105 let isl_rs_result = Constraint { ptr: isl_rs_result,
106 should_free_on_drop: true };
107 let err = isl_rs_ctx.last_error();
108 if err != Error::None_ {
109 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
110 }
111 Ok(isl_rs_result)
112 }
113
114 pub fn cmp_last_non_zero(&self, c2: &Constraint) -> Result<i32, LibISLError> {
116 let c1 = self;
117 let isl_rs_ctx = c1.get_ctx();
118 let c1 = c1.ptr;
119 let c2 = c2.ptr;
120 let isl_rs_result = unsafe { isl_constraint_cmp_last_non_zero(c1, c2) };
121 let err = isl_rs_ctx.last_error();
122 if err != Error::None_ {
123 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
124 }
125 Ok(isl_rs_result)
126 }
127
128 pub fn copy(&self) -> Result<Constraint, LibISLError> {
130 let c = self;
131 let isl_rs_ctx = c.get_ctx();
132 let c = c.ptr;
133 let isl_rs_result = unsafe { isl_constraint_copy(c) };
134 let isl_rs_result = Constraint { ptr: isl_rs_result,
135 should_free_on_drop: true };
136 let err = isl_rs_ctx.last_error();
137 if err != Error::None_ {
138 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
139 }
140 Ok(isl_rs_result)
141 }
142
143 pub fn dim(&self, type_: DimType) -> Result<i32, LibISLError> {
145 let constraint = self;
146 let isl_rs_ctx = constraint.get_ctx();
147 let constraint = constraint.ptr;
148 let type_ = type_.to_i32();
149 let isl_rs_result = unsafe { isl_constraint_dim(constraint, type_) };
150 let err = isl_rs_ctx.last_error();
151 if err != Error::None_ {
152 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
153 }
154 Ok(isl_rs_result)
155 }
156
157 pub fn dump(&self) -> Result<(), LibISLError> {
159 let c = self;
160 let isl_rs_ctx = c.get_ctx();
161 let c = c.ptr;
162 let isl_rs_result = unsafe { isl_constraint_dump(c) };
163 let err = isl_rs_ctx.last_error();
164 if err != Error::None_ {
165 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
166 }
167 Ok(isl_rs_result)
168 }
169
170 pub fn free(self) -> Result<Constraint, LibISLError> {
172 let c = self;
173 let isl_rs_ctx = c.get_ctx();
174 let mut c = c;
175 c.do_not_free_on_drop();
176 let c = c.ptr;
177 let isl_rs_result = unsafe { isl_constraint_free(c) };
178 let isl_rs_result = Constraint { ptr: isl_rs_result,
179 should_free_on_drop: true };
180 let err = isl_rs_ctx.last_error();
181 if err != Error::None_ {
182 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
183 }
184 Ok(isl_rs_result)
185 }
186
187 pub fn get_aff(&self) -> Result<Aff, LibISLError> {
189 let constraint = self;
190 let isl_rs_ctx = constraint.get_ctx();
191 let constraint = constraint.ptr;
192 let isl_rs_result = unsafe { isl_constraint_get_aff(constraint) };
193 let isl_rs_result = Aff { ptr: isl_rs_result,
194 should_free_on_drop: true };
195 let err = isl_rs_ctx.last_error();
196 if err != Error::None_ {
197 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
198 }
199 Ok(isl_rs_result)
200 }
201
202 pub fn get_bound(&self, type_: DimType, pos: i32) -> Result<Aff, LibISLError> {
204 let constraint = self;
205 let isl_rs_ctx = constraint.get_ctx();
206 let constraint = constraint.ptr;
207 let type_ = type_.to_i32();
208 let isl_rs_result = unsafe { isl_constraint_get_bound(constraint, type_, pos) };
209 let isl_rs_result = Aff { ptr: isl_rs_result,
210 should_free_on_drop: true };
211 let err = isl_rs_ctx.last_error();
212 if err != Error::None_ {
213 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
214 }
215 Ok(isl_rs_result)
216 }
217
218 pub fn get_coefficient_val(&self, type_: DimType, pos: i32) -> Result<Val, LibISLError> {
220 let constraint = self;
221 let isl_rs_ctx = constraint.get_ctx();
222 let constraint = constraint.ptr;
223 let type_ = type_.to_i32();
224 let isl_rs_result = unsafe { isl_constraint_get_coefficient_val(constraint, type_, pos) };
225 let isl_rs_result = Val { ptr: isl_rs_result,
226 should_free_on_drop: true };
227 let err = isl_rs_ctx.last_error();
228 if err != Error::None_ {
229 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
230 }
231 Ok(isl_rs_result)
232 }
233
234 pub fn get_constant_val(&self) -> Result<Val, LibISLError> {
236 let constraint = self;
237 let isl_rs_ctx = constraint.get_ctx();
238 let constraint = constraint.ptr;
239 let isl_rs_result = unsafe { isl_constraint_get_constant_val(constraint) };
240 let isl_rs_result = Val { ptr: isl_rs_result,
241 should_free_on_drop: true };
242 let err = isl_rs_ctx.last_error();
243 if err != Error::None_ {
244 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
245 }
246 Ok(isl_rs_result)
247 }
248
249 pub fn get_ctx(&self) -> Context {
251 let c = self;
252 let c = c.ptr;
253 let isl_rs_result = unsafe { isl_constraint_get_ctx(c) };
254 let isl_rs_result = Context { ptr: isl_rs_result,
255 should_free_on_drop: false };
256 isl_rs_result
257 }
258
259 pub fn get_dim_name(&self, type_: DimType, pos: u32) -> Result<&str, LibISLError> {
261 let constraint = self;
262 let isl_rs_ctx = constraint.get_ctx();
263 let constraint = constraint.ptr;
264 let type_ = type_.to_i32();
265 let isl_rs_result = unsafe { isl_constraint_get_dim_name(constraint, type_, pos) };
266 let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
267 let isl_rs_result = isl_rs_result.to_str().unwrap();
268 let err = isl_rs_ctx.last_error();
269 if err != Error::None_ {
270 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
271 }
272 Ok(isl_rs_result)
273 }
274
275 pub fn get_div(&self, pos: i32) -> Result<Aff, LibISLError> {
277 let constraint = self;
278 let isl_rs_ctx = constraint.get_ctx();
279 let constraint = constraint.ptr;
280 let isl_rs_result = unsafe { isl_constraint_get_div(constraint, pos) };
281 let isl_rs_result = Aff { ptr: isl_rs_result,
282 should_free_on_drop: true };
283 let err = isl_rs_ctx.last_error();
284 if err != Error::None_ {
285 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
286 }
287 Ok(isl_rs_result)
288 }
289
290 pub fn get_local_space(&self) -> Result<LocalSpace, LibISLError> {
292 let constraint = self;
293 let isl_rs_ctx = constraint.get_ctx();
294 let constraint = constraint.ptr;
295 let isl_rs_result = unsafe { isl_constraint_get_local_space(constraint) };
296 let isl_rs_result = LocalSpace { ptr: isl_rs_result,
297 should_free_on_drop: true };
298 let err = isl_rs_ctx.last_error();
299 if err != Error::None_ {
300 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
301 }
302 Ok(isl_rs_result)
303 }
304
305 pub fn get_space(&self) -> Result<Space, LibISLError> {
307 let constraint = self;
308 let isl_rs_ctx = constraint.get_ctx();
309 let constraint = constraint.ptr;
310 let isl_rs_result = unsafe { isl_constraint_get_space(constraint) };
311 let isl_rs_result = Space { ptr: isl_rs_result,
312 should_free_on_drop: true };
313 let err = isl_rs_ctx.last_error();
314 if err != Error::None_ {
315 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
316 }
317 Ok(isl_rs_result)
318 }
319
320 pub fn involves_dims(&self, type_: DimType, first: u32, n: u32) -> Result<bool, LibISLError> {
322 let constraint = self;
323 let isl_rs_ctx = constraint.get_ctx();
324 let constraint = constraint.ptr;
325 let type_ = type_.to_i32();
326 let isl_rs_result = unsafe { isl_constraint_involves_dims(constraint, type_, first, n) };
327 let isl_rs_result = match isl_rs_result {
328 0 => false,
329 1 => true,
330 _ => panic!("Got isl_bool = -1"),
331 };
332 let err = isl_rs_ctx.last_error();
333 if err != Error::None_ {
334 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
335 }
336 Ok(isl_rs_result)
337 }
338
339 pub fn is_div_constraint(&self) -> Result<bool, LibISLError> {
341 let constraint = self;
342 let isl_rs_ctx = constraint.get_ctx();
343 let constraint = constraint.ptr;
344 let isl_rs_result = unsafe { isl_constraint_is_div_constraint(constraint) };
345 let isl_rs_result = match isl_rs_result {
346 0 => false,
347 1 => true,
348 _ => panic!("Got isl_bool = -1"),
349 };
350 let err = isl_rs_ctx.last_error();
351 if err != Error::None_ {
352 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
353 }
354 Ok(isl_rs_result)
355 }
356
357 pub fn is_equal(&self, constraint2: &Constraint) -> Result<i32, LibISLError> {
359 let constraint1 = self;
360 let isl_rs_ctx = constraint1.get_ctx();
361 let constraint1 = constraint1.ptr;
362 let constraint2 = constraint2.ptr;
363 let isl_rs_result = unsafe { isl_constraint_is_equal(constraint1, constraint2) };
364 let err = isl_rs_ctx.last_error();
365 if err != Error::None_ {
366 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
367 }
368 Ok(isl_rs_result)
369 }
370
371 pub fn is_equality(&self) -> Result<bool, LibISLError> {
373 let constraint = self;
374 let isl_rs_ctx = constraint.get_ctx();
375 let constraint = constraint.ptr;
376 let isl_rs_result = unsafe { isl_constraint_is_equality(constraint) };
377 let isl_rs_result = match isl_rs_result {
378 0 => false,
379 1 => true,
380 _ => panic!("Got isl_bool = -1"),
381 };
382 let err = isl_rs_ctx.last_error();
383 if err != Error::None_ {
384 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
385 }
386 Ok(isl_rs_result)
387 }
388
389 pub fn is_lower_bound(&self, type_: DimType, pos: u32) -> Result<bool, LibISLError> {
391 let constraint = self;
392 let isl_rs_ctx = constraint.get_ctx();
393 let constraint = constraint.ptr;
394 let type_ = type_.to_i32();
395 let isl_rs_result = unsafe { isl_constraint_is_lower_bound(constraint, type_, pos) };
396 let isl_rs_result = match isl_rs_result {
397 0 => false,
398 1 => true,
399 _ => panic!("Got isl_bool = -1"),
400 };
401 let err = isl_rs_ctx.last_error();
402 if err != Error::None_ {
403 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
404 }
405 Ok(isl_rs_result)
406 }
407
408 pub fn is_upper_bound(&self, type_: DimType, pos: u32) -> Result<bool, LibISLError> {
410 let constraint = self;
411 let isl_rs_ctx = constraint.get_ctx();
412 let constraint = constraint.ptr;
413 let type_ = type_.to_i32();
414 let isl_rs_result = unsafe { isl_constraint_is_upper_bound(constraint, type_, pos) };
415 let isl_rs_result = match isl_rs_result {
416 0 => false,
417 1 => true,
418 _ => panic!("Got isl_bool = -1"),
419 };
420 let err = isl_rs_ctx.last_error();
421 if err != Error::None_ {
422 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
423 }
424 Ok(isl_rs_result)
425 }
426
427 pub fn negate(self) -> Result<Constraint, LibISLError> {
429 let constraint = self;
430 let isl_rs_ctx = constraint.get_ctx();
431 let mut constraint = constraint;
432 constraint.do_not_free_on_drop();
433 let constraint = constraint.ptr;
434 let isl_rs_result = unsafe { isl_constraint_negate(constraint) };
435 let isl_rs_result = Constraint { ptr: isl_rs_result,
436 should_free_on_drop: true };
437 let err = isl_rs_ctx.last_error();
438 if err != Error::None_ {
439 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
440 }
441 Ok(isl_rs_result)
442 }
443
444 pub fn plain_cmp(&self, c2: &Constraint) -> Result<i32, LibISLError> {
446 let c1 = self;
447 let isl_rs_ctx = c1.get_ctx();
448 let c1 = c1.ptr;
449 let c2 = c2.ptr;
450 let isl_rs_result = unsafe { isl_constraint_plain_cmp(c1, c2) };
451 let err = isl_rs_ctx.last_error();
452 if err != Error::None_ {
453 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
454 }
455 Ok(isl_rs_result)
456 }
457
458 pub fn set_coefficient_si(self, type_: DimType, pos: i32, v: i32)
460 -> Result<Constraint, LibISLError> {
461 let constraint = self;
462 let isl_rs_ctx = constraint.get_ctx();
463 let mut constraint = constraint;
464 constraint.do_not_free_on_drop();
465 let constraint = constraint.ptr;
466 let type_ = type_.to_i32();
467 let isl_rs_result = unsafe { isl_constraint_set_coefficient_si(constraint, type_, pos, v) };
468 let isl_rs_result = Constraint { ptr: isl_rs_result,
469 should_free_on_drop: true };
470 let err = isl_rs_ctx.last_error();
471 if err != Error::None_ {
472 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
473 }
474 Ok(isl_rs_result)
475 }
476
477 pub fn set_coefficient_val(self, type_: DimType, pos: i32, v: Val)
479 -> Result<Constraint, LibISLError> {
480 let constraint = self;
481 let isl_rs_ctx = constraint.get_ctx();
482 let mut constraint = constraint;
483 constraint.do_not_free_on_drop();
484 let constraint = constraint.ptr;
485 let type_ = type_.to_i32();
486 let mut v = v;
487 v.do_not_free_on_drop();
488 let v = v.ptr;
489 let isl_rs_result =
490 unsafe { isl_constraint_set_coefficient_val(constraint, type_, pos, v) };
491 let isl_rs_result = Constraint { ptr: isl_rs_result,
492 should_free_on_drop: true };
493 let err = isl_rs_ctx.last_error();
494 if err != Error::None_ {
495 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
496 }
497 Ok(isl_rs_result)
498 }
499
500 pub fn set_constant_si(self, v: i32) -> Result<Constraint, LibISLError> {
502 let constraint = self;
503 let isl_rs_ctx = constraint.get_ctx();
504 let mut constraint = constraint;
505 constraint.do_not_free_on_drop();
506 let constraint = constraint.ptr;
507 let isl_rs_result = unsafe { isl_constraint_set_constant_si(constraint, v) };
508 let isl_rs_result = Constraint { ptr: isl_rs_result,
509 should_free_on_drop: true };
510 let err = isl_rs_ctx.last_error();
511 if err != Error::None_ {
512 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
513 }
514 Ok(isl_rs_result)
515 }
516
517 pub fn set_constant_val(self, v: Val) -> Result<Constraint, LibISLError> {
519 let constraint = self;
520 let isl_rs_ctx = constraint.get_ctx();
521 let mut constraint = constraint;
522 constraint.do_not_free_on_drop();
523 let constraint = constraint.ptr;
524 let mut v = v;
525 v.do_not_free_on_drop();
526 let v = v.ptr;
527 let isl_rs_result = unsafe { isl_constraint_set_constant_val(constraint, v) };
528 let isl_rs_result = Constraint { ptr: isl_rs_result,
529 should_free_on_drop: true };
530 let err = isl_rs_ctx.last_error();
531 if err != Error::None_ {
532 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
533 }
534 Ok(isl_rs_result)
535 }
536
537 pub fn to_list(self) -> Result<ConstraintList, LibISLError> {
539 let el = self;
540 let isl_rs_ctx = el.get_ctx();
541 let mut el = el;
542 el.do_not_free_on_drop();
543 let el = el.ptr;
544 let isl_rs_result = unsafe { isl_constraint_to_list(el) };
545 let isl_rs_result = ConstraintList { ptr: isl_rs_result,
546 should_free_on_drop: true };
547 let err = isl_rs_ctx.last_error();
548 if err != Error::None_ {
549 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
550 }
551 Ok(isl_rs_result)
552 }
553
554 pub fn do_not_free_on_drop(&mut self) {
557 self.should_free_on_drop = false;
558 }
559}
560
561impl Drop for Constraint {
562 fn drop(&mut self) {
563 if self.should_free_on_drop {
564 unsafe {
565 isl_constraint_free(self.ptr);
566 }
567 }
568 }
569}