summaryrefslogtreecommitdiff
path: root/src/iterator/tuple.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/iterator/tuple.rs')
-rw-r--r--src/iterator/tuple.rs202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/iterator/tuple.rs b/src/iterator/tuple.rs
new file mode 100644
index 0000000..855cdc7
--- /dev/null
+++ b/src/iterator/tuple.rs
@@ -0,0 +1,202 @@
+use std::marker::PhantomData;
+
+use crate::{
+ iterator::{IteratorGuard, LockingTuple},
+ lockable::{Lockable, RawLock},
+ ThreadKey,
+};
+
+impl<'c, A, B> LockingTuple<'c, A, B> {
+ const fn transmute<C>(self) -> LockingTuple<'c, C, B> {
+ LockingTuple {
+ _lockable: PhantomData,
+ key: self.key,
+ tuple: self.tuple,
+ }
+ }
+}
+
+macro_rules! lock_impl {
+ ($self: expr, $field: tt) => {
+ unsafe {
+ $self.tuple.$field.raw_write();
+ (
+ IteratorGuard {
+ _key: &$self.key,
+ guard: $self.tuple.$field.guard(),
+ },
+ $self.transmute(),
+ )
+ }
+ };
+}
+
+macro_rules! recurse_impl {
+ ($self: expr, $field: tt) => {
+ LockingTuple {
+ _lockable: PhantomData,
+ key: $self.key,
+ tuple: &$self.tuple.$field,
+ }
+ };
+}
+
+type LockReturn<'a, 'context, Guarded, L, C> = (
+ IteratorGuard<'a, <Guarded as Lockable>::Guard<'a>, ThreadKey>,
+ LockingTuple<'context, L, C>,
+);
+
+impl<'context, A: RawLock + Lockable> LockingTuple<'context, (A,), (A,)> {
+ #[must_use]
+ pub fn lock_0<'a>(self) -> LockReturn<'a, 'context, A, ((),), (A,)>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 0)
+ }
+}
+
+impl<'context, A> LockingTuple<'context, (A,), (A,)> {
+ #[must_use]
+ pub const fn recurse_0(self) -> LockingTuple<'context, A, A> {
+ recurse_impl!(self, 0)
+ }
+}
+
+impl<'context, A: RawLock + Lockable, B, B0> LockingTuple<'context, (A, B), (A, B0)> {
+ #[must_use]
+ pub fn lock_0<'a>(self) -> LockReturn<'a, 'context, A, ((), B), (A, B0)>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 0)
+ }
+}
+
+impl<'context, A, B, B0> LockingTuple<'context, (A, B), (A, B0)> {
+ #[must_use]
+ pub const fn recurse_0(self) -> LockingTuple<'context, A, A> {
+ recurse_impl!(self, 0)
+ }
+}
+
+impl<'context, A: Lockable + RawLock, B> LockingTuple<'context, (A, B), (A, B)> {
+ #[must_use]
+ pub fn lock_and_recurse<'a>(
+ self,
+ ) -> (
+ IteratorGuard<'a, <A as Lockable>::Guard<'a>, ThreadKey>,
+ LockingTuple<'context, B, B>,
+ )
+ where
+ 'context: 'a,
+ {
+ unsafe {
+ self.tuple.0.raw_write();
+ (
+ IteratorGuard {
+ _key: self.key,
+ guard: self.tuple.0.guard(),
+ },
+ LockingTuple {
+ _lockable: PhantomData,
+ key: self.key,
+ tuple: &self.tuple.1,
+ },
+ )
+ }
+ }
+}
+
+impl<'context, A, A0, B: RawLock + Lockable> LockingTuple<'context, (A, B), (A0, B)> {
+ #[must_use]
+ pub fn lock_1<'a>(self) -> LockReturn<'a, 'context, B, ((), ()), (A0, B)>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B> LockingTuple<'context, (A, B), (A0, B)> {
+ #[must_use]
+ pub const fn recurse_1(self) -> LockingTuple<'context, B, B> {
+ recurse_impl!(self, 1)
+ }
+}
+
+impl<'context, A: RawLock + Lockable, B, B0, C, C0> LockingTuple<'context, (A, B, C), (A, B0, C0)> {
+ #[must_use]
+ pub fn lock_0<'a>(self) -> LockReturn<'a, 'context, A, ((), B, C), (A, B0, C0)>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 0)
+ }
+}
+
+impl<'context, A, B, B0, C, C0> LockingTuple<'context, (A, B, C), (A, B0, C0)> {
+ #[must_use]
+ pub const fn recurse_0(self) -> LockingTuple<'context, A, A> {
+ recurse_impl!(self, 0)
+ }
+}
+
+impl<'context, A, A0, B: RawLock + Lockable, C, C0> LockingTuple<'context, (A, B, C), (A0, B, C0)> {
+ #[must_use]
+ pub fn lock_1<'a>(self) -> LockReturn<'a, 'context, B, ((), (), C), (A0, B, C0)>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B, C, C0> LockingTuple<'context, (A, B, C), (A0, B, C0)> {
+ #[must_use]
+ pub const fn recurse_1(self) -> LockingTuple<'context, B, B> {
+ recurse_impl!(self, 1)
+ }
+}
+
+impl<'context, A, A0, B, B0, C: RawLock + Lockable> LockingTuple<'context, (A, B, C), (A0, B0, C)> {
+ #[must_use]
+ pub fn lock_2<'a>(self) -> LockReturn<'a, 'context, C, ((), (), ()), (A0, B0, C)>
+ where
+ 'context: 'a,
+ {
+ lock_impl!(self, 2)
+ }
+}
+
+impl<'context, A, A0, B, B0, C> LockingTuple<'context, (A, B, C), (A0, B0, C)> {
+ #[must_use]
+ pub const fn recurse_2(self) -> LockingTuple<'context, C, C> {
+ recurse_impl!(self, 2)
+ }
+}
+
+impl<'context, A, B, B0, C, C0, D, D0> LockingTuple<'context, (A, B, C, D), (A, B0, C0, D0)> {
+ #[must_use]
+ pub const fn recurse_0(self) -> LockingTuple<'context, A, A> {
+ recurse_impl!(self, 0)
+ }
+}
+impl<'context, A, A0, B, C, C0, D, D0> LockingTuple<'context, (A, B, C, D), (A0, B, C0, D0)> {
+ #[must_use]
+ pub const fn recurse_1(self) -> LockingTuple<'context, B, B> {
+ recurse_impl!(self, 1)
+ }
+}
+impl<'context, A, A0, B, B0, C, D, D0> LockingTuple<'context, (A, B, C, D), (A0, B0, C, D0)> {
+ #[must_use]
+ pub const fn recurse_2(self) -> LockingTuple<'context, C, C> {
+ recurse_impl!(self, 2)
+ }
+}
+impl<'context, A, A0, B, B0, C, C0, D> LockingTuple<'context, (A, B, C, D), (A0, B0, C0, D)> {
+ #[must_use]
+ pub const fn recurse_3(self) -> LockingTuple<'context, D, D> {
+ recurse_impl!(self, 3)
+ }
+}