Skip to content

Commit aef6aef

Browse files
Merge pull request #491 from qfall/unsafe_setters
Add `unsafe` Setters
2 parents 329966f + 30920a2 commit aef6aef

File tree

15 files changed

+583
-23
lines changed

15 files changed

+583
-23
lines changed

src/integer/mat_poly_over_z/unsafe_functions.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@
1010
//! [FLINT](https://flintlib.org/) structs. Therefore, they require to be unsafe.
1111
1212
use super::MatPolyOverZ;
13-
use crate::macros::unsafe_passthrough::unsafe_getter;
14-
use flint_sys::fmpz_poly_mat::fmpz_poly_mat_struct;
13+
use crate::macros::unsafe_passthrough::{unsafe_getter, unsafe_setter};
14+
use flint_sys::fmpz_poly_mat::{fmpz_poly_mat_clear, fmpz_poly_mat_struct};
1515

1616
unsafe_getter!(MatPolyOverZ, matrix, fmpz_poly_mat_struct);
17+
unsafe_setter!(
18+
MatPolyOverZ,
19+
matrix,
20+
fmpz_poly_mat_struct,
21+
fmpz_poly_mat_clear
22+
);
1723

1824
#[cfg(test)]
1925
mod test_get_fmpz_poly_mat_struct {
@@ -40,3 +46,29 @@ mod test_get_fmpz_poly_mat_struct {
4046
assert_eq!(poly, mat.get_entry(0, 0).unwrap());
4147
}
4248
}
49+
50+
#[cfg(test)]
51+
mod test_set_fmpz_poly_mat_struct {
52+
use super::MatPolyOverZ;
53+
use crate::{integer::PolyOverZ, traits::MatrixGetEntry};
54+
use flint_sys::fmpz_poly_mat::fmpz_poly_mat_init;
55+
use std::{mem::MaybeUninit, str::FromStr};
56+
57+
/// Checks availability of the setter for [`MatPolyOverZ::matrix`]
58+
/// and its ability to modify [`MatPolyOverZ`].
59+
#[test]
60+
#[allow(unused_mut)]
61+
fn availability_and_modification() {
62+
let mut mat = MatPolyOverZ::from_str("[[1 1]]").unwrap();
63+
let mut flint_struct = MaybeUninit::uninit();
64+
let flint_struct = unsafe {
65+
fmpz_poly_mat_init(flint_struct.as_mut_ptr(), 1, 1);
66+
flint_struct.assume_init()
67+
};
68+
let poly = PolyOverZ::default();
69+
70+
unsafe { mat.set_fmpz_poly_mat_struct(flint_struct) };
71+
72+
assert_eq!(poly, mat.get_entry(0, 0).unwrap());
73+
}
74+
}

src/integer/mat_z/unsafe_functions.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
//! [FLINT](https://flintlib.org/) structs. Therefore, they require to be unsafe.
1111
1212
use super::MatZ;
13-
use crate::macros::unsafe_passthrough::unsafe_getter;
14-
use flint_sys::fmpz_mat::fmpz_mat_struct;
13+
use crate::macros::unsafe_passthrough::{unsafe_getter, unsafe_setter};
14+
use flint_sys::fmpz_mat::{fmpz_mat_clear, fmpz_mat_struct};
1515

1616
unsafe_getter!(MatZ, matrix, fmpz_mat_struct);
17+
unsafe_setter!(MatZ, matrix, fmpz_mat_struct, fmpz_mat_clear);
1718

1819
#[cfg(test)]
1920
mod test_get_fmpz_mat_struct {
@@ -42,3 +43,28 @@ mod test_get_fmpz_mat_struct {
4243
assert_eq!(Z::from(2), mat.get_entry(0, 0).unwrap());
4344
}
4445
}
46+
47+
#[cfg(test)]
48+
mod test_set_fmpz_mat_struct {
49+
use super::MatZ;
50+
use crate::{integer::Z, traits::MatrixGetEntry};
51+
use flint_sys::fmpz_mat::fmpz_mat_init;
52+
use std::{mem::MaybeUninit, str::FromStr};
53+
54+
/// Checks availability of the setter for [`MatZ::matrix`]
55+
/// and its ability to modify [`MatZ`].
56+
#[test]
57+
#[allow(unused_mut)]
58+
fn availability_and_modification() {
59+
let mut mat = MatZ::from_str("[[1]]").unwrap();
60+
let mut flint_struct = MaybeUninit::uninit();
61+
let flint_struct = unsafe {
62+
fmpz_mat_init(flint_struct.as_mut_ptr(), 1, 1);
63+
flint_struct.assume_init()
64+
};
65+
66+
unsafe { mat.set_fmpz_mat_struct(flint_struct) };
67+
68+
assert_eq!(Z::from(0), mat.get_entry(0, 0).unwrap());
69+
}
70+
}

src/integer/poly_over_z/unsafe_functions.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
//! [FLINT](https://flintlib.org/) structs. Therefore, they require to be unsafe.
1111
1212
use super::PolyOverZ;
13-
use crate::macros::unsafe_passthrough::unsafe_getter;
14-
use flint_sys::fmpz_poly::fmpz_poly_struct;
13+
use crate::macros::unsafe_passthrough::{unsafe_getter, unsafe_setter};
14+
use flint_sys::fmpz_poly::{fmpz_poly_clear, fmpz_poly_struct};
1515

1616
unsafe_getter!(PolyOverZ, poly, fmpz_poly_struct);
17+
unsafe_setter!(PolyOverZ, poly, fmpz_poly_struct, fmpz_poly_clear);
1718

1819
#[cfg(test)]
1920
mod test_get_fmpz_poly_struct {
@@ -34,3 +35,27 @@ mod test_get_fmpz_poly_struct {
3435
assert_eq!(PolyOverZ::from(2), poly);
3536
}
3637
}
38+
39+
#[cfg(test)]
40+
mod test_set_fmpz_poly_struct {
41+
use super::PolyOverZ;
42+
use flint_sys::fmpz_poly::fmpz_poly_init;
43+
use std::mem::MaybeUninit;
44+
45+
/// Checks availability of the setter for [`PolyOverZ::poly`]
46+
/// and its ability to modify [`PolyOverZ`].
47+
#[test]
48+
#[allow(unused_mut)]
49+
fn availability_and_modification() {
50+
let mut poly = PolyOverZ::from(1);
51+
let mut flint_struct = MaybeUninit::uninit();
52+
let flint_struct = unsafe {
53+
fmpz_poly_init(flint_struct.as_mut_ptr());
54+
flint_struct.assume_init()
55+
};
56+
57+
unsafe { poly.set_fmpz_poly_struct(flint_struct) };
58+
59+
assert_eq!(PolyOverZ::default(), poly);
60+
}
61+
}

src/integer/z/unsafe_functions.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99
//! This module contains public functions that enable access to underlying
1010
//! [FLINT](https://flintlib.org/) structs. Therefore, they require to be unsafe.
1111
12-
use crate::{integer::Z, macros::unsafe_passthrough::unsafe_getter};
13-
use flint_sys::fmpz::fmpz;
12+
use crate::{
13+
integer::Z,
14+
macros::unsafe_passthrough::{unsafe_getter, unsafe_setter},
15+
};
16+
use flint_sys::fmpz::{fmpz, fmpz_clear};
1417

1518
unsafe_getter!(Z, value, fmpz);
19+
unsafe_setter!(Z, value, fmpz, fmpz_clear);
1620

1721
#[cfg(test)]
1822
mod test_get_fmpz {
@@ -32,3 +36,22 @@ mod test_get_fmpz {
3236
assert_eq!(Z::from(2), integer);
3337
}
3438
}
39+
40+
#[cfg(test)]
41+
mod test_set_fmpz {
42+
use super::Z;
43+
use flint_sys::fmpz::fmpz;
44+
45+
/// Checks availability of the setter for [`Z::value`]
46+
/// and its ability to modify [`Z`].
47+
#[test]
48+
#[allow(unused_mut)]
49+
fn availability_and_modification() {
50+
let mut integer = Z::from(1);
51+
let b = fmpz(2);
52+
53+
unsafe { integer.set_fmpz(b) };
54+
55+
assert_eq!(Z::from(2), integer);
56+
}
57+
}

src/integer_mod_q/mat_polynomial_ring_zq/unsafe_functions.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! [FLINT](https://flintlib.org/) structs. Therefore, they require to be unsafe.
1111
1212
use super::MatPolynomialRingZq;
13-
use crate::macros::unsafe_passthrough::unsafe_getter_indirect;
13+
use crate::macros::unsafe_passthrough::{unsafe_getter_indirect, unsafe_setter_indirect};
1414
use flint_sys::{fmpz_poly_mat::fmpz_poly_mat_struct, fq::fq_ctx_struct};
1515

1616
unsafe_getter_indirect!(
@@ -25,3 +25,16 @@ unsafe_getter_indirect!(
2525
get_fq_ctx_struct,
2626
fq_ctx_struct
2727
);
28+
29+
unsafe_setter_indirect!(
30+
MatPolynomialRingZq,
31+
matrix,
32+
set_fmpz_poly_mat_struct,
33+
fmpz_poly_mat_struct
34+
);
35+
unsafe_setter_indirect!(
36+
MatPolynomialRingZq,
37+
modulus,
38+
set_fq_ctx_struct,
39+
fq_ctx_struct
40+
);

src/integer_mod_q/mat_zq/unsafe_functions.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,20 @@
1010
//! [FLINT](https://flintlib.org/) structs. Therefore, they require to be unsafe.
1111
1212
use super::MatZq;
13-
use crate::macros::unsafe_passthrough::{unsafe_getter, unsafe_getter_indirect};
14-
use flint_sys::{fmpz_mod::fmpz_mod_ctx, fmpz_mod_mat::fmpz_mod_mat_struct};
13+
use crate::macros::unsafe_passthrough::{
14+
unsafe_getter, unsafe_getter_indirect, unsafe_setter, unsafe_setter_indirect,
15+
};
16+
use flint_sys::{
17+
fmpz_mod::fmpz_mod_ctx,
18+
fmpz_mod_mat::{fmpz_mod_mat_clear, fmpz_mod_mat_struct},
19+
};
1520

1621
unsafe_getter!(MatZq, matrix, fmpz_mod_mat_struct);
1722
unsafe_getter_indirect!(MatZq, modulus, get_fmpz_mod_ctx, fmpz_mod_ctx);
1823

24+
unsafe_setter!(MatZq, matrix, fmpz_mod_mat_struct, fmpz_mod_mat_clear);
25+
unsafe_setter_indirect!(MatZq, modulus, set_fmpz_mod_ctx, fmpz_mod_ctx);
26+
1927
#[cfg(test)]
2028
mod test_get_fmpz_mod_mat_struct {
2129
use super::MatZq;
@@ -35,3 +43,28 @@ mod test_get_fmpz_mod_mat_struct {
3543
assert_eq!(MatZq::from_str("[[3]] mod 5").unwrap(), mat);
3644
}
3745
}
46+
47+
#[cfg(test)]
48+
mod test_set_fmpz_mod_mat_struct {
49+
use super::MatZq;
50+
use flint_sys::{fmpz::fmpz, fmpz_mod_mat::fmpz_mod_mat_init};
51+
use std::{mem::MaybeUninit, str::FromStr};
52+
53+
/// Checks availability of the setter for [`MatZq::matrix`]
54+
/// and its ability to modify [`MatZq`].
55+
#[test]
56+
fn availability_and_modification() {
57+
let mut mat = MatZq::from_str("[[3]] mod 7").unwrap();
58+
let mut flint_struct = MaybeUninit::uninit();
59+
let flint_struct = unsafe {
60+
fmpz_mod_mat_init(flint_struct.as_mut_ptr(), 1, 1, &fmpz(7));
61+
flint_struct.assume_init()
62+
};
63+
64+
unsafe {
65+
mat.set_fmpz_mod_mat_struct(flint_struct);
66+
};
67+
68+
assert_eq!(MatZq::new(1, 1, 7), mat);
69+
}
70+
}

src/integer_mod_q/modulus/unsafe_functions.rs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,52 @@
1111
1212
use super::Modulus;
1313
use crate::macros::unsafe_passthrough::unsafe_getter_mod;
14-
use flint_sys::fmpz_mod::fmpz_mod_ctx;
14+
use flint_sys::fmpz_mod::{fmpz_mod_ctx, fmpz_mod_ctx_clear};
1515

1616
unsafe_getter_mod!(Modulus, modulus, fmpz_mod_ctx);
1717

18+
impl Modulus {
19+
/// Sets a mutable reference to the field `modulus` of type [`Modulus`] to a given `fmpz_mod_ctx`.
20+
///
21+
/// Parameters:
22+
/// - `flint_struct`: value to set the attribute to
23+
///
24+
/// **WARNING:** The set struct is part of [`flint_sys`].
25+
/// Any changes to this object are unsafe and may introduce memory leaks.
26+
/// Please be aware that most moduli are shared across multiple instances and all
27+
/// modifications of this struct will affect any other instance with a reference to this object.
28+
///
29+
/// This function is a passthrough to enable users of this library to use [`flint_sys`]
30+
/// and with that [FLINT](https://flintlib.org/) functions that might not be covered in our library yet.
31+
/// If this is the case, please consider contributing to this open-source project
32+
/// by opening a Pull Request at [qfall_math](https://github.com/qfall/math)
33+
/// to provide this feature in the future.
34+
///
35+
/// # Safety
36+
/// Ensure that the old `modulus` does not share any memory with any moduli
37+
/// that might be used in the future. The memory of the old `modulus` is freed
38+
/// using this function.
39+
///
40+
/// Any [`flint_sys`] struct and function is part of a FFI to the C-library `FLINT`.
41+
/// As `FLINT` is a C-library, it does not provide all memory safety features
42+
/// that Rust and our Wrapper provide.
43+
/// Thus, using functions of [`flint_sys`] can introduce memory leaks.
44+
pub unsafe fn set_fmpz_mod_ctx(&mut self, flint_struct: fmpz_mod_ctx) {
45+
let modulus = std::rc::Rc::<fmpz_mod_ctx>::get_mut(&mut self.modulus).unwrap();
46+
47+
// free memory of old modulus before new values of modulus are copied
48+
unsafe { fmpz_mod_ctx_clear(modulus) };
49+
50+
modulus.add_fxn = flint_struct.add_fxn;
51+
modulus.mod_ = flint_struct.mod_;
52+
modulus.mul_fxn = flint_struct.mul_fxn;
53+
modulus.n = flint_struct.n;
54+
modulus.n_limbs = flint_struct.n_limbs;
55+
modulus.ninv_limbs = flint_struct.ninv_limbs;
56+
modulus.sub_fxn = flint_struct.sub_fxn;
57+
}
58+
}
59+
1860
#[cfg(test)]
1961
mod test_get_fmpz_mod_ctx {
2062
use super::Modulus;
@@ -33,3 +75,28 @@ mod test_get_fmpz_mod_ctx {
3375
assert_eq!(Modulus::from(2), modulus);
3476
}
3577
}
78+
79+
#[cfg(test)]
80+
mod test_set_fmpz_mod_ctx {
81+
use super::Modulus;
82+
use flint_sys::{fmpz::fmpz, fmpz_mod::fmpz_mod_ctx_init};
83+
use std::mem::MaybeUninit;
84+
85+
/// Checks availability of the setter for [`Modulus::modulus`]
86+
/// and its ability to modify [`Modulus`].
87+
#[test]
88+
#[allow(unused_mut)]
89+
fn availability_and_modification() {
90+
let mut modulus = Modulus::from(3);
91+
92+
let mut flint_struct = MaybeUninit::uninit();
93+
let mut flint_struct = unsafe {
94+
fmpz_mod_ctx_init(flint_struct.as_mut_ptr(), &fmpz(2));
95+
flint_struct.assume_init()
96+
};
97+
98+
unsafe { modulus.set_fmpz_mod_ctx(flint_struct) };
99+
100+
assert_eq!(Modulus::from(2), modulus);
101+
}
102+
}

0 commit comments

Comments
 (0)