1use super::{Context, Error, Id, IdList, LibISLError, Space};
5use libc::uintptr_t;
6use std::ffi::{CStr, CString};
7use std::os::raw::c_char;
8
9pub struct MultiId {
11 pub ptr: uintptr_t,
12 pub should_free_on_drop: bool,
13}
14
15extern "C" {
16
17 fn isl_multi_id_align_params(multi: uintptr_t, model: uintptr_t) -> uintptr_t;
18
19 fn isl_multi_id_copy(multi: uintptr_t) -> uintptr_t;
20
21 fn isl_multi_id_dump(mi: uintptr_t) -> ();
22
23 fn isl_multi_id_factor_range(multi: uintptr_t) -> uintptr_t;
24
25 fn isl_multi_id_flat_range_product(multi1: uintptr_t, multi2: uintptr_t) -> uintptr_t;
26
27 fn isl_multi_id_flatten_range(multi: uintptr_t) -> uintptr_t;
28
29 fn isl_multi_id_free(multi: uintptr_t) -> uintptr_t;
30
31 fn isl_multi_id_from_id_list(space: uintptr_t, list: uintptr_t) -> uintptr_t;
32
33 fn isl_multi_id_from_range(multi: uintptr_t) -> uintptr_t;
34
35 fn isl_multi_id_get_at(multi: uintptr_t, pos: i32) -> uintptr_t;
36
37 fn isl_multi_id_get_ctx(multi: uintptr_t) -> uintptr_t;
38
39 fn isl_multi_id_get_domain_space(multi: uintptr_t) -> uintptr_t;
40
41 fn isl_multi_id_get_id(multi: uintptr_t, pos: i32) -> uintptr_t;
42
43 fn isl_multi_id_get_list(multi: uintptr_t) -> uintptr_t;
44
45 fn isl_multi_id_get_space(multi: uintptr_t) -> uintptr_t;
46
47 fn isl_multi_id_plain_is_equal(multi1: uintptr_t, multi2: uintptr_t) -> i32;
48
49 fn isl_multi_id_range_factor_domain(multi: uintptr_t) -> uintptr_t;
50
51 fn isl_multi_id_range_factor_range(multi: uintptr_t) -> uintptr_t;
52
53 fn isl_multi_id_range_is_wrapping(multi: uintptr_t) -> i32;
54
55 fn isl_multi_id_range_product(multi1: uintptr_t, multi2: uintptr_t) -> uintptr_t;
56
57 fn isl_multi_id_range_splice(multi1: uintptr_t, pos: u32, multi2: uintptr_t) -> uintptr_t;
58
59 fn isl_multi_id_read_from_str(ctx: uintptr_t, str_: *const c_char) -> uintptr_t;
60
61 fn isl_multi_id_reset_user(multi: uintptr_t) -> uintptr_t;
62
63 fn isl_multi_id_set_at(multi: uintptr_t, pos: i32, el: uintptr_t) -> uintptr_t;
64
65 fn isl_multi_id_set_id(multi: uintptr_t, pos: i32, el: uintptr_t) -> uintptr_t;
66
67 fn isl_multi_id_size(multi: uintptr_t) -> i32;
68
69 fn isl_multi_id_to_str(mi: uintptr_t) -> *const c_char;
70
71}
72
73impl MultiId {
74 pub fn align_params(self, model: Space) -> Result<MultiId, LibISLError> {
76 let multi = self;
77 let isl_rs_ctx = multi.get_ctx();
78 let mut multi = multi;
79 multi.do_not_free_on_drop();
80 let multi = multi.ptr;
81 let mut model = model;
82 model.do_not_free_on_drop();
83 let model = model.ptr;
84 let isl_rs_result = unsafe { isl_multi_id_align_params(multi, model) };
85 let isl_rs_result = MultiId { ptr: isl_rs_result,
86 should_free_on_drop: true };
87 let err = isl_rs_ctx.last_error();
88 if err != Error::None_ {
89 let err_msg = isl_rs_ctx.last_error_msg();
90 isl_rs_ctx.reset_error();
91 return Err(LibISLError::new(err, err_msg));
92 }
93 Ok(isl_rs_result)
94 }
95
96 pub fn copy(&self) -> Result<MultiId, LibISLError> {
98 let multi = self;
99 let isl_rs_ctx = multi.get_ctx();
100 let multi = multi.ptr;
101 let isl_rs_result = unsafe { isl_multi_id_copy(multi) };
102 let isl_rs_result = MultiId { ptr: isl_rs_result,
103 should_free_on_drop: true };
104 let err = isl_rs_ctx.last_error();
105 if err != Error::None_ {
106 let err_msg = isl_rs_ctx.last_error_msg();
107 isl_rs_ctx.reset_error();
108 return Err(LibISLError::new(err, err_msg));
109 }
110 Ok(isl_rs_result)
111 }
112
113 pub fn dump(&self) -> Result<(), LibISLError> {
115 let mi = self;
116 let isl_rs_ctx = mi.get_ctx();
117 let mi = mi.ptr;
118 let isl_rs_result = unsafe { isl_multi_id_dump(mi) };
119 let err = isl_rs_ctx.last_error();
120 if err != Error::None_ {
121 let err_msg = isl_rs_ctx.last_error_msg();
122 isl_rs_ctx.reset_error();
123 return Err(LibISLError::new(err, err_msg));
124 }
125 Ok(isl_rs_result)
126 }
127
128 pub fn factor_range(self) -> Result<MultiId, LibISLError> {
130 let multi = self;
131 let isl_rs_ctx = multi.get_ctx();
132 let mut multi = multi;
133 multi.do_not_free_on_drop();
134 let multi = multi.ptr;
135 let isl_rs_result = unsafe { isl_multi_id_factor_range(multi) };
136 let isl_rs_result = MultiId { ptr: isl_rs_result,
137 should_free_on_drop: true };
138 let err = isl_rs_ctx.last_error();
139 if err != Error::None_ {
140 let err_msg = isl_rs_ctx.last_error_msg();
141 isl_rs_ctx.reset_error();
142 return Err(LibISLError::new(err, err_msg));
143 }
144 Ok(isl_rs_result)
145 }
146
147 pub fn flat_range_product(self, multi2: MultiId) -> Result<MultiId, LibISLError> {
149 let multi1 = self;
150 let isl_rs_ctx = multi1.get_ctx();
151 let mut multi1 = multi1;
152 multi1.do_not_free_on_drop();
153 let multi1 = multi1.ptr;
154 let mut multi2 = multi2;
155 multi2.do_not_free_on_drop();
156 let multi2 = multi2.ptr;
157 let isl_rs_result = unsafe { isl_multi_id_flat_range_product(multi1, multi2) };
158 let isl_rs_result = MultiId { ptr: isl_rs_result,
159 should_free_on_drop: true };
160 let err = isl_rs_ctx.last_error();
161 if err != Error::None_ {
162 let err_msg = isl_rs_ctx.last_error_msg();
163 isl_rs_ctx.reset_error();
164 return Err(LibISLError::new(err, err_msg));
165 }
166 Ok(isl_rs_result)
167 }
168
169 pub fn flatten_range(self) -> Result<MultiId, LibISLError> {
171 let multi = self;
172 let isl_rs_ctx = multi.get_ctx();
173 let mut multi = multi;
174 multi.do_not_free_on_drop();
175 let multi = multi.ptr;
176 let isl_rs_result = unsafe { isl_multi_id_flatten_range(multi) };
177 let isl_rs_result = MultiId { ptr: isl_rs_result,
178 should_free_on_drop: true };
179 let err = isl_rs_ctx.last_error();
180 if err != Error::None_ {
181 let err_msg = isl_rs_ctx.last_error_msg();
182 isl_rs_ctx.reset_error();
183 return Err(LibISLError::new(err, err_msg));
184 }
185 Ok(isl_rs_result)
186 }
187
188 pub fn free(self) -> Result<MultiId, LibISLError> {
190 let multi = self;
191 let isl_rs_ctx = multi.get_ctx();
192 let mut multi = multi;
193 multi.do_not_free_on_drop();
194 let multi = multi.ptr;
195 let isl_rs_result = unsafe { isl_multi_id_free(multi) };
196 let isl_rs_result = MultiId { ptr: isl_rs_result,
197 should_free_on_drop: true };
198 let err = isl_rs_ctx.last_error();
199 if err != Error::None_ {
200 let err_msg = isl_rs_ctx.last_error_msg();
201 isl_rs_ctx.reset_error();
202 return Err(LibISLError::new(err, err_msg));
203 }
204 Ok(isl_rs_result)
205 }
206
207 pub fn from_id_list(space: Space, list: IdList) -> Result<MultiId, LibISLError> {
209 let isl_rs_ctx = space.get_ctx();
210 let mut space = space;
211 space.do_not_free_on_drop();
212 let space = space.ptr;
213 let mut list = list;
214 list.do_not_free_on_drop();
215 let list = list.ptr;
216 let isl_rs_result = unsafe { isl_multi_id_from_id_list(space, list) };
217 let isl_rs_result = MultiId { ptr: isl_rs_result,
218 should_free_on_drop: true };
219 let err = isl_rs_ctx.last_error();
220 if err != Error::None_ {
221 let err_msg = isl_rs_ctx.last_error_msg();
222 isl_rs_ctx.reset_error();
223 return Err(LibISLError::new(err, err_msg));
224 }
225 Ok(isl_rs_result)
226 }
227
228 pub fn from_range(self) -> Result<MultiId, LibISLError> {
230 let multi = self;
231 let isl_rs_ctx = multi.get_ctx();
232 let mut multi = multi;
233 multi.do_not_free_on_drop();
234 let multi = multi.ptr;
235 let isl_rs_result = unsafe { isl_multi_id_from_range(multi) };
236 let isl_rs_result = MultiId { ptr: isl_rs_result,
237 should_free_on_drop: true };
238 let err = isl_rs_ctx.last_error();
239 if err != Error::None_ {
240 let err_msg = isl_rs_ctx.last_error_msg();
241 isl_rs_ctx.reset_error();
242 return Err(LibISLError::new(err, err_msg));
243 }
244 Ok(isl_rs_result)
245 }
246
247 pub fn get_at(&self, pos: i32) -> Result<Id, LibISLError> {
249 let multi = self;
250 let isl_rs_ctx = multi.get_ctx();
251 let multi = multi.ptr;
252 let isl_rs_result = unsafe { isl_multi_id_get_at(multi, pos) };
253 let isl_rs_result = Id { ptr: isl_rs_result,
254 should_free_on_drop: true };
255 let err = isl_rs_ctx.last_error();
256 if err != Error::None_ {
257 let err_msg = isl_rs_ctx.last_error_msg();
258 isl_rs_ctx.reset_error();
259 return Err(LibISLError::new(err, err_msg));
260 }
261 Ok(isl_rs_result)
262 }
263
264 pub fn get_ctx(&self) -> Context {
266 let multi = self;
267 let multi = multi.ptr;
268 let isl_rs_result = unsafe { isl_multi_id_get_ctx(multi) };
269 let isl_rs_result = Context { ptr: isl_rs_result,
270 should_free_on_drop: false };
271 isl_rs_result
272 }
273
274 pub fn get_domain_space(&self) -> Result<Space, LibISLError> {
276 let multi = self;
277 let isl_rs_ctx = multi.get_ctx();
278 let multi = multi.ptr;
279 let isl_rs_result = unsafe { isl_multi_id_get_domain_space(multi) };
280 let isl_rs_result = Space { ptr: isl_rs_result,
281 should_free_on_drop: true };
282 let err = isl_rs_ctx.last_error();
283 if err != Error::None_ {
284 let err_msg = isl_rs_ctx.last_error_msg();
285 isl_rs_ctx.reset_error();
286 return Err(LibISLError::new(err, err_msg));
287 }
288 Ok(isl_rs_result)
289 }
290
291 pub fn get_id(&self, pos: i32) -> Result<Id, LibISLError> {
293 let multi = self;
294 let isl_rs_ctx = multi.get_ctx();
295 let multi = multi.ptr;
296 let isl_rs_result = unsafe { isl_multi_id_get_id(multi, pos) };
297 let isl_rs_result = Id { ptr: isl_rs_result,
298 should_free_on_drop: true };
299 let err = isl_rs_ctx.last_error();
300 if err != Error::None_ {
301 let err_msg = isl_rs_ctx.last_error_msg();
302 isl_rs_ctx.reset_error();
303 return Err(LibISLError::new(err, err_msg));
304 }
305 Ok(isl_rs_result)
306 }
307
308 pub fn get_list(&self) -> Result<IdList, LibISLError> {
310 let multi = self;
311 let isl_rs_ctx = multi.get_ctx();
312 let multi = multi.ptr;
313 let isl_rs_result = unsafe { isl_multi_id_get_list(multi) };
314 let isl_rs_result = IdList { ptr: isl_rs_result,
315 should_free_on_drop: true };
316 let err = isl_rs_ctx.last_error();
317 if err != Error::None_ {
318 let err_msg = isl_rs_ctx.last_error_msg();
319 isl_rs_ctx.reset_error();
320 return Err(LibISLError::new(err, err_msg));
321 }
322 Ok(isl_rs_result)
323 }
324
325 pub fn get_space(&self) -> Result<Space, LibISLError> {
327 let multi = self;
328 let isl_rs_ctx = multi.get_ctx();
329 let multi = multi.ptr;
330 let isl_rs_result = unsafe { isl_multi_id_get_space(multi) };
331 let isl_rs_result = Space { ptr: isl_rs_result,
332 should_free_on_drop: true };
333 let err = isl_rs_ctx.last_error();
334 if err != Error::None_ {
335 let err_msg = isl_rs_ctx.last_error_msg();
336 isl_rs_ctx.reset_error();
337 return Err(LibISLError::new(err, err_msg));
338 }
339 Ok(isl_rs_result)
340 }
341
342 pub fn plain_is_equal(&self, multi2: &MultiId) -> Result<bool, LibISLError> {
344 let multi1 = self;
345 let isl_rs_ctx = multi1.get_ctx();
346 let multi1 = multi1.ptr;
347 let multi2 = multi2.ptr;
348 let isl_rs_result = unsafe { isl_multi_id_plain_is_equal(multi1, multi2) };
349 let isl_rs_result = match isl_rs_result {
350 0 => false,
351 1 => true,
352 _ => {
353 return Err(LibISLError::new(Error::Unknown, "Got isl_bool = -1"));
354 }
355 };
356 let err = isl_rs_ctx.last_error();
357 if err != Error::None_ {
358 let err_msg = isl_rs_ctx.last_error_msg();
359 isl_rs_ctx.reset_error();
360 return Err(LibISLError::new(err, err_msg));
361 }
362 Ok(isl_rs_result)
363 }
364
365 pub fn range_factor_domain(self) -> Result<MultiId, LibISLError> {
367 let multi = self;
368 let isl_rs_ctx = multi.get_ctx();
369 let mut multi = multi;
370 multi.do_not_free_on_drop();
371 let multi = multi.ptr;
372 let isl_rs_result = unsafe { isl_multi_id_range_factor_domain(multi) };
373 let isl_rs_result = MultiId { ptr: isl_rs_result,
374 should_free_on_drop: true };
375 let err = isl_rs_ctx.last_error();
376 if err != Error::None_ {
377 let err_msg = isl_rs_ctx.last_error_msg();
378 isl_rs_ctx.reset_error();
379 return Err(LibISLError::new(err, err_msg));
380 }
381 Ok(isl_rs_result)
382 }
383
384 pub fn range_factor_range(self) -> Result<MultiId, LibISLError> {
386 let multi = self;
387 let isl_rs_ctx = multi.get_ctx();
388 let mut multi = multi;
389 multi.do_not_free_on_drop();
390 let multi = multi.ptr;
391 let isl_rs_result = unsafe { isl_multi_id_range_factor_range(multi) };
392 let isl_rs_result = MultiId { ptr: isl_rs_result,
393 should_free_on_drop: true };
394 let err = isl_rs_ctx.last_error();
395 if err != Error::None_ {
396 let err_msg = isl_rs_ctx.last_error_msg();
397 isl_rs_ctx.reset_error();
398 return Err(LibISLError::new(err, err_msg));
399 }
400 Ok(isl_rs_result)
401 }
402
403 pub fn range_is_wrapping(&self) -> Result<bool, LibISLError> {
405 let multi = self;
406 let isl_rs_ctx = multi.get_ctx();
407 let multi = multi.ptr;
408 let isl_rs_result = unsafe { isl_multi_id_range_is_wrapping(multi) };
409 let isl_rs_result = match isl_rs_result {
410 0 => false,
411 1 => true,
412 _ => {
413 return Err(LibISLError::new(Error::Unknown, "Got isl_bool = -1"));
414 }
415 };
416 let err = isl_rs_ctx.last_error();
417 if err != Error::None_ {
418 let err_msg = isl_rs_ctx.last_error_msg();
419 isl_rs_ctx.reset_error();
420 return Err(LibISLError::new(err, err_msg));
421 }
422 Ok(isl_rs_result)
423 }
424
425 pub fn range_product(self, multi2: MultiId) -> Result<MultiId, LibISLError> {
427 let multi1 = self;
428 let isl_rs_ctx = multi1.get_ctx();
429 let mut multi1 = multi1;
430 multi1.do_not_free_on_drop();
431 let multi1 = multi1.ptr;
432 let mut multi2 = multi2;
433 multi2.do_not_free_on_drop();
434 let multi2 = multi2.ptr;
435 let isl_rs_result = unsafe { isl_multi_id_range_product(multi1, multi2) };
436 let isl_rs_result = MultiId { ptr: isl_rs_result,
437 should_free_on_drop: true };
438 let err = isl_rs_ctx.last_error();
439 if err != Error::None_ {
440 let err_msg = isl_rs_ctx.last_error_msg();
441 isl_rs_ctx.reset_error();
442 return Err(LibISLError::new(err, err_msg));
443 }
444 Ok(isl_rs_result)
445 }
446
447 pub fn range_splice(self, pos: u32, multi2: MultiId) -> Result<MultiId, LibISLError> {
449 let multi1 = self;
450 let isl_rs_ctx = multi1.get_ctx();
451 let mut multi1 = multi1;
452 multi1.do_not_free_on_drop();
453 let multi1 = multi1.ptr;
454 let mut multi2 = multi2;
455 multi2.do_not_free_on_drop();
456 let multi2 = multi2.ptr;
457 let isl_rs_result = unsafe { isl_multi_id_range_splice(multi1, pos, multi2) };
458 let isl_rs_result = MultiId { ptr: isl_rs_result,
459 should_free_on_drop: true };
460 let err = isl_rs_ctx.last_error();
461 if err != Error::None_ {
462 let err_msg = isl_rs_ctx.last_error_msg();
463 isl_rs_ctx.reset_error();
464 return Err(LibISLError::new(err, err_msg));
465 }
466 Ok(isl_rs_result)
467 }
468
469 pub fn read_from_str(ctx: &Context, str_: &str) -> Result<MultiId, LibISLError> {
471 let isl_rs_ctx = Context { ptr: ctx.ptr,
472 should_free_on_drop: false };
473 let ctx = ctx.ptr;
474 let str_ = CString::new(str_).unwrap();
475 let str_ = str_.as_ptr();
476 let isl_rs_result = unsafe { isl_multi_id_read_from_str(ctx, str_) };
477 let isl_rs_result = MultiId { ptr: isl_rs_result,
478 should_free_on_drop: true };
479 let err = isl_rs_ctx.last_error();
480 if err != Error::None_ {
481 let err_msg = isl_rs_ctx.last_error_msg();
482 isl_rs_ctx.reset_error();
483 return Err(LibISLError::new(err, err_msg));
484 }
485 Ok(isl_rs_result)
486 }
487
488 pub fn reset_user(self) -> Result<MultiId, LibISLError> {
490 let multi = self;
491 let isl_rs_ctx = multi.get_ctx();
492 let mut multi = multi;
493 multi.do_not_free_on_drop();
494 let multi = multi.ptr;
495 let isl_rs_result = unsafe { isl_multi_id_reset_user(multi) };
496 let isl_rs_result = MultiId { ptr: isl_rs_result,
497 should_free_on_drop: true };
498 let err = isl_rs_ctx.last_error();
499 if err != Error::None_ {
500 let err_msg = isl_rs_ctx.last_error_msg();
501 isl_rs_ctx.reset_error();
502 return Err(LibISLError::new(err, err_msg));
503 }
504 Ok(isl_rs_result)
505 }
506
507 pub fn set_at(self, pos: i32, el: Id) -> Result<MultiId, LibISLError> {
509 let multi = self;
510 let isl_rs_ctx = multi.get_ctx();
511 let mut multi = multi;
512 multi.do_not_free_on_drop();
513 let multi = multi.ptr;
514 let mut el = el;
515 el.do_not_free_on_drop();
516 let el = el.ptr;
517 let isl_rs_result = unsafe { isl_multi_id_set_at(multi, pos, el) };
518 let isl_rs_result = MultiId { ptr: isl_rs_result,
519 should_free_on_drop: true };
520 let err = isl_rs_ctx.last_error();
521 if err != Error::None_ {
522 let err_msg = isl_rs_ctx.last_error_msg();
523 isl_rs_ctx.reset_error();
524 return Err(LibISLError::new(err, err_msg));
525 }
526 Ok(isl_rs_result)
527 }
528
529 pub fn set_id(self, pos: i32, el: Id) -> Result<MultiId, LibISLError> {
531 let multi = self;
532 let isl_rs_ctx = multi.get_ctx();
533 let mut multi = multi;
534 multi.do_not_free_on_drop();
535 let multi = multi.ptr;
536 let mut el = el;
537 el.do_not_free_on_drop();
538 let el = el.ptr;
539 let isl_rs_result = unsafe { isl_multi_id_set_id(multi, pos, el) };
540 let isl_rs_result = MultiId { ptr: isl_rs_result,
541 should_free_on_drop: true };
542 let err = isl_rs_ctx.last_error();
543 if err != Error::None_ {
544 let err_msg = isl_rs_ctx.last_error_msg();
545 isl_rs_ctx.reset_error();
546 return Err(LibISLError::new(err, err_msg));
547 }
548 Ok(isl_rs_result)
549 }
550
551 pub fn size(&self) -> Result<i32, LibISLError> {
553 let multi = self;
554 let isl_rs_ctx = multi.get_ctx();
555 let multi = multi.ptr;
556 let isl_rs_result = unsafe { isl_multi_id_size(multi) };
557 let err = isl_rs_ctx.last_error();
558 if err != Error::None_ {
559 let err_msg = isl_rs_ctx.last_error_msg();
560 isl_rs_ctx.reset_error();
561 return Err(LibISLError::new(err, err_msg));
562 }
563 Ok(isl_rs_result)
564 }
565
566 pub fn to_str(&self) -> Result<&str, LibISLError> {
568 let mi = self;
569 let isl_rs_ctx = mi.get_ctx();
570 let mi = mi.ptr;
571 let isl_rs_result = unsafe { isl_multi_id_to_str(mi) };
572 let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
573 let isl_rs_result = isl_rs_result.to_str().unwrap();
574 let err = isl_rs_ctx.last_error();
575 if err != Error::None_ {
576 let err_msg = isl_rs_ctx.last_error_msg();
577 isl_rs_ctx.reset_error();
578 return Err(LibISLError::new(err, err_msg));
579 }
580 Ok(isl_rs_result)
581 }
582
583 pub fn do_not_free_on_drop(&mut self) {
586 self.should_free_on_drop = false;
587 }
588}
589
590impl Drop for MultiId {
591 fn drop(&mut self) {
592 if self.should_free_on_drop {
593 unsafe {
594 isl_multi_id_free(self.ptr);
595 }
596 }
597 }
598}