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 /// - `trans: &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 /// # Panics
36 ///
37 /// The method may panic if:
38 /// - `I >= 4` or `I == 0`,
39 /// - the two darts are not `I`-linkable.
40 pub fn link<const I: u8>(
41 &self,
42 trans: &mut Transaction,
43 lhs_dart_id: DartIdType,
44 rhs_dart_id: DartIdType,
45 ) -> TransactionClosureResult<(), LinkError> {
46 // these assertions + match on a const are optimized away
47 assert!(I < 4);
48 assert_ne!(I, 0);
49 match I {
50 1 => self.one_link(trans, lhs_dart_id, rhs_dart_id),
51 2 => self.two_link(trans, lhs_dart_id, rhs_dart_id),
52 3 => self.three_link(trans, lhs_dart_id, rhs_dart_id),
53 _ => unreachable!(),
54 }
55 }
56
57 /// `I`-unlink operator.
58 ///
59 /// # Description
60 ///
61 /// This operation corresponds to unlinking two darts by resetting their *β* images. Unlike
62 /// unsewing, this does not alter associated attributes. For a thorough explanation of this
63 /// operation, its hypothesis & consequences, refer to the [user guide][UG].
64 ///
65 /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
66 ///
67 /// # Arguments
68 ///
69 /// - `const I: u8` -- Unlink dimension.
70 /// - `trans: &mut Transaction` -- Transaction associated to the operation.
71 /// - `lhs_dart_id: DartIdType` -- First dart ID.
72 ///
73 /// The second dart ID is fetched using `I` and `lhs_dart_id`.
74 ///
75 /// # Errors
76 ///
77 /// This method should be called in a transactional context. The `Result` is then used to
78 /// validate the transaction; Errors should not be processed manually, only processed via the
79 /// `?` operator. The policy in case of failure can be defined when creating the transaction,
80 /// using `Transaction::with_control`.
81 ///
82 /// # Panics
83 ///
84 /// The method may panic if:
85 /// - `I >= 4` or `I == 0`,
86 /// - `lhs_dart_id` is already `I`-free.
87 pub fn unlink<const I: u8>(
88 &self,
89 trans: &mut Transaction,
90 lhs_dart_id: DartIdType,
91 ) -> TransactionClosureResult<(), LinkError> {
92 // these assertions + match on a const are optimized away
93 assert!(I < 4);
94 assert_ne!(I, 0);
95 match I {
96 1 => self.one_unlink(trans, lhs_dart_id),
97 2 => self.two_unlink(trans, lhs_dart_id),
98 3 => self.three_unlink(trans, lhs_dart_id),
99 _ => unreachable!(),
100 }
101 }
102
103 /// `I`-link operator.
104 ///
105 /// This variant is equivalent to [`link`][Self::link], but internally uses a transaction that
106 /// will be retried until validated.
107 pub fn force_link<const I: u8>(
108 &self,
109 lhs_dart_id: DartIdType,
110 rhs_dart_id: DartIdType,
111 ) -> Result<(), LinkError> {
112 // these assertions + match on a const are optimized away
113 assert!(I < 4);
114 assert_ne!(I, 0);
115 match I {
116 1 => self.force_one_link(lhs_dart_id, rhs_dart_id),
117 2 => self.force_two_link(lhs_dart_id, rhs_dart_id),
118 3 => self.force_three_link(lhs_dart_id, rhs_dart_id),
119 _ => unreachable!(),
120 }
121 }
122
123 /// `I`-unlink operator.
124 ///
125 /// This variant is equivalent to [`unlink`][Self::unlink], but internally uses a transaction
126 /// that will be retried until validated.
127 pub fn force_unlink<const I: u8>(&self, lhs_dart_id: DartIdType) -> Result<(), LinkError> {
128 // these assertions + match on a const are optimized away
129 assert!(I < 4);
130 assert_ne!(I, 0);
131 match I {
132 1 => self.force_one_unlink(lhs_dart_id),
133 2 => self.force_two_unlink(lhs_dart_id),
134 3 => self.force_three_unlink(lhs_dart_id),
135 _ => unreachable!(),
136 }
137 }
138}