qfall_math/rational/mat_q/
ownership.rs1use crate::traits::MatrixDimensions;
15
16use super::MatQ;
17use flint_sys::fmpq_mat::{fmpq_mat_clear, fmpq_mat_set};
18
19impl Clone for MatQ {
20 fn clone(&self) -> Self {
32 let mut mat = MatQ::new(self.get_num_rows(), self.get_num_columns());
33 unsafe {
34 fmpq_mat_set(&mut mat.matrix, &self.matrix);
35 }
36 mat
37 }
38}
39
40impl Drop for MatQ {
41 fn drop(&mut self) {
63 unsafe { fmpq_mat_clear(&mut self.matrix) }
64 }
65}
66
67#[cfg(test)]
69mod test_clone {
70 use super::MatQ;
71 use crate::{
72 rational::Q,
73 traits::{MatrixDimensions, MatrixGetEntry},
74 };
75 use std::str::FromStr;
76
77 #[test]
79 #[allow(clippy::redundant_clone)]
80 fn keep_alive() {
81 let a: MatQ;
82 let str_1 = "[[1/2, 2/3, 3/4],[3/1, 4/2, 5/4]]";
83 {
84 let b = MatQ::from_str(str_1).unwrap();
85
86 a = b.clone();
87 }
88
89 assert_eq!(a.get_num_rows(), 2);
90 assert_eq!(a.get_num_columns(), 3);
91
92 assert_eq!(a.get_entry(0, 0).unwrap(), Q::from((1, 2)));
93 assert_eq!(a.get_entry(0, 1).unwrap(), Q::from((2, 3)));
94 assert_eq!(a.get_entry(0, 2).unwrap(), Q::from((3, 4)));
95 assert_eq!(a.get_entry(1, 0).unwrap(), Q::from(3));
96 assert_eq!(a.get_entry(1, 1).unwrap(), Q::from((4, 2)));
97 assert_eq!(a.get_entry(1, 2).unwrap(), Q::from((5, 4)));
98 }
99
100 #[test]
102 fn entries_stored_separately() {
103 let a: MatQ;
104 let string = format!(
105 "[[{}/1, {}/2],[{}/3, {}/{}]]",
106 u64::MAX,
107 i64::MAX,
108 i64::MIN,
109 u64::MAX,
110 i64::MIN
111 );
112 let b = MatQ::from_str(&string).unwrap();
113
114 a = b.clone();
115
116 assert_ne!(
117 a.get_entry(0, 0).unwrap().value.num.0,
118 b.get_entry(0, 0).unwrap().value.num.0
119 );
120 assert_ne!(
121 a.get_entry(0, 1).unwrap().value.num.0,
122 b.get_entry(0, 1).unwrap().value.num.0
123 );
124 assert_ne!(
125 a.get_entry(1, 0).unwrap().value.num.0,
126 b.get_entry(1, 0).unwrap().value.num.0
127 );
128 assert_ne!(
129 a.get_entry(1, 1).unwrap().value.num.0,
130 b.get_entry(1, 1).unwrap().value.num.0
131 );
132 assert_ne!(
133 a.get_entry(1, 1).unwrap().value.den.0,
134 b.get_entry(1, 1).unwrap().value.den.0
135 );
136
137 assert_eq!(
138 a.get_entry(0, 1).unwrap().value.den.0,
139 b.get_entry(0, 1).unwrap().value.den.0
140 ); }
142}
143
144#[cfg(test)]
146mod test_drop {
147 use super::MatQ;
148 use crate::traits::MatrixGetEntry;
149 use std::collections::HashSet;
150 use std::str::FromStr;
151
152 fn create_and_drop_matq() -> (i64, i64, i64, i64) {
155 let string = format!("[[{}/{}, {}/{}]]", u64::MAX, i64::MIN, i64::MAX, 1);
156 let a = MatQ::from_str(&string).unwrap();
157
158 let storage_num_0 = a.get_entry(0, 0).unwrap().value.num.0;
159 let storage_num_1 = a.get_entry(0, 1).unwrap().value.num.0;
160 let storage_den_0 = a.get_entry(0, 0).unwrap().value.den.0;
161 let storage_den_1 = a.get_entry(0, 1).unwrap().value.den.0;
162
163 (storage_num_0, storage_num_1, storage_den_0, storage_den_1)
164 }
165
166 #[test]
168 fn free_memory() {
169 let mut set = HashSet::new();
170
171 for _i in 0..5 {
172 set.insert(create_and_drop_matq());
173 }
174
175 assert!(set.len() < 5);
176 }
177}