Skip to main content

qfall_math/integer_mod_q/modulus_polynomial_ring_zq/
ownership.rs

1// Copyright © 2023 Niklas Siemer
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module contains implementations of functions
10//! important for ownership such as the [`Clone`] and [`Drop`] trait.
11//!
12//! The explicit functions contain the documentation.
13
14use super::ModulusPolynomialRingZq;
15use std::rc::Rc;
16
17impl Clone for ModulusPolynomialRingZq {
18    /// Clones the given element and returns another cloned reference
19    /// to the [`fq_ctx_struct`](flint_sys::fq::fq_ctx_struct) element.
20    ///
21    /// # Examples
22    /// ```
23    /// use qfall_math::integer_mod_q::ModulusPolynomialRingZq;
24    /// use std::str::FromStr;
25    ///
26    /// // initialize X^2 + 1 mod 17, i.e. a polynomial with modulus
27    /// let a = ModulusPolynomialRingZq::from_str("3  1 0 1 mod 17").unwrap();
28    ///
29    ///
30    /// let b = a.clone();
31    /// ```
32    fn clone(&self) -> Self {
33        Self {
34            modulus: Rc::clone(&self.modulus),
35            ntt_basis: Rc::clone(&self.ntt_basis),
36            non_zero: self.non_zero.clone(),
37        }
38    }
39}
40
41/// Test that the [`Clone`] trait is correctly implemented.
42#[cfg(test)]
43mod test_clone {
44    use super::ModulusPolynomialRingZq;
45    use std::{rc::Rc, str::FromStr};
46
47    /// Check if new references/ cloned Moduli's increase the Rc counter
48    #[test]
49    fn references_increased() {
50        let a = ModulusPolynomialRingZq::from_str("3  1 0 1 mod 17").unwrap();
51        assert_eq!(Rc::strong_count(&a.modulus), 1);
52
53        let b = a.clone();
54
55        assert_eq!(Rc::strong_count(&a.modulus), 2);
56        assert_eq!(Rc::strong_count(&b.modulus), 2);
57
58        let c = b.clone();
59
60        assert_eq!(Rc::strong_count(&a.modulus), 3);
61        assert_eq!(Rc::strong_count(&b.modulus), 3);
62        assert_eq!(Rc::strong_count(&c.modulus), 3);
63    }
64}
65
66/// Test that the [`Drop`] trait is correctly implemented.
67#[cfg(test)]
68mod test_drop {
69    use super::ModulusPolynomialRingZq;
70    use std::{rc::Rc, str::FromStr};
71
72    /// Check whether references are decreased when dropping instances
73    #[test]
74    fn references_decreased() {
75        let a = ModulusPolynomialRingZq::from_str("3  1 0 1 mod 17").unwrap();
76        assert_eq!(Rc::strong_count(&a.modulus), 1);
77
78        {
79            let b = a.clone();
80
81            assert_eq!(Rc::strong_count(&a.modulus), 2);
82            assert_eq!(Rc::strong_count(&b.modulus), 2);
83        }
84
85        assert_eq!(Rc::strong_count(&a.modulus), 1);
86
87        let b = a.clone();
88        assert_eq!(Rc::strong_count(&a.modulus), 2);
89        assert_eq!(Rc::strong_count(&b.modulus), 2);
90
91        let c = b.clone();
92        assert_eq!(Rc::strong_count(&a.modulus), 3);
93        assert_eq!(Rc::strong_count(&b.modulus), 3);
94        assert_eq!(Rc::strong_count(&c.modulus), 3);
95
96        drop(a);
97        assert_eq!(Rc::strong_count(&b.modulus), 2);
98    }
99}