honeycomb_core/cmap/dim3/links/
mod.rs

1mod one;
2mod three;
3mod two;
4
5use crate::cmap::{CMap3, DartIdType, LinkError};
6use crate::geometry::CoordsFloat;
7use crate::stm::{Transaction, TransactionClosureResult};
8
9/// # **Link operations**
10impl<T: CoordsFloat> CMap3<T> {
11    /// `I`-link operator.
12    ///
13    /// # Description
14    ///
15    /// This operation corresponds to coherently linking two darts via their *β* images. Unlike
16    /// sewing, this does not alter associated attributes. For a thorough explanation of this
17    /// operation, its hypothesis & consequences, refer to the [user guide][UG].
18    ///
19    /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
20    ///
21    /// # Arguments
22    ///
23    /// - `const I: u8` -- Link dimension.
24    /// - `t: &mut Transaction` -- Transaction associated to the operation.
25    /// - `lhs_dart_id: DartIdType` -- First dart ID.
26    /// - `rhs_dart_id: DartIdType` -- Second dart ID.
27    ///
28    /// # Errors
29    ///
30    /// This method should be called in a transactional context. The `Result` is then used to
31    /// validate the transaction; Errors should not be processed manually, only processed via the
32    /// `?` operator. The policy in case of failure can be defined when creating the transaction,
33    /// using `Transaction::with_control`.
34    ///
35    /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
36    /// more detail about the latter.
37    ///
38    /// # Panics
39    ///
40    /// The method may panic if:
41    /// - `I >= 4` or `I == 0`,
42    /// - the two darts are not `I`-linkable.
43    pub fn link<const I: u8>(
44        &self,
45        t: &mut Transaction,
46        lhs_dart_id: DartIdType,
47        rhs_dart_id: DartIdType,
48    ) -> TransactionClosureResult<(), LinkError> {
49        // these assertions + match on a const are optimized away
50        assert!(I < 4);
51        assert_ne!(I, 0);
52        match I {
53            1 => self.one_link(t, lhs_dart_id, rhs_dart_id),
54            2 => self.two_link(t, lhs_dart_id, rhs_dart_id),
55            3 => self.three_link(t, lhs_dart_id, rhs_dart_id),
56            _ => unreachable!(),
57        }
58    }
59
60    /// `I`-unlink operator.
61    ///
62    /// # Description
63    ///
64    /// This operation corresponds to unlinking two darts by resetting their *β* images. Unlike
65    /// unsewing, this does not alter associated attributes. For a thorough explanation of this
66    /// operation, its hypothesis & consequences, refer to the [user guide][UG].
67    ///
68    /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
69    ///
70    /// # Arguments
71    ///
72    /// - `const I: u8` -- Unlink dimension.
73    /// - `t: &mut Transaction` -- Transaction associated to the operation.
74    /// - `lhs_dart_id: DartIdType` -- First dart ID.
75    ///
76    /// The second dart ID is fetched using `I` and `lhs_dart_id`.
77    ///
78    /// # Errors
79    ///
80    /// This method should be called in a transactional context. The `Result` is then used to
81    /// validate the transaction; Errors should not be processed manually, only processed via the
82    /// `?` operator. The policy in case of failure can be defined when creating the transaction,
83    /// using `Transaction::with_control`.
84    ///
85    /// # Panics
86    ///
87    /// The method may panic if:
88    /// - `I >= 4` or `I == 0`,
89    /// - `lhs_dart_id` is already `I`-free.
90    pub fn unlink<const I: u8>(
91        &self,
92        t: &mut Transaction,
93        lhs_dart_id: DartIdType,
94    ) -> TransactionClosureResult<(), LinkError> {
95        // these assertions + match on a const are optimized away
96        assert!(I < 4);
97        assert_ne!(I, 0);
98        match I {
99            1 => self.one_unlink(t, lhs_dart_id),
100            2 => self.two_unlink(t, lhs_dart_id),
101            3 => self.three_unlink(t, lhs_dart_id),
102            _ => unreachable!(),
103        }
104    }
105
106    /// `I`-link operator.
107    ///
108    /// This variant is equivalent to [`link`][Self::link], but internally uses a transaction that
109    /// will be retried until validated.
110    ///
111    /// # Errors
112    ///
113    /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
114    /// more detail about the latter.
115    ///
116    /// # Panics
117    ///
118    /// The method may panic if:
119    /// - `I >= 4` or `I == 0`,
120    /// - `lhs_dart_id` is already `I`-free.
121    pub fn force_link<const I: u8>(
122        &self,
123        lhs_dart_id: DartIdType,
124        rhs_dart_id: DartIdType,
125    ) -> Result<(), LinkError> {
126        // these assertions + match on a const are optimized away
127        assert!(I < 4);
128        assert_ne!(I, 0);
129        match I {
130            1 => self.force_one_link(lhs_dart_id, rhs_dart_id),
131            2 => self.force_two_link(lhs_dart_id, rhs_dart_id),
132            3 => self.force_three_link(lhs_dart_id, rhs_dart_id),
133            _ => unreachable!(),
134        }
135    }
136
137    /// `I`-unlink operator.
138    ///
139    /// This variant is equivalent to [`unlink`][Self::unlink], but internally uses a transaction
140    /// that will be retried until validated.
141    ///
142    /// # Errors
143    ///
144    /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
145    /// more detail about the latter.
146    ///
147    /// # Panics
148    ///
149    /// The method may panic if:
150    /// - `I >= 4` or `I == 0`,
151    /// - `lhs_dart_id` is already `I`-free.
152    pub fn force_unlink<const I: u8>(&self, lhs_dart_id: DartIdType) -> Result<(), LinkError> {
153        // these assertions + match on a const are optimized away
154        assert!(I < 4);
155        assert_ne!(I, 0);
156        match I {
157            1 => self.force_one_unlink(lhs_dart_id),
158            2 => self.force_two_unlink(lhs_dart_id),
159            3 => self.force_three_unlink(lhs_dart_id),
160            _ => unreachable!(),
161        }
162    }
163}