summaryrefslogtreecommitdiff
path: root/src/context/tuple.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/context/tuple.rs')
-rw-r--r--src/context/tuple.rs847
1 files changed, 847 insertions, 0 deletions
diff --git a/src/context/tuple.rs b/src/context/tuple.rs
new file mode 100644
index 0000000..9bca72e
--- /dev/null
+++ b/src/context/tuple.rs
@@ -0,0 +1,847 @@
+use std::marker::PhantomData;
+
+use crate::{
+ context::{ContextGuard, LockingIterator, LockingTuple},
+ lockable::{Lockable, RawLock, Sharable},
+ ThreadKey,
+};
+
+impl<'c, A, B, O> LockingTuple<'c, A, B, O> {
+ fn transmute<C>(self) -> LockingTuple<'c, C, B, O> {
+ LockingTuple {
+ _lockable: PhantomData,
+ key: self.key,
+ tuple: self.tuple,
+ outer: self.outer,
+ }
+ }
+}
+
+macro_rules! lock_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ $self.tuple.$field.raw_write();
+ (
+ ContextGuard {
+ _key: &$self.key,
+ guard: $self.tuple.$field.guard(),
+ },
+ $self.transmute(),
+ )
+ }
+ };
+}
+
+macro_rules! try_lock_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ if $self.tuple.$field.raw_try_write() {
+ Ok((
+ ContextGuard {
+ _key: $self.key,
+ guard: $self.tuple.$field.guard(),
+ },
+ $self.transmute(),
+ ))
+ } else {
+ Err($self)
+ }
+ }
+ };
+}
+
+macro_rules! lock_mut_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ $self.tuple.$field.raw_write();
+ ContextGuard {
+ _key: $self.key,
+ guard: $self.tuple.$field.guard(),
+ }
+ }
+ };
+}
+
+macro_rules! try_lock_mut_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ if $self.tuple.$field.raw_try_write() {
+ Some(ContextGuard {
+ _key: $self.key,
+ guard: $self.tuple.$field.guard(),
+ })
+ } else {
+ None
+ }
+ }
+ };
+}
+
+macro_rules! read_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ $self.tuple.$field.raw_read();
+ (
+ ContextGuard {
+ _key: &$self.key,
+ guard: $self.tuple.$field.read_guard(),
+ },
+ $self.transmute(),
+ )
+ }
+ };
+}
+
+macro_rules! try_read_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ if $self.tuple.$field.raw_try_read() {
+ Ok((
+ ContextGuard {
+ _key: $self.key,
+ guard: $self.tuple.$field.read_guard(),
+ },
+ $self.transmute(),
+ ))
+ } else {
+ Err($self)
+ }
+ }
+ };
+}
+
+macro_rules! read_mut_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ $self.tuple.$field.raw_read();
+ ContextGuard {
+ _key: $self.key,
+ guard: $self.tuple.$field.read_guard(),
+ }
+ }
+ };
+}
+
+macro_rules! try_read_mut_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ if $self.tuple.$field.raw_try_read() {
+ Some(ContextGuard {
+ _key: $self.key,
+ guard: $self.tuple.$field.read_guard(),
+ })
+ } else {
+ None
+ }
+ }
+ };
+}
+
+macro_rules! recurse_impl {
+ ($self: expr, $field: tt) => {
+ LockingTuple {
+ _lockable: PhantomData,
+ key: $self.key,
+ tuple: &$self.tuple.$field,
+ outer: $self.transmute(),
+ }
+ };
+}
+
+macro_rules! recurse_iter_impl {
+ ($self: expr, $field: tt) => {
+ LockingIterator {
+ key: $self.key,
+ iterator: $self.tuple.$field.into_iter(),
+ outer: $self.transmute(),
+ }
+ };
+}
+
+type LockReturn<'a, 'context, Guarded, L, C, O> = (
+ ContextGuard<'a, <Guarded as Lockable>::Guard<'a>, ThreadKey>,
+ LockingTuple<'context, L, C, O>,
+);
+
+type TryLockReturn<'a, 'context, Guarded, L, C, O, This> =
+ Result<LockReturn<'a, 'context, Guarded, L, C, O>, This>;
+
+type ReadReturn<'a, 'context, Guarded, L, C, O> = (
+ ContextGuard<'a, <Guarded as Sharable>::ReadGuard<'a>, ThreadKey>,
+ LockingTuple<'context, L, C, O>,
+);
+
+type TryReadReturn<'a, 'context, Guarded, L, C, O, This> =
+ Result<ReadReturn<'a, 'context, Guarded, L, C, O>, This>;
+
+type RecurseReturn<'context, Inner, L, C, O> =
+ LockingTuple<'context, Inner, Inner, LockingTuple<'context, L, C, O>>;
+
+type RecurseIterReturn<'context, Inner, L, C, O> = LockingIterator<
+ 'context,
+ <&'context Inner as IntoIterator>::IntoIter,
+ LockingTuple<'context, L, C, O>,
+>;
+
+impl<T, C, Outer> LockingTuple<'_, T, C, Outer> {
+ /// Exit out of the current scope of the locking tuple into the parent.
+ pub fn exit(self) -> Outer {
+ self.outer
+ }
+}
+
+impl<'context, A: RawLock + Lockable, Outer> LockingTuple<'context, (A,), (A,), Outer> {
+ /// Lock the first element, and return a new tuple where the first element
+ /// is inaccessible.
+ #[must_use]
+ pub fn lock_0<'a>(self) -> LockReturn<'a, 'context, A, ((),), (A,), Outer>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 0)
+ }
+
+ /// Attempts to lock the first element without blocking, and return a new tuple
+ /// where the first element is inaccessible.
+ ///
+ /// # Errors
+ ///
+ /// If the element is already locked, `Err` is returned with the original
+ /// tuple.
+ pub fn try_lock_0<'a>(self) -> TryLockReturn<'a, 'context, A, ((),), (A,), Outer, Self>
+ where
+ 'context: 'a,
+ {
+ try_lock_impl!(self, 0)
+ }
+
+ /// Lock the first element. The tuple becomes unusable until the returned
+ /// guard is dropped.
+ #[must_use]
+ pub fn lock_mut_0(&mut self) -> ContextGuard<'_, A::Guard<'_>, ThreadKey> {
+ lock_mut_impl!(self, 0)
+ }
+
+ /// Attempts to lock the first element without blocking. If successful, the
+ /// tuple becomes unusable until the returned guard is dropped. If the element
+ /// is already locked, `None` is returned.
+ #[must_use]
+ pub fn try_lock_mut_0(&mut self) -> Option<ContextGuard<'_, A::Guard<'_>, ThreadKey>> {
+ try_lock_mut_impl!(self, 0)
+ }
+}
+
+impl<'context, A: RawLock + Sharable, Outer> LockingTuple<'context, (A,), (A,), Outer> {
+ /// Acquire a shared lock to the first element, and return a new tuple where
+ /// the first element is inaccessible.
+ #[must_use]
+ pub fn read_0<'a>(self) -> ReadReturn<'a, 'context, A, ((),), (A,), Outer>
+ where
+ 'context: 'a,
+ {
+ read_impl!(self, 0)
+ }
+
+ /// Attempts to acquire a shared lock the first element without blocking, and
+ /// return a new tuple where the first element is inaccessible.
+ ///
+ /// # Errors
+ ///
+ /// If the element is already exclusively locked, `Err` is returned with the original
+ /// tuple.
+ pub fn try_read_0<'a>(self) -> TryReadReturn<'a, 'context, A, ((),), (A,), Outer, Self>
+ where
+ 'context: 'a,
+ {
+ try_read_impl!(self, 0)
+ }
+
+ /// Acquire a shared lock to the first element. The tuple becomes unusable
+ /// until the returned guard is dropped.
+ #[must_use]
+ pub fn read_mut_0(&mut self) -> ContextGuard<'_, A::ReadGuard<'_>, ThreadKey> {
+ read_mut_impl!(self, 0)
+ }
+
+ /// Attempts to acquire a shared lock the first element without blocking. If
+ /// successful, the tuple becomes unusable until the returned guard is
+ /// dropped. If the element is already exclusively locked, `None` is returned.
+ #[must_use]
+ pub fn try_read_mut_0(&mut self) -> Option<ContextGuard<'_, A::ReadGuard<'_>, ThreadKey>> {
+ try_read_mut_impl!(self, 0)
+ }
+}
+
+impl<'context, A, O> LockingTuple<'context, (A,), (A,), O> {
+ /// Consume the tuple, and return the first element as a new tuple.
+ #[must_use]
+ pub fn recurse_0(self) -> RecurseReturn<'context, A, ((),), (A,), O> {
+ recurse_impl!(self, 0)
+ }
+
+ /// Consume the tuple, and return the first element as a locking iterator.
+ pub fn recurse_0_iter(self) -> RecurseIterReturn<'context, A, ((),), (A,), O>
+ where
+ &'context A: IntoIterator,
+ {
+ recurse_iter_impl!(self, 0)
+ }
+}
+
+impl<'context, A: RawLock + Lockable, B, B0, O> LockingTuple<'context, (A, B), (A, B0), O> {
+ /// Lock the first element, and return a new tuple where the first element
+ /// is inaccessible.
+ #[must_use]
+ pub fn lock_0<'a>(self) -> LockReturn<'a, 'context, A, ((), B), (A, B0), O>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 0)
+ }
+
+ /// Lock the first element. The tuple becomes unusable until the returned
+ /// guard is dropped.
+ #[must_use]
+ pub fn lock_mut_0(&mut self) -> ContextGuard<'_, A::Guard<'_>, ThreadKey> {
+ lock_mut_impl!(self, 0)
+ }
+
+ /// Attempts to lock the first element without blocking, and return a new tuple
+ /// where the first element is inaccessible.
+ ///
+ /// # Errors
+ ///
+ /// If the element is already locked, `Err` is returned with the original
+ /// tuple.
+ pub fn try_lock_0<'a>(self) -> TryLockReturn<'a, 'context, A, ((), B), (A, B0), O, Self>
+ where
+ 'context: 'a,
+ {
+ try_lock_impl!(self, 0)
+ }
+
+ /// Attempts to lock the first element without blocking. If successful, the
+ /// tuple becomes unusable until the returned guard is dropped. If the element
+ /// is already locked, `None` is returned.
+ #[must_use]
+ pub fn try_lock_mut_0(&mut self) -> Option<ContextGuard<'_, A::Guard<'_>, ThreadKey>> {
+ try_lock_mut_impl!(self, 0)
+ }
+}
+
+impl<'context, A: RawLock + Sharable, B, B0, O> LockingTuple<'context, (A, B), (A, B0), O> {
+ /// Acquire a shared lock to the first element, and return a new tuple where
+ /// the first element is inaccessible.
+ #[must_use]
+ pub fn read_0<'a>(self) -> ReadReturn<'a, 'context, A, ((), B), (A, B0), O>
+ where
+ 'context: 'a,
+ {
+ read_impl!(self, 0)
+ }
+
+ /// Attempts to acquire a shared lock the first element without blocking, and
+ /// return a new tuple where the first element is inaccessible.
+ ///
+ /// # Errors
+ ///
+ /// If the element is already exclusively locked, `Err` is returned with the original
+ /// tuple.
+ pub fn try_read_0<'a>(self) -> TryReadReturn<'a, 'context, A, ((), B), (A, B0), O, Self>
+ where
+ 'context: 'a,
+ {
+ try_read_impl!(self, 0)
+ }
+
+ /// Acquire a shared lock to the first element. The tuple becomes unusable
+ /// until the returned guard is dropped.
+ #[must_use]
+ pub fn read_mut_0(&mut self) -> ContextGuard<'_, A::ReadGuard<'_>, ThreadKey> {
+ read_mut_impl!(self, 0)
+ }
+
+ /// Attempts to acquire a shared lock the first element without blocking. If
+ /// successful, the tuple becomes unusable until the returned guard is
+ /// dropped. If the element is already exclusively locked, `None` is returned.
+ #[must_use]
+ pub fn try_read_mut_0(&mut self) -> Option<ContextGuard<'_, A::ReadGuard<'_>, ThreadKey>> {
+ try_read_mut_impl!(self, 0)
+ }
+}
+
+impl<'context, A, B, B0, O> LockingTuple<'context, (A, B), (A, B0), O> {
+ /// Consume the tuple, and return the first element as a new tuple.
+ #[must_use]
+ pub fn recurse_0(self) -> RecurseReturn<'context, A, ((), B), (A, B0), O> {
+ recurse_impl!(self, 0)
+ }
+
+ /// Consume the tuple, and return the first element as a locking iterator.
+ pub fn recurse_0_iter(self) -> RecurseIterReturn<'context, A, ((), B), (A, B0), O>
+ where
+ &'context A: IntoIterator,
+ {
+ recurse_iter_impl!(self, 0)
+ }
+}
+
+impl<'context, A: Lockable + RawLock, B, O> LockingTuple<'context, (A, B), (A, B), O> {
+ /// Lock the first element, and return the second element as a new tuple.
+ #[must_use]
+ pub fn lock_and_recurse<'a>(
+ self,
+ ) -> (
+ ContextGuard<'a, <A as Lockable>::Guard<'a>, ThreadKey>,
+ LockingTuple<'context, B, B, O>,
+ )
+ where
+ 'context: 'a,
+ {
+ unsafe {
+ self.tuple.0.raw_write();
+ (
+ ContextGuard {
+ _key: self.key,
+ guard: self.tuple.0.guard(),
+ },
+ LockingTuple {
+ _lockable: PhantomData,
+ key: self.key,
+ tuple: &self.tuple.1,
+ outer: self.outer,
+ },
+ )
+ }
+ }
+}
+
+impl<'context, A, A0, B: RawLock + Lockable, O> LockingTuple<'context, (A, B), (A0, B), O> {
+ /// Lock the second element, and return a new tuple where the first and second
+ /// elements are inaccessible.
+ #[must_use]
+ pub fn lock_1<'a>(self) -> LockReturn<'a, 'context, B, ((), ()), (A0, B), O>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 1)
+ }
+
+ /// Lock the second element. The tuple becomes unusable until the returned
+ /// guard is dropped.
+ #[must_use]
+ pub fn lock_mut_1(&mut self) -> ContextGuard<'_, B::Guard<'_>, ThreadKey> {
+ lock_mut_impl!(self, 1)
+ }
+
+ /// Attempts to lock the second element without blocking, and return a new tuple
+ /// where the first element is inaccessible.
+ ///
+ /// # Errors
+ ///
+ /// If the element is already locked, `Err` is returned with the original
+ /// tuple.
+ pub fn try_lock_1<'a>(self) -> TryLockReturn<'a, 'context, B, ((), ()), (A0, B), O, Self>
+ where
+ 'context: 'a,
+ {
+ try_lock_impl!(self, 1)
+ }
+
+ /// Attempts to lock the second element without blocking. If successful, the
+ /// tuple becomes unusable until the returned guard is dropped. If the element
+ /// is already locked, `None` is returned.
+ #[must_use]
+ pub fn try_lock_mut_1(&mut self) -> Option<ContextGuard<'_, B::Guard<'_>, ThreadKey>> {
+ try_lock_mut_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B: RawLock + Sharable, O> LockingTuple<'context, (A, B), (A0, B), O> {
+ /// Acquire a shared lock to the second element, and return a new tuple where
+ /// the second element is inaccessible.
+ #[must_use]
+ pub fn read_1<'a>(self) -> ReadReturn<'a, 'context, B, ((), ()), (A0, B), O>
+ where
+ 'context: 'a,
+ {
+ read_impl!(self, 1)
+ }
+
+ /// Attempts to acquire a shared lock the second element without blocking, and
+ /// return a new tuple where the second element is inaccessible.
+ ///
+ /// # Errors
+ ///
+ /// If the element is already exclusively locked, `Err` is returned with the original
+ /// tuple.
+ pub fn try_read_1<'a>(self) -> TryReadReturn<'a, 'context, B, ((), ()), (A0, B), O, Self>
+ where
+ 'context: 'a,
+ {
+ try_read_impl!(self, 1)
+ }
+
+ /// Acquire a shared lock to the second element. The tuple becomes unusable
+ /// until the returned guard is dropped.
+ #[must_use]
+ pub fn read_mut_1(&mut self) -> ContextGuard<'_, B::ReadGuard<'_>, ThreadKey> {
+ read_mut_impl!(self, 1)
+ }
+
+ /// Attempts to acquire a shared lock the second element without blocking. If
+ /// successful, the tuple becomes unusable until the returned guard is
+ /// dropped. If the element is already exclusively locked, `None` is returned.
+ #[must_use]
+ pub fn try_read_mut_1(&mut self) -> Option<ContextGuard<'_, B::ReadGuard<'_>, ThreadKey>> {
+ try_read_mut_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B, O> LockingTuple<'context, (A, B), (A0, B), O> {
+ /// Consume the tuple, and return the second element as a new tuple.
+ #[must_use]
+ pub fn recurse_1(self) -> RecurseReturn<'context, B, ((), ()), (A0, B), O> {
+ recurse_impl!(self, 1)
+ }
+
+ /// Consume the tuple, and return the second element as a locking iterator.
+ pub fn recurse_1_iter(self) -> RecurseIterReturn<'context, B, (A, ()), (A0, B), O>
+ where
+ &'context B: IntoIterator,
+ {
+ recurse_iter_impl!(self, 1)
+ }
+}
+
+impl<'context, A: RawLock + Lockable, B, B0, C, C0, O>
+ LockingTuple<'context, (A, B, C), (A, B0, C0), O>
+{
+ /// Lock the first element, and return a new tuple where the first element
+ /// is inaccessible.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn lock_0<'a>(self) -> LockReturn<'a, 'context, A, ((), B, C), (A, B0, C0), O>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 0)
+ }
+
+ /// Lock the first element. The tuple becomes unusable until the returned
+ /// guard is dropped.
+ #[must_use]
+ pub fn lock_mut_0(&mut self) -> ContextGuard<'_, A::Guard<'_>, ThreadKey> {
+ lock_mut_impl!(self, 0)
+ }
+
+ /// Attempts to lock the first element without blocking. If successful, the
+ /// tuple becomes unusable until the returned guard is dropped. If the element
+ /// is already locked, `None` is returned.
+ #[must_use]
+ pub fn try_lock_mut_0(&mut self) -> Option<ContextGuard<'_, A::Guard<'_>, ThreadKey>> {
+ try_lock_mut_impl!(self, 0)
+ }
+}
+
+impl<'context, A: RawLock + Sharable, B, B0, C, C0, O>
+ LockingTuple<'context, (A, B, C), (A, B0, C0), O>
+{
+ /// Acquire a shared lock to the first element, and return a new tuple where
+ /// the first element is inaccessible.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn read_0<'a>(self) -> ReadReturn<'a, 'context, A, ((), B, C), (A, B0, C0), O>
+ where
+ 'context: 'a,
+ {
+ read_impl!(self, 0)
+ }
+
+ /// Acquire a shared lock to the first element. The tuple becomes unusable
+ /// until the returned guard is dropped.
+ #[must_use]
+ pub fn read_mut_0(&mut self) -> ContextGuard<'_, A::ReadGuard<'_>, ThreadKey> {
+ read_mut_impl!(self, 0)
+ }
+
+ /// Attempts to acquire a shared lock the first element without blocking. If
+ /// successful, the tuple becomes unusable until the returned guard is
+ /// dropped. If the element is already exclusively locked, `None` is returned.
+ #[must_use]
+ pub fn try_read_mut_0(&mut self) -> Option<ContextGuard<'_, A::ReadGuard<'_>, ThreadKey>> {
+ try_read_mut_impl!(self, 0)
+ }
+}
+
+impl<'context, A, B, B0, C, C0, O> LockingTuple<'context, (A, B, C), (A, B0, C0), O> {
+ /// Consume the tuple, and return the first element as a new tuple.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_0(self) -> RecurseReturn<'context, A, ((), B, C), (A, B0, C0), O> {
+ recurse_impl!(self, 0)
+ }
+
+ /// Consume the tuple, and return the first element as a locking iterator.
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_0_iter(self) -> RecurseIterReturn<'context, A, ((), B, C), (A, B0, C0), O>
+ where
+ &'context A: IntoIterator,
+ {
+ recurse_iter_impl!(self, 0)
+ }
+}
+
+impl<'context, A, A0, B: RawLock + Lockable, C, C0, O>
+ LockingTuple<'context, (A, B, C), (A0, B, C0), O>
+{
+ /// Lock the second element, and return a new tuple where the first and second
+ /// elements are inaccessible.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn lock_1<'a>(self) -> LockReturn<'a, 'context, B, ((), (), C), (A0, B, C0), O>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 1)
+ }
+
+ /// Lock the second element. The tuple becomes unusable until the returned
+ /// guard is dropped.
+ #[must_use]
+ pub fn lock_mut_1(&mut self) -> ContextGuard<'_, B::Guard<'_>, ThreadKey> {
+ lock_mut_impl!(self, 1)
+ }
+
+ /// Attempts to lock the second element without blocking. If successful, the
+ /// tuple becomes unusable until the returned guard is dropped. If the element
+ /// is already locked, `None` is returned.
+ #[must_use]
+ pub fn try_lock_mut_1(&mut self) -> Option<ContextGuard<'_, B::Guard<'_>, ThreadKey>> {
+ try_lock_mut_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B: RawLock + Sharable, C, C0, O>
+ LockingTuple<'context, (A, B, C), (A0, B, C0), O>
+{
+ /// Acquire a shared lock to the second element, and return a new tuple where
+ /// the second element is inaccessible.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn read_1<'a>(self) -> ReadReturn<'a, 'context, B, ((), (), C), (A0, B, C0), O>
+ where
+ 'context: 'a,
+ {
+ read_impl!(self, 1)
+ }
+
+ /// Acquire a shared lock to the second element. The tuple becomes unusable
+ /// until the returned guard is dropped.
+ #[must_use]
+ pub fn read_mut_1(&mut self) -> ContextGuard<'_, B::ReadGuard<'_>, ThreadKey> {
+ read_mut_impl!(self, 1)
+ }
+
+ /// Attempts to acquire a shared lock the second element without blocking. If
+ /// successful, the tuple becomes unusable until the returned guard is
+ /// dropped. If the element is already exclusively locked, `None` is returned.
+ #[must_use]
+ pub fn try_read_mut_1(&mut self) -> Option<ContextGuard<'_, B::ReadGuard<'_>, ThreadKey>> {
+ try_read_mut_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B, C, C0, O> LockingTuple<'context, (A, B, C), (A0, B, C0), O> {
+ /// Consume the tuple, and return the second element as a new tuple.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_1(self) -> RecurseReturn<'context, B, ((), (), C), (A0, B, C0), O> {
+ recurse_impl!(self, 1)
+ }
+
+ /// Consume the tuple, and return the second element as a locking iterator.
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_1_iter(self) -> RecurseIterReturn<'context, B, ((), (), C), (A0, B, C0), O>
+ where
+ &'context B: IntoIterator,
+ {
+ recurse_iter_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B, B0, C: RawLock + Lockable, O>
+ LockingTuple<'context, (A, B, C), (A0, B0, C), O>
+{
+ /// Lock the third element, and return a new tuple where all elements are
+ /// inaccessible.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn lock_2<'a>(self) -> LockReturn<'a, 'context, C, ((), (), ()), (A0, B0, C), O>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 2)
+ }
+
+ /// Lock the third element. The tuple becomes unusable until the returned
+ /// guard is dropped.
+ #[must_use]
+ pub fn lock_mut_2(&mut self) -> ContextGuard<'_, C::Guard<'_>, ThreadKey> {
+ lock_mut_impl!(self, 2)
+ }
+
+ /// Attempts to lock the third element without blocking. If successful, the
+ /// tuple becomes unusable until the returned guard is dropped. If the element
+ /// is already locked, `None` is returned.
+ #[must_use]
+ pub fn try_lock_mut_2(&mut self) -> Option<ContextGuard<'_, C::Guard<'_>, ThreadKey>> {
+ try_lock_mut_impl!(self, 2)
+ }
+}
+
+impl<'context, A, A0, B, B0, C: RawLock + Sharable, O>
+ LockingTuple<'context, (A, B, C), (A0, B0, C), O>
+{
+ /// Acquire a shared lock to the third element, and return a new tuple where
+ /// the third element is inaccessible.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn read_2<'a>(self) -> ReadReturn<'a, 'context, C, ((), (), ()), (A0, B0, C), O>
+ where
+ 'context: 'a,
+ {
+ read_impl!(self, 2)
+ }
+
+ /// Acquire a shared lock to the third element. The tuple becomes unusable
+ /// until the returned guard is dropped.
+ #[must_use]
+ pub fn read_mut_2(&mut self) -> ContextGuard<'_, C::ReadGuard<'_>, ThreadKey> {
+ read_mut_impl!(self, 2)
+ }
+
+ /// Attempts to acquire a shared lock the third element without blocking. If
+ /// successful, the tuple becomes unusable until the returned guard is
+ /// dropped. If the element is already exclusively locked, `None` is returned.
+ #[must_use]
+ pub fn try_read_mut_2(&mut self) -> Option<ContextGuard<'_, C::ReadGuard<'_>, ThreadKey>> {
+ try_read_mut_impl!(self, 2)
+ }
+}
+
+impl<'context, A, A0, B, B0, C, O> LockingTuple<'context, (A, B, C), (A0, B0, C), O> {
+ /// Consume the tuple, and return the third element as a new tuple.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_2(self) -> RecurseReturn<'context, C, ((), (), ()), (A0, B0, C), O> {
+ recurse_impl!(self, 2)
+ }
+
+ /// Consume the tuple, and return the third element as a locking iterator.
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_2_iter(self) -> RecurseIterReturn<'context, C, ((), (), ()), (A0, B0, C), O>
+ where
+ &'context C: IntoIterator,
+ {
+ recurse_iter_impl!(self, 2)
+ }
+}
+
+impl<'context, A, B, B0, C, C0, D, D0, O> LockingTuple<'context, (A, B, C, D), (A, B0, C0, D0), O> {
+ /// Consume the tuple, and return the first element as a new tuple.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_0(self) -> RecurseReturn<'context, A, ((), B, C, D), (A, B0, C0, D0), O> {
+ recurse_impl!(self, 0)
+ }
+
+ /// Consume the tuple, and return the first element as a locking iterator.
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_0_iter(self) -> RecurseIterReturn<'context, A, ((), B, C, D), (A, B0, C0, D0), O>
+ where
+ &'context A: IntoIterator,
+ {
+ recurse_iter_impl!(self, 0)
+ }
+}
+
+impl<'context, A, A0, B, C, C0, D, D0, O> LockingTuple<'context, (A, B, C, D), (A0, B, C0, D0), O> {
+ /// Consume the tuple, and return the second element as a new tuple.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_1(self) -> RecurseReturn<'context, B, ((), (), C, D), (A0, B, C0, D0), O> {
+ recurse_impl!(self, 1)
+ }
+
+ /// Consume the tuple, and return the second element as a locking iterator.
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_1_iter(
+ self,
+ ) -> RecurseIterReturn<'context, B, ((), (), C, D), (A0, B, C0, D0), O>
+ where
+ &'context B: IntoIterator,
+ {
+ recurse_iter_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B, B0, C, D, D0, O> LockingTuple<'context, (A, B, C, D), (A0, B0, C, D0), O> {
+ /// Consume the tuple, and return the third element as a new tuple.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_2(self) -> RecurseReturn<'context, C, ((), (), (), D), (A0, B0, C, D0), O> {
+ recurse_impl!(self, 2)
+ }
+
+ /// Consume the tuple, and return the third element as a locking iterator.
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_2_iter(
+ self,
+ ) -> RecurseIterReturn<'context, C, ((), (), (), D), (A0, B0, C, D0), O>
+ where
+ &'context C: IntoIterator,
+ {
+ recurse_iter_impl!(self, 2)
+ }
+}
+
+impl<'context, A, A0, B, B0, C, C0, D, O> LockingTuple<'context, (A, B, C, D), (A0, B0, C0, D), O> {
+ /// Consume the tuple, and return the fourth element as a new tuple.
+ #[must_use]
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_3(self) -> RecurseReturn<'context, D, ((), (), (), ()), (A0, B0, C0, D), O> {
+ recurse_impl!(self, 3)
+ }
+
+ /// Consume the tuple, and return the first element as a locking iterator.
+ // The type is impossible to refactor, and I already wrote this function, so no point in removing it
+ #[expect(clippy::type_complexity)]
+ pub fn recurse_3_iter(
+ self,
+ ) -> RecurseIterReturn<'context, D, ((), (), (), ()), (A0, B0, C0, D), O>
+ where
+ &'context D: IntoIterator,
+ {
+ recurse_iter_impl!(self, 3)
+ }
+}