From 55b3a2425b242fbc5c6e471f220eeb8b949e8751 Mon Sep 17 00:00:00 2001 From: Mica White Date: Wed, 26 Aug 2026 20:46:31 -0400 Subject: Add tests --- src/iterator/context.rs | 52 ------------ src/iterator/guard.rs | 58 -------------- src/iterator/iterator.rs | 118 --------------------------- src/iterator/tuple.rs | 202 ----------------------------------------------- 4 files changed, 430 deletions(-) delete mode 100644 src/iterator/context.rs delete mode 100644 src/iterator/guard.rs delete mode 100644 src/iterator/iterator.rs delete mode 100644 src/iterator/tuple.rs (limited to 'src/iterator') diff --git a/src/iterator/context.rs b/src/iterator/context.rs deleted file mode 100644 index a5c9123..0000000 --- a/src/iterator/context.rs +++ /dev/null @@ -1,52 +0,0 @@ -use std::marker::PhantomData; - -use crate::{ - iterator::{LockContext, LockingIterator, LockingTuple}, - lockable::Lockable, - ThreadKey, -}; - -impl<'l, L> LockContext<'l, L> { - pub(crate) const fn new(lockable: &'l L) -> Self { - Self { - key: None, - lockable, - } - } -} - -impl LockContext<'_, L> { - pub fn tuple(&mut self, key: ThreadKey) -> LockingTuple<'_, L, L> { - unsafe { - self.key = Some(key); - - LockingTuple { - _lockable: PhantomData, - // safety: we just inserted a key - key: self.key.as_ref().unwrap_unchecked(), - tuple: self.lockable, - } - } - } -} - -impl<'l, L> LockContext<'l, L> -where - &'l L: IntoIterator, -{ - #[expect(clippy::iter_not_returning_iterator)] - pub fn iter( - &mut self, - key: ThreadKey, - ) -> LockingIterator<'_, <&'l L as IntoIterator>::IntoIter> { - unsafe { - self.key = Some(key); - - LockingIterator { - // safety: we just inserted a key - key: self.key.as_ref().unwrap_unchecked(), - iterator: self.lockable.into_iter(), - } - } - } -} diff --git a/src/iterator/guard.rs b/src/iterator/guard.rs deleted file mode 100644 index cb220ac..0000000 --- a/src/iterator/guard.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::fmt::{Debug, Display}; -use std::hash::Hash; -use std::ops::{Deref, DerefMut}; - -use super::IteratorGuard; - -#[mutants::skip] // hashing involves RNG and is hard to test -#[cfg(not(tarpaulin_include))] -impl Hash for IteratorGuard<'_, Guard, Key> { - fn hash(&self, state: &mut H) { - self.guard.hash(state) - } -} - -// No implementations of Eq, PartialEq, PartialOrd, or Ord -// You can't implement both PartialEq and PartialEq -// It's easier to just implement neither and ask users to dereference -// This is less of a problem when using the scoped lock API - -#[mutants::skip] -#[cfg(not(tarpaulin_include))] -impl Debug for IteratorGuard<'_, Guard, Key> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - Debug::fmt(&**self, f) - } -} - -impl Display for IteratorGuard<'_, Guard, Key> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - Display::fmt(&**self, f) - } -} - -impl Deref for IteratorGuard<'_, Guard, Key> { - type Target = Guard; - - fn deref(&self) -> &Self::Target { - &self.guard - } -} - -impl DerefMut for IteratorGuard<'_, Guard, Key> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.guard - } -} - -impl AsRef for IteratorGuard<'_, Guard, Key> { - fn as_ref(&self) -> &Guard { - &self.guard - } -} - -impl AsMut for IteratorGuard<'_, Guard, Key> { - fn as_mut(&mut self) -> &mut Guard { - &mut self.guard - } -} diff --git a/src/iterator/iterator.rs b/src/iterator/iterator.rs deleted file mode 100644 index 316a276..0000000 --- a/src/iterator/iterator.rs +++ /dev/null @@ -1,118 +0,0 @@ -use std::iter::{Enumerate, Fuse, Skip, Take}; - -use super::{IteratorGuard, LockingIterator}; - -use crate::{ - lockable::{Lockable, RawLock, Sharable}, - ThreadKey, -}; - -impl<'l, I> LockingIterator<'l, I> { - fn with_iterator(self, f: impl FnOnce(I) -> M) -> LockingIterator<'l, M> { - LockingIterator { - key: self.key, - iterator: f(self.iterator), - } - } -} - -impl<'c, L: 'c + Iterator, I: 'c + RawLock + Lockable> LockingIterator<'c, L> { - pub fn lock_next( - &mut self, - ) -> Option::Guard<'c>, ThreadKey>> { - if let Some(lock) = self.iterator.next() { - unsafe { - lock.raw_write(); - let guard = lock.guard(); - - Some(IteratorGuard { - _key: self.key, - guard, - }) - } - } else { - None - } - } - - pub fn lock_last(self) -> Option::Guard<'c>, ThreadKey>> { - self.iterator.last().map(|lock| unsafe { - lock.raw_write(); - let guard = lock.guard(); - - IteratorGuard { - _key: self.key, - guard, - } - }) - } -} - -impl<'c, L: 'c + Iterator, I: 'c + RawLock + Sharable> LockingIterator<'c, L> { - pub fn read_next( - &mut self, - ) -> Option::ReadGuard<'c>, ThreadKey>> { - if let Some(lock) = self.iterator.next() { - unsafe { - lock.raw_read(); - let guard = lock.read_guard(); - - Some(IteratorGuard { - _key: self.key, - guard, - }) - } - } else { - None - } - } - - pub fn read_last(self) -> Option::ReadGuard<'c>, ThreadKey>> { - self.iterator.last().map(|lock| unsafe { - lock.raw_read(); - let guard = lock.read_guard(); - - IteratorGuard { - _key: self.key, - guard, - } - }) - } -} - -impl<'l, L: Iterator> LockingIterator<'l, L> { - pub fn skip_next(&mut self) -> Option { - self.iterator.next() - } - - pub fn skip_mut(&mut self, n: usize) { - for _ in 0..n { - self.iterator.next(); - } - } - - #[must_use] - pub fn size_hint(&self) -> (usize, Option) { - self.iterator.size_hint() - } - - #[must_use] - pub fn enumerate(self) -> LockingIterator<'l, Enumerate> { - self.with_iterator(Iterator::enumerate) - } - - #[must_use] - pub fn skip(self, n: usize) -> LockingIterator<'l, Skip> { - self.with_iterator(|i| i.skip(n)) - } - - #[must_use] - pub fn take(self, n: usize) -> LockingIterator<'l, Take> { - self.with_iterator(|i| i.take(n)) - } - - #[must_use] - pub fn fuse(self) -> LockingIterator<'l, Fuse> { - self.with_iterator(Iterator::fuse) - } -} diff --git a/src/iterator/tuple.rs b/src/iterator/tuple.rs deleted file mode 100644 index 855cdc7..0000000 --- a/src/iterator/tuple.rs +++ /dev/null @@ -1,202 +0,0 @@ -use std::marker::PhantomData; - -use crate::{ - iterator::{IteratorGuard, LockingTuple}, - lockable::{Lockable, RawLock}, - ThreadKey, -}; - -impl<'c, A, B> LockingTuple<'c, A, B> { - const fn transmute(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, ::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, ::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) - } -} -- cgit v1.3.1