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 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
90 }
91 Ok(isl_rs_result)
92 }
93
94 pub fn copy(&self) -> Result<MultiId, LibISLError> {
96 let multi = self;
97 let isl_rs_ctx = multi.get_ctx();
98 let multi = multi.ptr;
99 let isl_rs_result = unsafe { isl_multi_id_copy(multi) };
100 let isl_rs_result = MultiId { ptr: isl_rs_result,
101 should_free_on_drop: true };
102 let err = isl_rs_ctx.last_error();
103 if err != Error::None_ {
104 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
105 }
106 Ok(isl_rs_result)
107 }
108
109 pub fn dump(&self) -> Result<(), LibISLError> {
111 let mi = self;
112 let isl_rs_ctx = mi.get_ctx();
113 let mi = mi.ptr;
114 let isl_rs_result = unsafe { isl_multi_id_dump(mi) };
115 let err = isl_rs_ctx.last_error();
116 if err != Error::None_ {
117 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
118 }
119 Ok(isl_rs_result)
120 }
121
122 pub fn factor_range(self) -> Result<MultiId, LibISLError> {
124 let multi = self;
125 let isl_rs_ctx = multi.get_ctx();
126 let mut multi = multi;
127 multi.do_not_free_on_drop();
128 let multi = multi.ptr;
129 let isl_rs_result = unsafe { isl_multi_id_factor_range(multi) };
130 let isl_rs_result = MultiId { ptr: isl_rs_result,
131 should_free_on_drop: true };
132 let err = isl_rs_ctx.last_error();
133 if err != Error::None_ {
134 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
135 }
136 Ok(isl_rs_result)
137 }
138
139 pub fn flat_range_product(self, multi2: MultiId) -> Result<MultiId, LibISLError> {
141 let multi1 = self;
142 let isl_rs_ctx = multi1.get_ctx();
143 let mut multi1 = multi1;
144 multi1.do_not_free_on_drop();
145 let multi1 = multi1.ptr;
146 let mut multi2 = multi2;
147 multi2.do_not_free_on_drop();
148 let multi2 = multi2.ptr;
149 let isl_rs_result = unsafe { isl_multi_id_flat_range_product(multi1, multi2) };
150 let isl_rs_result = MultiId { ptr: isl_rs_result,
151 should_free_on_drop: true };
152 let err = isl_rs_ctx.last_error();
153 if err != Error::None_ {
154 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
155 }
156 Ok(isl_rs_result)
157 }
158
159 pub fn flatten_range(self) -> Result<MultiId, LibISLError> {
161 let multi = self;
162 let isl_rs_ctx = multi.get_ctx();
163 let mut multi = multi;
164 multi.do_not_free_on_drop();
165 let multi = multi.ptr;
166 let isl_rs_result = unsafe { isl_multi_id_flatten_range(multi) };
167 let isl_rs_result = MultiId { ptr: isl_rs_result,
168 should_free_on_drop: true };
169 let err = isl_rs_ctx.last_error();
170 if err != Error::None_ {
171 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
172 }
173 Ok(isl_rs_result)
174 }
175
176 pub fn free(self) -> Result<MultiId, LibISLError> {
178 let multi = self;
179 let isl_rs_ctx = multi.get_ctx();
180 let mut multi = multi;
181 multi.do_not_free_on_drop();
182 let multi = multi.ptr;
183 let isl_rs_result = unsafe { isl_multi_id_free(multi) };
184 let isl_rs_result = MultiId { ptr: isl_rs_result,
185 should_free_on_drop: true };
186 let err = isl_rs_ctx.last_error();
187 if err != Error::None_ {
188 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
189 }
190 Ok(isl_rs_result)
191 }
192
193 pub fn from_id_list(space: Space, list: IdList) -> Result<MultiId, LibISLError> {
195 let isl_rs_ctx = space.get_ctx();
196 let mut space = space;
197 space.do_not_free_on_drop();
198 let space = space.ptr;
199 let mut list = list;
200 list.do_not_free_on_drop();
201 let list = list.ptr;
202 let isl_rs_result = unsafe { isl_multi_id_from_id_list(space, list) };
203 let isl_rs_result = MultiId { ptr: isl_rs_result,
204 should_free_on_drop: true };
205 let err = isl_rs_ctx.last_error();
206 if err != Error::None_ {
207 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
208 }
209 Ok(isl_rs_result)
210 }
211
212 pub fn from_range(self) -> Result<MultiId, LibISLError> {
214 let multi = self;
215 let isl_rs_ctx = multi.get_ctx();
216 let mut multi = multi;
217 multi.do_not_free_on_drop();
218 let multi = multi.ptr;
219 let isl_rs_result = unsafe { isl_multi_id_from_range(multi) };
220 let isl_rs_result = MultiId { ptr: isl_rs_result,
221 should_free_on_drop: true };
222 let err = isl_rs_ctx.last_error();
223 if err != Error::None_ {
224 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
225 }
226 Ok(isl_rs_result)
227 }
228
229 pub fn get_at(&self, pos: i32) -> Result<Id, LibISLError> {
231 let multi = self;
232 let isl_rs_ctx = multi.get_ctx();
233 let multi = multi.ptr;
234 let isl_rs_result = unsafe { isl_multi_id_get_at(multi, pos) };
235 let isl_rs_result = Id { ptr: isl_rs_result,
236 should_free_on_drop: true };
237 let err = isl_rs_ctx.last_error();
238 if err != Error::None_ {
239 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
240 }
241 Ok(isl_rs_result)
242 }
243
244 pub fn get_ctx(&self) -> Context {
246 let multi = self;
247 let multi = multi.ptr;
248 let isl_rs_result = unsafe { isl_multi_id_get_ctx(multi) };
249 let isl_rs_result = Context { ptr: isl_rs_result,
250 should_free_on_drop: false };
251 isl_rs_result
252 }
253
254 pub fn get_domain_space(&self) -> Result<Space, LibISLError> {
256 let multi = self;
257 let isl_rs_ctx = multi.get_ctx();
258 let multi = multi.ptr;
259 let isl_rs_result = unsafe { isl_multi_id_get_domain_space(multi) };
260 let isl_rs_result = Space { ptr: isl_rs_result,
261 should_free_on_drop: true };
262 let err = isl_rs_ctx.last_error();
263 if err != Error::None_ {
264 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
265 }
266 Ok(isl_rs_result)
267 }
268
269 pub fn get_id(&self, pos: i32) -> Result<Id, LibISLError> {
271 let multi = self;
272 let isl_rs_ctx = multi.get_ctx();
273 let multi = multi.ptr;
274 let isl_rs_result = unsafe { isl_multi_id_get_id(multi, pos) };
275 let isl_rs_result = Id { ptr: isl_rs_result,
276 should_free_on_drop: true };
277 let err = isl_rs_ctx.last_error();
278 if err != Error::None_ {
279 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
280 }
281 Ok(isl_rs_result)
282 }
283
284 pub fn get_list(&self) -> Result<IdList, LibISLError> {
286 let multi = self;
287 let isl_rs_ctx = multi.get_ctx();
288 let multi = multi.ptr;
289 let isl_rs_result = unsafe { isl_multi_id_get_list(multi) };
290 let isl_rs_result = IdList { ptr: isl_rs_result,
291 should_free_on_drop: true };
292 let err = isl_rs_ctx.last_error();
293 if err != Error::None_ {
294 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
295 }
296 Ok(isl_rs_result)
297 }
298
299 pub fn get_space(&self) -> Result<Space, LibISLError> {
301 let multi = self;
302 let isl_rs_ctx = multi.get_ctx();
303 let multi = multi.ptr;
304 let isl_rs_result = unsafe { isl_multi_id_get_space(multi) };
305 let isl_rs_result = Space { ptr: isl_rs_result,
306 should_free_on_drop: true };
307 let err = isl_rs_ctx.last_error();
308 if err != Error::None_ {
309 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
310 }
311 Ok(isl_rs_result)
312 }
313
314 pub fn plain_is_equal(&self, multi2: &MultiId) -> Result<bool, LibISLError> {
316 let multi1 = self;
317 let isl_rs_ctx = multi1.get_ctx();
318 let multi1 = multi1.ptr;
319 let multi2 = multi2.ptr;
320 let isl_rs_result = unsafe { isl_multi_id_plain_is_equal(multi1, multi2) };
321 let isl_rs_result = match isl_rs_result {
322 0 => false,
323 1 => true,
324 _ => panic!("Got isl_bool = -1"),
325 };
326 let err = isl_rs_ctx.last_error();
327 if err != Error::None_ {
328 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
329 }
330 Ok(isl_rs_result)
331 }
332
333 pub fn range_factor_domain(self) -> Result<MultiId, LibISLError> {
335 let multi = self;
336 let isl_rs_ctx = multi.get_ctx();
337 let mut multi = multi;
338 multi.do_not_free_on_drop();
339 let multi = multi.ptr;
340 let isl_rs_result = unsafe { isl_multi_id_range_factor_domain(multi) };
341 let isl_rs_result = MultiId { ptr: isl_rs_result,
342 should_free_on_drop: true };
343 let err = isl_rs_ctx.last_error();
344 if err != Error::None_ {
345 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
346 }
347 Ok(isl_rs_result)
348 }
349
350 pub fn range_factor_range(self) -> Result<MultiId, LibISLError> {
352 let multi = self;
353 let isl_rs_ctx = multi.get_ctx();
354 let mut multi = multi;
355 multi.do_not_free_on_drop();
356 let multi = multi.ptr;
357 let isl_rs_result = unsafe { isl_multi_id_range_factor_range(multi) };
358 let isl_rs_result = MultiId { ptr: isl_rs_result,
359 should_free_on_drop: true };
360 let err = isl_rs_ctx.last_error();
361 if err != Error::None_ {
362 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
363 }
364 Ok(isl_rs_result)
365 }
366
367 pub fn range_is_wrapping(&self) -> Result<bool, LibISLError> {
369 let multi = self;
370 let isl_rs_ctx = multi.get_ctx();
371 let multi = multi.ptr;
372 let isl_rs_result = unsafe { isl_multi_id_range_is_wrapping(multi) };
373 let isl_rs_result = match isl_rs_result {
374 0 => false,
375 1 => true,
376 _ => panic!("Got isl_bool = -1"),
377 };
378 let err = isl_rs_ctx.last_error();
379 if err != Error::None_ {
380 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
381 }
382 Ok(isl_rs_result)
383 }
384
385 pub fn range_product(self, multi2: MultiId) -> Result<MultiId, LibISLError> {
387 let multi1 = self;
388 let isl_rs_ctx = multi1.get_ctx();
389 let mut multi1 = multi1;
390 multi1.do_not_free_on_drop();
391 let multi1 = multi1.ptr;
392 let mut multi2 = multi2;
393 multi2.do_not_free_on_drop();
394 let multi2 = multi2.ptr;
395 let isl_rs_result = unsafe { isl_multi_id_range_product(multi1, multi2) };
396 let isl_rs_result = MultiId { ptr: isl_rs_result,
397 should_free_on_drop: true };
398 let err = isl_rs_ctx.last_error();
399 if err != Error::None_ {
400 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
401 }
402 Ok(isl_rs_result)
403 }
404
405 pub fn range_splice(self, pos: u32, multi2: MultiId) -> Result<MultiId, LibISLError> {
407 let multi1 = self;
408 let isl_rs_ctx = multi1.get_ctx();
409 let mut multi1 = multi1;
410 multi1.do_not_free_on_drop();
411 let multi1 = multi1.ptr;
412 let mut multi2 = multi2;
413 multi2.do_not_free_on_drop();
414 let multi2 = multi2.ptr;
415 let isl_rs_result = unsafe { isl_multi_id_range_splice(multi1, pos, multi2) };
416 let isl_rs_result = MultiId { ptr: isl_rs_result,
417 should_free_on_drop: true };
418 let err = isl_rs_ctx.last_error();
419 if err != Error::None_ {
420 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
421 }
422 Ok(isl_rs_result)
423 }
424
425 pub fn read_from_str(ctx: &Context, str_: &str) -> Result<MultiId, LibISLError> {
427 let isl_rs_ctx = Context { ptr: ctx.ptr,
428 should_free_on_drop: false };
429 let ctx = ctx.ptr;
430 let str_ = CString::new(str_).unwrap();
431 let str_ = str_.as_ptr();
432 let isl_rs_result = unsafe { isl_multi_id_read_from_str(ctx, str_) };
433 let isl_rs_result = MultiId { ptr: isl_rs_result,
434 should_free_on_drop: true };
435 let err = isl_rs_ctx.last_error();
436 if err != Error::None_ {
437 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
438 }
439 Ok(isl_rs_result)
440 }
441
442 pub fn reset_user(self) -> Result<MultiId, LibISLError> {
444 let multi = self;
445 let isl_rs_ctx = multi.get_ctx();
446 let mut multi = multi;
447 multi.do_not_free_on_drop();
448 let multi = multi.ptr;
449 let isl_rs_result = unsafe { isl_multi_id_reset_user(multi) };
450 let isl_rs_result = MultiId { ptr: isl_rs_result,
451 should_free_on_drop: true };
452 let err = isl_rs_ctx.last_error();
453 if err != Error::None_ {
454 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
455 }
456 Ok(isl_rs_result)
457 }
458
459 pub fn set_at(self, pos: i32, el: Id) -> Result<MultiId, LibISLError> {
461 let multi = self;
462 let isl_rs_ctx = multi.get_ctx();
463 let mut multi = multi;
464 multi.do_not_free_on_drop();
465 let multi = multi.ptr;
466 let mut el = el;
467 el.do_not_free_on_drop();
468 let el = el.ptr;
469 let isl_rs_result = unsafe { isl_multi_id_set_at(multi, pos, el) };
470 let isl_rs_result = MultiId { ptr: isl_rs_result,
471 should_free_on_drop: true };
472 let err = isl_rs_ctx.last_error();
473 if err != Error::None_ {
474 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
475 }
476 Ok(isl_rs_result)
477 }
478
479 pub fn set_id(self, pos: i32, el: Id) -> Result<MultiId, LibISLError> {
481 let multi = self;
482 let isl_rs_ctx = multi.get_ctx();
483 let mut multi = multi;
484 multi.do_not_free_on_drop();
485 let multi = multi.ptr;
486 let mut el = el;
487 el.do_not_free_on_drop();
488 let el = el.ptr;
489 let isl_rs_result = unsafe { isl_multi_id_set_id(multi, pos, el) };
490 let isl_rs_result = MultiId { ptr: isl_rs_result,
491 should_free_on_drop: true };
492 let err = isl_rs_ctx.last_error();
493 if err != Error::None_ {
494 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
495 }
496 Ok(isl_rs_result)
497 }
498
499 pub fn size(&self) -> Result<i32, LibISLError> {
501 let multi = self;
502 let isl_rs_ctx = multi.get_ctx();
503 let multi = multi.ptr;
504 let isl_rs_result = unsafe { isl_multi_id_size(multi) };
505 let err = isl_rs_ctx.last_error();
506 if err != Error::None_ {
507 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
508 }
509 Ok(isl_rs_result)
510 }
511
512 pub fn to_str(&self) -> Result<&str, LibISLError> {
514 let mi = self;
515 let isl_rs_ctx = mi.get_ctx();
516 let mi = mi.ptr;
517 let isl_rs_result = unsafe { isl_multi_id_to_str(mi) };
518 let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
519 let isl_rs_result = isl_rs_result.to_str().unwrap();
520 let err = isl_rs_ctx.last_error();
521 if err != Error::None_ {
522 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
523 }
524 Ok(isl_rs_result)
525 }
526
527 pub fn do_not_free_on_drop(&mut self) {
530 self.should_free_on_drop = false;
531 }
532}
533
534impl Drop for MultiId {
535 fn drop(&mut self) {
536 if self.should_free_on_drop {
537 unsafe {
538 isl_multi_id_free(self.ptr);
539 }
540 }
541 }
542}