1use std::ffi::c_void;
6use std::mem;
7use std::os::raw::c_long;
8use std::sync::Once;
9
10#[cfg(any(feature = "gmp", feature = "gmprational"))]
11use std::mem::MaybeUninit;
12
13use crate::NumberType;
14
15use cddlib_sys as sys;
16
17#[cfg(feature = "gmp")]
18pub struct CddFloat {
19 inner: sys::gmpfloat::mytype,
20}
21
22#[cfg(feature = "gmprational")]
23pub struct CddRational {
24 inner: sys::gmprational::mytype,
25}
26
27#[cfg(feature = "f64")]
28pub type DefaultNumber = f64;
29
30#[cfg(all(not(feature = "f64"), feature = "gmprational"))]
31pub type DefaultNumber = CddRational;
32
33#[cfg(all(not(feature = "f64"), not(feature = "gmprational"), feature = "gmp"))]
34pub type DefaultNumber = CddFloat;
35
36mod sealed {
37 pub trait Sealed {}
38}
39
40pub trait CddNumber: sealed::Sealed + 'static {
41 const MYTYPE_SIZE: usize;
42 const DEFAULT_NUMBER_TYPE: NumberType;
43
44 fn ensure_initialized();
45
46 #[doc(hidden)]
47 fn dd_no_error() -> u32;
48
49 #[doc(hidden)]
50 unsafe fn dd_create_matrix(rows: c_long, cols: c_long) -> *mut c_void;
51
52 #[doc(hidden)]
53 unsafe fn dd_copy_matrix(matrix: *mut c_void) -> *mut c_void;
54
55 #[doc(hidden)]
56 unsafe fn dd_free_matrix(matrix: *mut c_void);
57
58 #[doc(hidden)]
59 unsafe fn dd_matrix_append_to(dst: *mut *mut c_void, src: *mut c_void) -> i32;
60
61 #[doc(hidden)]
62 unsafe fn dd_append_matrix(a: *mut c_void, b: *mut c_void) -> *mut c_void;
63
64 #[doc(hidden)]
65 unsafe fn dd_matrix_row_remove(matrix: *mut *mut c_void, row: c_long) -> i32;
66
67 #[doc(hidden)]
68 unsafe fn dd_initialize_arow(cols: c_long, out: *mut *mut c_void);
69
70 #[doc(hidden)]
71 unsafe fn dd_free_arow(cols: c_long, arow: *mut c_void);
72
73 #[doc(hidden)]
74 unsafe fn dd_redundant(
75 matrix: *mut c_void,
76 row: c_long,
77 cert: *mut c_void,
78 err: *mut u32,
79 ) -> i32;
80
81 #[doc(hidden)]
82 unsafe fn dd_redundant_rows(matrix: *mut c_void, err: *mut u32) -> *mut libc::c_ulong;
83
84 #[doc(hidden)]
85 unsafe fn dd_matrix_canonicalize(
86 matrix: *mut *mut c_void,
87 impl_lin: *mut *mut libc::c_ulong,
88 redset: *mut *mut libc::c_ulong,
89 newpos: *mut *mut c_long,
90 err: *mut u32,
91 ) -> i32;
92
93 #[doc(hidden)]
94 unsafe fn set_groundsize(set: *mut libc::c_ulong) -> c_long;
95
96 #[doc(hidden)]
97 unsafe fn set_member(elem: c_long, set: *mut libc::c_ulong) -> i32;
98
99 #[doc(hidden)]
100 unsafe fn set_free(set: *mut libc::c_ulong);
101
102 #[doc(hidden)]
103 unsafe fn dd_matrix2poly(matrix: *mut c_void, err: *mut u32) -> *mut c_void;
104
105 #[doc(hidden)]
106 unsafe fn dd_free_polyhedra(poly: *mut c_void);
107
108 #[doc(hidden)]
109 unsafe fn dd_copy_inequalities(poly: *mut c_void) -> *mut c_void;
110
111 #[doc(hidden)]
112 unsafe fn dd_copy_generators(poly: *mut c_void) -> *mut c_void;
113
114 #[doc(hidden)]
115 unsafe fn dd_copy_adjacency(poly: *mut c_void) -> *mut c_void;
116
117 #[doc(hidden)]
118 unsafe fn dd_copy_input_adjacency(poly: *mut c_void) -> *mut c_void;
119
120 #[doc(hidden)]
121 unsafe fn dd_copy_incidence(poly: *mut c_void) -> *mut c_void;
122
123 #[doc(hidden)]
124 unsafe fn dd_copy_input_incidence(poly: *mut c_void) -> *mut c_void;
125
126 #[doc(hidden)]
127 unsafe fn dd_append_matrix2poly(poly: *mut *mut c_void, rows: *mut c_void) -> i32;
128
129 #[doc(hidden)]
130 unsafe fn dd_free_set_family(family: *mut c_void);
131
132 #[doc(hidden)]
133 unsafe fn dd_matrix2lp(matrix: *mut c_void, err: *mut u32) -> *mut c_void;
134
135 #[doc(hidden)]
136 unsafe fn dd_free_lp_data(lp: *mut c_void);
137
138 #[doc(hidden)]
139 unsafe fn dd_lp_solve_dual_simplex(lp: *mut c_void, err: *mut u32) -> i32;
140
141 #[doc(hidden)]
142 unsafe fn lp_status_raw(lp: *mut c_void) -> u32;
143
144 #[doc(hidden)]
145 unsafe fn dd_copy_lp_solution(lp: *mut c_void) -> *mut c_void;
146
147 #[doc(hidden)]
148 unsafe fn dd_free_lp_solution(sol: *mut c_void);
149
150 #[doc(hidden)]
151 unsafe fn lp_solution_optvalue_ptr(sol: *mut c_void) -> *const c_void;
152
153 #[doc(hidden)]
154 unsafe fn write_mytype_real(target: *mut c_void, value: f64);
155
156 #[doc(hidden)]
157 unsafe fn write_mytype_int(target: *mut c_void, value: c_long);
158
159 #[doc(hidden)]
160 unsafe fn read_mytype_real(source: *const c_void) -> f64;
161
162 #[doc(hidden)]
163 unsafe fn write_mytype(target: *mut c_void, value: &Self);
164
165 #[doc(hidden)]
166 unsafe fn read_mytype(source: *const c_void) -> Self;
167}
168
169#[cfg(feature = "f64")]
170impl sealed::Sealed for f64 {}
171
172#[cfg(feature = "f64")]
173impl CddNumber for f64 {
174 const MYTYPE_SIZE: usize = mem::size_of::<sys::f64::mytype>();
175 const DEFAULT_NUMBER_TYPE: NumberType = NumberType::Real;
176
177 fn ensure_initialized() {
178 static INIT: Once = Once::new();
179 INIT.call_once(|| unsafe {
180 sys::f64::dd_set_global_constants();
181 });
182 }
183
184 fn dd_no_error() -> u32 {
185 sys::f64::dd_ErrorType_dd_NoError
186 }
187
188 unsafe fn dd_create_matrix(rows: c_long, cols: c_long) -> *mut c_void {
189 unsafe { sys::f64::dd_CreateMatrix(rows, cols).cast() }
190 }
191
192 unsafe fn dd_copy_matrix(matrix: *mut c_void) -> *mut c_void {
193 unsafe { sys::f64::dd_CopyMatrix(matrix.cast()).cast() }
194 }
195
196 unsafe fn dd_free_matrix(matrix: *mut c_void) {
197 unsafe {
198 sys::f64::dd_FreeMatrix(matrix.cast());
199 }
200 }
201
202 unsafe fn dd_matrix_append_to(dst: *mut *mut c_void, src: *mut c_void) -> i32 {
203 unsafe { sys::f64::dd_MatrixAppendTo(dst.cast(), src.cast()) }
204 }
205
206 unsafe fn dd_append_matrix(a: *mut c_void, b: *mut c_void) -> *mut c_void {
207 unsafe { sys::f64::dd_AppendMatrix(a.cast(), b.cast()).cast() }
208 }
209
210 unsafe fn dd_matrix_row_remove(matrix: *mut *mut c_void, row: c_long) -> i32 {
211 unsafe { sys::f64::dd_MatrixRowRemove(matrix.cast(), row) }
212 }
213
214 unsafe fn dd_initialize_arow(cols: c_long, out: *mut *mut c_void) {
215 unsafe {
216 sys::f64::dd_InitializeArow(cols, out.cast());
217 }
218 }
219
220 unsafe fn dd_free_arow(cols: c_long, arow: *mut c_void) {
221 unsafe {
222 sys::f64::dd_FreeArow(cols, arow.cast());
223 }
224 }
225
226 unsafe fn dd_redundant(
227 matrix: *mut c_void,
228 row: c_long,
229 cert: *mut c_void,
230 err: *mut u32,
231 ) -> i32 {
232 unsafe { sys::f64::dd_Redundant(matrix.cast(), row, cert.cast(), err.cast()) }
233 }
234
235 unsafe fn dd_redundant_rows(matrix: *mut c_void, err: *mut u32) -> *mut libc::c_ulong {
236 unsafe { sys::f64::dd_RedundantRows(matrix.cast(), err.cast()).cast() }
237 }
238
239 unsafe fn dd_matrix_canonicalize(
240 matrix: *mut *mut c_void,
241 impl_lin: *mut *mut libc::c_ulong,
242 redset: *mut *mut libc::c_ulong,
243 newpos: *mut *mut c_long,
244 err: *mut u32,
245 ) -> i32 {
246 unsafe {
247 sys::f64::dd_MatrixCanonicalize(
248 matrix.cast(),
249 impl_lin.cast(),
250 redset.cast(),
251 newpos.cast(),
252 err.cast(),
253 )
254 }
255 }
256
257 unsafe fn set_groundsize(set: *mut libc::c_ulong) -> c_long {
258 unsafe { sys::f64::set_groundsize(set.cast()) }
259 }
260
261 unsafe fn set_member(elem: c_long, set: *mut libc::c_ulong) -> i32 {
262 unsafe { sys::f64::set_member(elem, set.cast()) }
263 }
264
265 unsafe fn set_free(set: *mut libc::c_ulong) {
266 unsafe {
267 sys::f64::set_free(set.cast());
268 }
269 }
270
271 unsafe fn dd_matrix2poly(matrix: *mut c_void, err: *mut u32) -> *mut c_void {
272 unsafe { sys::f64::dd_DDMatrix2Poly(matrix.cast(), err.cast()).cast() }
273 }
274
275 unsafe fn dd_free_polyhedra(poly: *mut c_void) {
276 unsafe {
277 sys::f64::dd_FreePolyhedra(poly.cast());
278 }
279 }
280
281 unsafe fn dd_copy_inequalities(poly: *mut c_void) -> *mut c_void {
282 unsafe { sys::f64::dd_CopyInequalities(poly.cast()).cast() }
283 }
284
285 unsafe fn dd_copy_generators(poly: *mut c_void) -> *mut c_void {
286 unsafe { sys::f64::dd_CopyGenerators(poly.cast()).cast() }
287 }
288
289 unsafe fn dd_copy_adjacency(poly: *mut c_void) -> *mut c_void {
290 unsafe { sys::f64::dd_CopyAdjacency(poly.cast()).cast() }
291 }
292
293 unsafe fn dd_copy_input_adjacency(poly: *mut c_void) -> *mut c_void {
294 unsafe { sys::f64::dd_CopyInputAdjacency(poly.cast()).cast() }
295 }
296
297 unsafe fn dd_copy_incidence(poly: *mut c_void) -> *mut c_void {
298 unsafe { sys::f64::dd_CopyIncidence(poly.cast()).cast() }
299 }
300
301 unsafe fn dd_copy_input_incidence(poly: *mut c_void) -> *mut c_void {
302 unsafe { sys::f64::dd_CopyInputIncidence(poly.cast()).cast() }
303 }
304
305 unsafe fn dd_append_matrix2poly(poly: *mut *mut c_void, rows: *mut c_void) -> i32 {
306 unsafe { sys::f64::dd_AppendMatrix2Poly(poly.cast(), rows.cast()) }
307 }
308
309 unsafe fn dd_free_set_family(family: *mut c_void) {
310 unsafe {
311 sys::f64::dd_FreeSetFamily(family.cast());
312 }
313 }
314
315 unsafe fn dd_matrix2lp(matrix: *mut c_void, err: *mut u32) -> *mut c_void {
316 unsafe { sys::f64::dd_Matrix2LP(matrix.cast(), err.cast()).cast() }
317 }
318
319 unsafe fn dd_free_lp_data(lp: *mut c_void) {
320 unsafe {
321 sys::f64::dd_FreeLPData(lp.cast());
322 }
323 }
324
325 unsafe fn dd_lp_solve_dual_simplex(lp: *mut c_void, err: *mut u32) -> i32 {
326 unsafe {
327 sys::f64::dd_LPSolve(
328 lp.cast(),
329 sys::f64::dd_LPSolverType_dd_DualSimplex,
330 err.cast(),
331 )
332 }
333 }
334
335 unsafe fn lp_status_raw(lp: *mut c_void) -> u32 {
336 unsafe { (*lp.cast::<sys::f64::dd_lpdata>()).LPS }
337 }
338
339 unsafe fn dd_copy_lp_solution(lp: *mut c_void) -> *mut c_void {
340 unsafe { sys::f64::dd_CopyLPSolution(lp.cast()).cast() }
341 }
342
343 unsafe fn dd_free_lp_solution(sol: *mut c_void) {
344 unsafe {
345 sys::f64::dd_FreeLPSolution(sol.cast());
346 }
347 }
348
349 unsafe fn lp_solution_optvalue_ptr(sol: *mut c_void) -> *const c_void {
350 unsafe {
351 let sol = sol.cast::<sys::f64::dd_lpsolution>();
352 (&(*sol).optvalue as *const sys::f64::mytype).cast()
353 }
354 }
355
356 unsafe fn write_mytype_real(target: *mut c_void, value: f64) {
357 unsafe {
358 (*target.cast::<sys::f64::mytype>())[0] = value;
359 }
360 }
361
362 unsafe fn write_mytype_int(target: *mut c_void, value: c_long) {
363 unsafe {
364 (*target.cast::<sys::f64::mytype>())[0] = value as f64;
365 }
366 }
367
368 unsafe fn read_mytype_real(source: *const c_void) -> f64 {
369 unsafe { (*source.cast::<sys::f64::mytype>())[0] }
370 }
371
372 unsafe fn write_mytype(target: *mut c_void, value: &Self) {
373 unsafe {
374 Self::write_mytype_real(target, *value);
375 }
376 }
377
378 unsafe fn read_mytype(source: *const c_void) -> Self {
379 unsafe { Self::read_mytype_real(source) }
380 }
381}
382
383#[cfg(feature = "gmp")]
384impl sealed::Sealed for CddFloat {}
385
386#[cfg(feature = "gmp")]
387impl CddNumber for CddFloat {
388 const MYTYPE_SIZE: usize = mem::size_of::<sys::gmpfloat::mytype>();
389 const DEFAULT_NUMBER_TYPE: NumberType = NumberType::Real;
390
391 fn ensure_initialized() {
392 static INIT: Once = Once::new();
393 INIT.call_once(|| unsafe {
394 sys::gmpfloat::dd_set_global_constants();
395 });
396 }
397
398 fn dd_no_error() -> u32 {
399 sys::gmpfloat::dd_ErrorType_dd_NoError
400 }
401
402 unsafe fn dd_create_matrix(rows: c_long, cols: c_long) -> *mut c_void {
403 unsafe { sys::gmpfloat::dd_CreateMatrix(rows, cols).cast() }
404 }
405
406 unsafe fn dd_copy_matrix(matrix: *mut c_void) -> *mut c_void {
407 unsafe { sys::gmpfloat::dd_CopyMatrix(matrix.cast()).cast() }
408 }
409
410 unsafe fn dd_free_matrix(matrix: *mut c_void) {
411 unsafe {
412 sys::gmpfloat::dd_FreeMatrix(matrix.cast());
413 }
414 }
415
416 unsafe fn dd_matrix_append_to(dst: *mut *mut c_void, src: *mut c_void) -> i32 {
417 unsafe { sys::gmpfloat::dd_MatrixAppendTo(dst.cast(), src.cast()) }
418 }
419
420 unsafe fn dd_append_matrix(a: *mut c_void, b: *mut c_void) -> *mut c_void {
421 unsafe { sys::gmpfloat::dd_AppendMatrix(a.cast(), b.cast()).cast() }
422 }
423
424 unsafe fn dd_matrix_row_remove(matrix: *mut *mut c_void, row: c_long) -> i32 {
425 unsafe { sys::gmpfloat::dd_MatrixRowRemove(matrix.cast(), row) }
426 }
427
428 unsafe fn dd_initialize_arow(cols: c_long, out: *mut *mut c_void) {
429 unsafe {
430 sys::gmpfloat::dd_InitializeArow(cols, out.cast());
431 }
432 }
433
434 unsafe fn dd_free_arow(cols: c_long, arow: *mut c_void) {
435 unsafe {
436 sys::gmpfloat::dd_FreeArow(cols, arow.cast());
437 }
438 }
439
440 unsafe fn dd_redundant(
441 matrix: *mut c_void,
442 row: c_long,
443 cert: *mut c_void,
444 err: *mut u32,
445 ) -> i32 {
446 unsafe { sys::gmpfloat::dd_Redundant(matrix.cast(), row, cert.cast(), err.cast()) }
447 }
448
449 unsafe fn dd_redundant_rows(matrix: *mut c_void, err: *mut u32) -> *mut libc::c_ulong {
450 unsafe { sys::gmpfloat::dd_RedundantRows(matrix.cast(), err.cast()).cast() }
451 }
452
453 unsafe fn dd_matrix_canonicalize(
454 matrix: *mut *mut c_void,
455 impl_lin: *mut *mut libc::c_ulong,
456 redset: *mut *mut libc::c_ulong,
457 newpos: *mut *mut c_long,
458 err: *mut u32,
459 ) -> i32 {
460 unsafe {
461 sys::gmpfloat::dd_MatrixCanonicalize(
462 matrix.cast(),
463 impl_lin.cast(),
464 redset.cast(),
465 newpos.cast(),
466 err.cast(),
467 )
468 }
469 }
470
471 unsafe fn set_groundsize(set: *mut libc::c_ulong) -> c_long {
472 unsafe { sys::gmpfloat::set_groundsize(set.cast()) }
473 }
474
475 unsafe fn set_member(elem: c_long, set: *mut libc::c_ulong) -> i32 {
476 unsafe { sys::gmpfloat::set_member(elem, set.cast()) }
477 }
478
479 unsafe fn set_free(set: *mut libc::c_ulong) {
480 unsafe {
481 sys::gmpfloat::set_free(set.cast());
482 }
483 }
484
485 unsafe fn dd_matrix2poly(matrix: *mut c_void, err: *mut u32) -> *mut c_void {
486 unsafe { sys::gmpfloat::dd_DDMatrix2Poly(matrix.cast(), err.cast()).cast() }
487 }
488
489 unsafe fn dd_free_polyhedra(poly: *mut c_void) {
490 unsafe {
491 sys::gmpfloat::dd_FreePolyhedra(poly.cast());
492 }
493 }
494
495 unsafe fn dd_copy_inequalities(poly: *mut c_void) -> *mut c_void {
496 unsafe { sys::gmpfloat::dd_CopyInequalities(poly.cast()).cast() }
497 }
498
499 unsafe fn dd_copy_generators(poly: *mut c_void) -> *mut c_void {
500 unsafe { sys::gmpfloat::dd_CopyGenerators(poly.cast()).cast() }
501 }
502
503 unsafe fn dd_copy_adjacency(poly: *mut c_void) -> *mut c_void {
504 unsafe { sys::gmpfloat::dd_CopyAdjacency(poly.cast()).cast() }
505 }
506
507 unsafe fn dd_copy_input_adjacency(poly: *mut c_void) -> *mut c_void {
508 unsafe { sys::gmpfloat::dd_CopyInputAdjacency(poly.cast()).cast() }
509 }
510
511 unsafe fn dd_copy_incidence(poly: *mut c_void) -> *mut c_void {
512 unsafe { sys::gmpfloat::dd_CopyIncidence(poly.cast()).cast() }
513 }
514
515 unsafe fn dd_copy_input_incidence(poly: *mut c_void) -> *mut c_void {
516 unsafe { sys::gmpfloat::dd_CopyInputIncidence(poly.cast()).cast() }
517 }
518
519 unsafe fn dd_append_matrix2poly(poly: *mut *mut c_void, rows: *mut c_void) -> i32 {
520 unsafe { sys::gmpfloat::dd_AppendMatrix2Poly(poly.cast(), rows.cast()) }
521 }
522
523 unsafe fn dd_free_set_family(family: *mut c_void) {
524 unsafe {
525 sys::gmpfloat::dd_FreeSetFamily(family.cast());
526 }
527 }
528
529 unsafe fn dd_matrix2lp(matrix: *mut c_void, err: *mut u32) -> *mut c_void {
530 unsafe { sys::gmpfloat::dd_Matrix2LP(matrix.cast(), err.cast()).cast() }
531 }
532
533 unsafe fn dd_free_lp_data(lp: *mut c_void) {
534 unsafe {
535 sys::gmpfloat::dd_FreeLPData(lp.cast());
536 }
537 }
538
539 unsafe fn dd_lp_solve_dual_simplex(lp: *mut c_void, err: *mut u32) -> i32 {
540 unsafe {
541 sys::gmpfloat::dd_LPSolve(
542 lp.cast(),
543 sys::gmpfloat::dd_LPSolverType_dd_DualSimplex,
544 err.cast(),
545 )
546 }
547 }
548
549 unsafe fn lp_status_raw(lp: *mut c_void) -> u32 {
550 unsafe { (*lp.cast::<sys::gmpfloat::dd_lpdata>()).LPS }
551 }
552
553 unsafe fn dd_copy_lp_solution(lp: *mut c_void) -> *mut c_void {
554 unsafe { sys::gmpfloat::dd_CopyLPSolution(lp.cast()).cast() }
555 }
556
557 unsafe fn dd_free_lp_solution(sol: *mut c_void) {
558 unsafe {
559 sys::gmpfloat::dd_FreeLPSolution(sol.cast());
560 }
561 }
562
563 unsafe fn lp_solution_optvalue_ptr(sol: *mut c_void) -> *const c_void {
564 unsafe {
565 let sol = sol.cast::<sys::gmpfloat::dd_lpsolution>();
566 (&(*sol).optvalue as *const sys::gmpfloat::mytype).cast()
567 }
568 }
569
570 unsafe fn write_mytype_real(target: *mut c_void, value: f64) {
571 unsafe {
572 sys::gmpfloat::__gmpf_set_d(target.cast(), value);
573 }
574 }
575
576 unsafe fn write_mytype_int(target: *mut c_void, value: c_long) {
577 unsafe {
578 sys::gmpfloat::__gmpf_set_si(target.cast(), value);
579 }
580 }
581
582 unsafe fn read_mytype_real(source: *const c_void) -> f64 {
583 unsafe { sys::gmpfloat::__gmpf_get_d(source.cast()) }
584 }
585
586 unsafe fn write_mytype(target: *mut c_void, value: &Self) {
587 unsafe {
588 sys::gmpfloat::__gmpf_set(target.cast(), value.inner.as_ptr());
589 }
590 }
591
592 unsafe fn read_mytype(source: *const c_void) -> Self {
593 unsafe {
594 Self::ensure_initialized();
595 let mut inner = MaybeUninit::<sys::gmpfloat::mytype>::uninit();
596 sys::gmpfloat::__gmpf_init(inner.as_mut_ptr().cast());
597 sys::gmpfloat::__gmpf_set(inner.as_mut_ptr().cast(), source.cast());
598 CddFloat {
599 inner: inner.assume_init(),
600 }
601 }
602 }
603}
604
605#[cfg(feature = "gmprational")]
606impl sealed::Sealed for CddRational {}
607
608#[cfg(feature = "gmprational")]
609impl CddNumber for CddRational {
610 const MYTYPE_SIZE: usize = mem::size_of::<sys::gmprational::mytype>();
611 const DEFAULT_NUMBER_TYPE: NumberType = NumberType::Rational;
612
613 fn ensure_initialized() {
614 static INIT: Once = Once::new();
615 INIT.call_once(|| unsafe {
616 sys::gmprational::dd_set_global_constants();
617 });
618 }
619
620 fn dd_no_error() -> u32 {
621 sys::gmprational::dd_ErrorType_dd_NoError
622 }
623
624 unsafe fn dd_create_matrix(rows: c_long, cols: c_long) -> *mut c_void {
625 unsafe { sys::gmprational::dd_CreateMatrix(rows, cols).cast() }
626 }
627
628 unsafe fn dd_copy_matrix(matrix: *mut c_void) -> *mut c_void {
629 unsafe { sys::gmprational::dd_CopyMatrix(matrix.cast()).cast() }
630 }
631
632 unsafe fn dd_free_matrix(matrix: *mut c_void) {
633 unsafe {
634 sys::gmprational::dd_FreeMatrix(matrix.cast());
635 }
636 }
637
638 unsafe fn dd_matrix_append_to(dst: *mut *mut c_void, src: *mut c_void) -> i32 {
639 unsafe { sys::gmprational::dd_MatrixAppendTo(dst.cast(), src.cast()) }
640 }
641
642 unsafe fn dd_append_matrix(a: *mut c_void, b: *mut c_void) -> *mut c_void {
643 unsafe { sys::gmprational::dd_AppendMatrix(a.cast(), b.cast()).cast() }
644 }
645
646 unsafe fn dd_matrix_row_remove(matrix: *mut *mut c_void, row: c_long) -> i32 {
647 unsafe { sys::gmprational::dd_MatrixRowRemove(matrix.cast(), row) }
648 }
649
650 unsafe fn dd_initialize_arow(cols: c_long, out: *mut *mut c_void) {
651 unsafe {
652 sys::gmprational::dd_InitializeArow(cols, out.cast());
653 }
654 }
655
656 unsafe fn dd_free_arow(cols: c_long, arow: *mut c_void) {
657 unsafe {
658 sys::gmprational::dd_FreeArow(cols, arow.cast());
659 }
660 }
661
662 unsafe fn dd_redundant(
663 matrix: *mut c_void,
664 row: c_long,
665 cert: *mut c_void,
666 err: *mut u32,
667 ) -> i32 {
668 unsafe { sys::gmprational::dd_Redundant(matrix.cast(), row, cert.cast(), err.cast()) }
669 }
670
671 unsafe fn dd_redundant_rows(matrix: *mut c_void, err: *mut u32) -> *mut libc::c_ulong {
672 unsafe { sys::gmprational::dd_RedundantRows(matrix.cast(), err.cast()).cast() }
673 }
674
675 unsafe fn dd_matrix_canonicalize(
676 matrix: *mut *mut c_void,
677 impl_lin: *mut *mut libc::c_ulong,
678 redset: *mut *mut libc::c_ulong,
679 newpos: *mut *mut c_long,
680 err: *mut u32,
681 ) -> i32 {
682 unsafe {
683 sys::gmprational::dd_MatrixCanonicalize(
684 matrix.cast(),
685 impl_lin.cast(),
686 redset.cast(),
687 newpos.cast(),
688 err.cast(),
689 )
690 }
691 }
692
693 unsafe fn set_groundsize(set: *mut libc::c_ulong) -> c_long {
694 unsafe { sys::gmprational::set_groundsize(set.cast()) }
695 }
696
697 unsafe fn set_member(elem: c_long, set: *mut libc::c_ulong) -> i32 {
698 unsafe { sys::gmprational::set_member(elem, set.cast()) }
699 }
700
701 unsafe fn set_free(set: *mut libc::c_ulong) {
702 unsafe {
703 sys::gmprational::set_free(set.cast());
704 }
705 }
706
707 unsafe fn dd_matrix2poly(matrix: *mut c_void, err: *mut u32) -> *mut c_void {
708 unsafe { sys::gmprational::dd_DDMatrix2Poly(matrix.cast(), err.cast()).cast() }
709 }
710
711 unsafe fn dd_free_polyhedra(poly: *mut c_void) {
712 unsafe {
713 sys::gmprational::dd_FreePolyhedra(poly.cast());
714 }
715 }
716
717 unsafe fn dd_copy_inequalities(poly: *mut c_void) -> *mut c_void {
718 unsafe { sys::gmprational::dd_CopyInequalities(poly.cast()).cast() }
719 }
720
721 unsafe fn dd_copy_generators(poly: *mut c_void) -> *mut c_void {
722 unsafe { sys::gmprational::dd_CopyGenerators(poly.cast()).cast() }
723 }
724
725 unsafe fn dd_copy_adjacency(poly: *mut c_void) -> *mut c_void {
726 unsafe { sys::gmprational::dd_CopyAdjacency(poly.cast()).cast() }
727 }
728
729 unsafe fn dd_copy_input_adjacency(poly: *mut c_void) -> *mut c_void {
730 unsafe { sys::gmprational::dd_CopyInputAdjacency(poly.cast()).cast() }
731 }
732
733 unsafe fn dd_copy_incidence(poly: *mut c_void) -> *mut c_void {
734 unsafe { sys::gmprational::dd_CopyIncidence(poly.cast()).cast() }
735 }
736
737 unsafe fn dd_copy_input_incidence(poly: *mut c_void) -> *mut c_void {
738 unsafe { sys::gmprational::dd_CopyInputIncidence(poly.cast()).cast() }
739 }
740
741 unsafe fn dd_append_matrix2poly(poly: *mut *mut c_void, rows: *mut c_void) -> i32 {
742 unsafe { sys::gmprational::dd_AppendMatrix2Poly(poly.cast(), rows.cast()) }
743 }
744
745 unsafe fn dd_free_set_family(family: *mut c_void) {
746 unsafe {
747 sys::gmprational::dd_FreeSetFamily(family.cast());
748 }
749 }
750
751 unsafe fn dd_matrix2lp(matrix: *mut c_void, err: *mut u32) -> *mut c_void {
752 unsafe { sys::gmprational::dd_Matrix2LP(matrix.cast(), err.cast()).cast() }
753 }
754
755 unsafe fn dd_free_lp_data(lp: *mut c_void) {
756 unsafe {
757 sys::gmprational::dd_FreeLPData(lp.cast());
758 }
759 }
760
761 unsafe fn dd_lp_solve_dual_simplex(lp: *mut c_void, err: *mut u32) -> i32 {
762 unsafe {
763 sys::gmprational::dd_LPSolve(
764 lp.cast(),
765 sys::gmprational::dd_LPSolverType_dd_DualSimplex,
766 err.cast(),
767 )
768 }
769 }
770
771 unsafe fn lp_status_raw(lp: *mut c_void) -> u32 {
772 unsafe { (*lp.cast::<sys::gmprational::dd_lpdata>()).LPS }
773 }
774
775 unsafe fn dd_copy_lp_solution(lp: *mut c_void) -> *mut c_void {
776 unsafe { sys::gmprational::dd_CopyLPSolution(lp.cast()).cast() }
777 }
778
779 unsafe fn dd_free_lp_solution(sol: *mut c_void) {
780 unsafe {
781 sys::gmprational::dd_FreeLPSolution(sol.cast());
782 }
783 }
784
785 unsafe fn lp_solution_optvalue_ptr(sol: *mut c_void) -> *const c_void {
786 unsafe {
787 let sol = sol.cast::<sys::gmprational::dd_lpsolution>();
788 (&(*sol).optvalue as *const sys::gmprational::mytype).cast()
789 }
790 }
791
792 unsafe fn write_mytype_real(target: *mut c_void, value: f64) {
793 unsafe {
794 sys::gmprational::__gmpq_set_d(target.cast(), value);
795 }
796 }
797
798 unsafe fn write_mytype_int(target: *mut c_void, value: c_long) {
799 unsafe {
800 sys::gmprational::__gmpq_set_si(target.cast(), value, 1);
801 }
802 }
803
804 unsafe fn read_mytype_real(source: *const c_void) -> f64 {
805 unsafe { sys::gmprational::__gmpq_get_d(source.cast()) }
806 }
807
808 unsafe fn write_mytype(target: *mut c_void, value: &Self) {
809 unsafe {
810 sys::gmprational::__gmpq_set(target.cast(), value.inner.as_ptr());
811 }
812 }
813
814 unsafe fn read_mytype(source: *const c_void) -> Self {
815 unsafe {
816 Self::ensure_initialized();
817 let mut inner = MaybeUninit::<sys::gmprational::mytype>::uninit();
818 sys::gmprational::__gmpq_init(inner.as_mut_ptr().cast());
819 sys::gmprational::__gmpq_set(inner.as_mut_ptr().cast(), source.cast());
820 CddRational {
821 inner: inner.assume_init(),
822 }
823 }
824 }
825}
826
827#[cfg(feature = "gmp")]
828impl CddFloat {
829 pub fn to_f64(&self) -> f64 {
830 <Self as CddNumber>::ensure_initialized();
831 unsafe { sys::gmpfloat::__gmpf_get_d(self.inner.as_ptr()) }
832 }
833}
834
835#[cfg(feature = "gmp")]
836impl Clone for CddFloat {
837 fn clone(&self) -> Self {
838 <Self as CddNumber>::ensure_initialized();
839 unsafe {
840 let mut inner = MaybeUninit::<sys::gmpfloat::mytype>::uninit();
841 sys::gmpfloat::__gmpf_init(inner.as_mut_ptr().cast());
842 sys::gmpfloat::__gmpf_set(inner.as_mut_ptr().cast(), self.inner.as_ptr());
843 CddFloat {
844 inner: inner.assume_init(),
845 }
846 }
847 }
848}
849
850#[cfg(feature = "gmp")]
851impl Drop for CddFloat {
852 fn drop(&mut self) {
853 <Self as CddNumber>::ensure_initialized();
854 unsafe {
855 sys::gmpfloat::__gmpf_clear(self.inner.as_mut_ptr());
856 }
857 }
858}
859
860#[cfg(feature = "gmp")]
861impl From<f64> for CddFloat {
862 fn from(value: f64) -> Self {
863 <Self as CddNumber>::ensure_initialized();
864 unsafe {
865 let mut inner = MaybeUninit::<sys::gmpfloat::mytype>::uninit();
866 sys::gmpfloat::__gmpf_init(inner.as_mut_ptr().cast());
867 sys::gmpfloat::__gmpf_set_d(inner.as_mut_ptr().cast(), value);
868 CddFloat {
869 inner: inner.assume_init(),
870 }
871 }
872 }
873}
874
875#[cfg(feature = "gmprational")]
876impl CddRational {
877 pub fn to_f64(&self) -> f64 {
878 <Self as CddNumber>::ensure_initialized();
879 unsafe { sys::gmprational::__gmpq_get_d(self.inner.as_ptr()) }
880 }
881}
882
883#[cfg(feature = "gmprational")]
884impl std::fmt::Display for CddRational {
885 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
886 use std::ffi::CStr;
887
888 <Self as CddNumber>::ensure_initialized();
889 unsafe {
890 let ptr = sys::gmprational::__gmpq_get_str(std::ptr::null_mut(), 10, self.inner.as_ptr());
891 if ptr.is_null() {
892 return Err(std::fmt::Error);
893 }
894 let s = CStr::from_ptr(ptr)
895 .to_str()
896 .map_err(|_| std::fmt::Error)?;
897 let result = f.write_str(s);
898 libc::free(ptr.cast());
899 result
900 }
901 }
902}
903
904#[cfg(feature = "gmprational")]
905impl Clone for CddRational {
906 fn clone(&self) -> Self {
907 <Self as CddNumber>::ensure_initialized();
908 unsafe {
909 let mut inner = MaybeUninit::<sys::gmprational::mytype>::uninit();
910 sys::gmprational::__gmpq_init(inner.as_mut_ptr().cast());
911 sys::gmprational::__gmpq_set(inner.as_mut_ptr().cast(), self.inner.as_ptr());
912 CddRational {
913 inner: inner.assume_init(),
914 }
915 }
916 }
917}
918
919#[cfg(feature = "gmprational")]
920impl Drop for CddRational {
921 fn drop(&mut self) {
922 <Self as CddNumber>::ensure_initialized();
923 unsafe {
924 sys::gmprational::__gmpq_clear(self.inner.as_mut_ptr());
925 }
926 }
927}
928
929#[cfg(feature = "gmprational")]
930impl From<f64> for CddRational {
931 fn from(value: f64) -> Self {
932 <Self as CddNumber>::ensure_initialized();
933 unsafe {
934 let mut inner = MaybeUninit::<sys::gmprational::mytype>::uninit();
935 sys::gmprational::__gmpq_init(inner.as_mut_ptr().cast());
936 sys::gmprational::__gmpq_set_d(inner.as_mut_ptr().cast(), value);
937 CddRational {
938 inner: inner.assume_init(),
939 }
940 }
941 }
942}