1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
mod one;
mod two;
use fast_stm::atomically_with_err;
use crate::cmap::{CMap2, DartIdType, LinkError};
use crate::geometry::CoordsFloat;
use crate::stm::{Transaction, TransactionClosureResult};
/// # **Link operations**
impl<T: CoordsFloat> CMap2<T> {
/// `I`-link operator.
///
/// # Description
///
/// This operation corresponds to coherently linking two darts via their *β* images. Unlike
/// sewing, this does not alter associated attributes. For a thorough explanation of this
/// operation, its hypothesis & consequences, refer to the [user guide][UG].
///
/// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
///
/// # Arguments
///
/// - `const I: u8` -- Link dimension.
/// - `t: &mut Transaction` -- Transaction associated to the operation.
/// - `ld: DartIdType` -- First dart ID.
/// - `rd: DartIdType` -- Second dart ID.
///
/// # Errors
///
/// This method should be called in a transactional context. The `Result` is then used to
/// validate the transaction; Errors should not be processed manually, only processed via the
/// `?` operator. The policy in case of failure can be defined when creating the transaction,
/// using `Transaction::with_control`.
///
/// # Panics
///
/// The method may panic if:
/// - `I >= 3` or `I == 0`,
/// - the two darts are not `I`-linkable.
pub fn link_tx<const I: u8>(
&self,
t: &mut Transaction,
ld: DartIdType,
rd: DartIdType,
) -> TransactionClosureResult<(), LinkError> {
// these assertions + match on a const are optimized away
assert!(I < 3);
assert_ne!(I, 0);
match I {
1 => self.one_link_tx(t, ld, rd),
2 => self.two_link_tx(t, ld, rd),
_ => unreachable!(),
}
}
/// `I`-unlink operator.
///
/// # Description
///
/// This operation corresponds to unlinking two darts by resetting their *β* images. Unlike
/// unsewing, this does not alter associated attributes. For a thorough explanation of this
/// operation, its hypothesis & consequences, refer to the [user guide][UG].
///
/// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
///
/// # Arguments
///
/// - `const I: u8` -- Unlink dimension.
/// - `t: &mut Transaction` -- Transaction associated to the operation.
/// - `ld: DartIdType` -- First dart ID.
///
/// The second dart ID is fetched using `I` and `ld`.
///
/// # Errors
///
/// This method should be called in a transactional context. The `Result` is then used to
/// validate the transaction; Errors should not be processed manually, only processed via the
/// `?` operator. The policy in case of failure can be defined when creating the transaction,
/// using `Transaction::with_control`.
///
/// # Panics
///
/// The method may panic if:
/// - `I >= 3` or `I == 0`,
/// - `ld` is already `I`-free.
pub fn unlink_tx<const I: u8>(
&self,
t: &mut Transaction,
ld: DartIdType,
) -> TransactionClosureResult<(), LinkError> {
// these assertions + match on a const are optimized away
assert!(I < 3);
assert_ne!(I, 0);
match I {
1 => self.one_unlink_tx(t, ld),
2 => self.two_unlink_tx(t, ld),
_ => unreachable!(),
}
}
#[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
/// `I`-link operator.
///
/// This variant is equivalent to [`link`][Self::link], but internally uses a transaction that
/// will be retried until validated.
pub fn link<const I: u8>(&self, ld: DartIdType, rd: DartIdType) -> Result<(), LinkError> {
// these assertions + match on a const are optimized away
assert!(I < 3);
assert_ne!(I, 0);
match I {
1 => atomically_with_err(|t| self.one_link_tx(t, ld, rd)),
2 => atomically_with_err(|t| self.two_link_tx(t, ld, rd)),
_ => unreachable!(),
}
}
#[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
/// # `I`-unlink operator.
///
/// This variant is equivalent to [`unlink`][Self::unlink], but internally uses a transaction
/// that will be retried until validated.
pub fn unlink<const I: u8>(&self, ld: DartIdType) -> Result<(), LinkError> {
// these assertions + match on a const are optimized away
assert!(I < 3);
assert_ne!(I, 0);
match I {
1 => atomically_with_err(|t| self.one_unlink_tx(t, ld)),
2 => atomically_with_err(|t| self.two_unlink_tx(t, ld)),
_ => unreachable!(),
}
}
}