use crate::{
acquirable::{Acquirable, MutexRef},
level::{MaxLevel, MinLevel},
mutex::guard::MutexGuard,
};
impl<'a, A, B> Acquirable<'a> for (A, B)
where
A: MutexRef<'a>,
B: MutexRef<'a, RawMtx = A::RawMtx>,
A::Lvl: MinLevel<B::Lvl> + MaxLevel<B::Lvl>,
{
type MinLvl = <A::Lvl as MinLevel<B::Lvl>>::Min;
type MaxLvl = <A::Lvl as MaxLevel<B::Lvl>>::Max;
type Guard = (
MutexGuard<'a, A::RawMtx, A::Data>,
MutexGuard<'a, B::RawMtx, B::Data>,
);
fn collect_ids(&self, out: &mut alloc::vec::Vec<crate::id::LockId>) {
out.push(self.0.id());
out.push(self.1.id());
}
#[allow(clippy::expect_used, non_snake_case)]
fn lock_sorted(&'a self, sorted_indices: &[usize]) -> Self::Guard {
let mut GA: Option<MutexGuard<'a, A::RawMtx, A::Data>> = None;
let mut GB: Option<MutexGuard<'a, B::RawMtx, B::Data>> = None;
for &target in sorted_indices {
match target {
0 => GA = Some(self.0.lock_ref()),
1 => GB = Some(self.1.lock_ref()),
_ => unreachable!(),
}
}
(
GA.expect("lock_sorted: missing index 0"),
GB.expect("lock_sorted: missing index 1"),
)
}
}
macro_rules! impl_lockable_tuple_same_level {
($n:literal: $first_idx:tt $first_T:ident $first_G:ident $(, $idx:tt $T:ident $G:ident)+) => {
impl<'a, $first_G, $($G,)+> Acquirable<'a>
for ($first_G, $($G,)+)
where
$first_G: MutexRef<'a>,
$($G: MutexRef<'a, Lvl = $first_G::Lvl, RawMtx = $first_G::RawMtx>,)+
{
type MinLvl = $first_G::Lvl;
type MaxLvl = $first_G::Lvl;
type Guard = (
MutexGuard<'a, $first_G::RawMtx, $first_G::Data>,
$(MutexGuard<'a, $G::RawMtx, $G::Data>,)+
);
fn collect_ids(&self, out: &mut alloc::vec::Vec<crate::id::LockId>) {
out.push(self.$first_idx.id());
$(out.push(self.$idx.id());)+
}
#[allow(clippy::expect_used, non_snake_case)]
fn lock_sorted(&'a self, sorted_indices: &[usize]) -> Self::Guard {
let mut $first_T: Option<MutexGuard<'a, $first_G::RawMtx, $first_G::Data>> = None;
$(let mut $T: Option<MutexGuard<'a, $G::RawMtx, $G::Data>> = None;)+
for &target in sorted_indices {
match target {
$first_idx => $first_T = Some(self.$first_idx.lock_ref()),
$($idx => $T = Some(self.$idx.lock_ref()),)+
_ => unreachable!(),
}
}
(
$first_T.expect("lock_sorted: missing index in permutation"),
$($T.expect("lock_sorted: missing index in permutation"),)+
)
}
}
};
}
impl_lockable_tuple_same_level!( 3: 0 A GA, 1 B GB, 2 C GC);
impl_lockable_tuple_same_level!( 4: 0 A GA, 1 B GB, 2 C GC, 3 D GD);
impl_lockable_tuple_same_level!( 5: 0 A GA, 1 B GB, 2 C GC, 3 D GD, 4 E GE);
impl_lockable_tuple_same_level!( 6: 0 A GA, 1 B GB, 2 C GC, 3 D GD, 4 E GE, 5 F GF);
impl_lockable_tuple_same_level!( 7: 0 A GA, 1 B GB, 2 C GC, 3 D GD, 4 E GE, 5 F GF, 6 G GG);
impl_lockable_tuple_same_level!( 8: 0 A GA, 1 B GB, 2 C GC, 3 D GD, 4 E GE, 5 F GF, 6 G GG, 7 H GH);
impl_lockable_tuple_same_level!( 9: 0 A GA, 1 B GB, 2 C GC, 3 D GD, 4 E GE, 5 F GF, 6 G GG, 7 H GH, 8 I GI);
impl_lockable_tuple_same_level!(10: 0 A GA, 1 B GB, 2 C GC, 3 D GD, 4 E GE, 5 F GF, 6 G GG, 7 H GH, 8 I GI, 9 J GJ);
impl_lockable_tuple_same_level!(11: 0 A GA, 1 B GB, 2 C GC, 3 D GD, 4 E GE, 5 F GF, 6 G GG, 7 H GH, 8 I GI, 9 J GJ, 10 K GK);
impl_lockable_tuple_same_level!(12: 0 A GA, 1 B GB, 2 C GC, 3 D GD, 4 E GE, 5 F GF, 6 G GG, 7 H GH, 8 I GI, 9 J GJ, 10 K GK, 11 L GL);