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) } }