legion_core/
borrow.rs

1//! Atomic runtime borrow checking module.
2//! These types implement something akin to `RefCell`, but are atomically handled allowing them to
3//! cross thread boundaries.
4use std::cell::UnsafeCell;
5use std::hash::{Hash, Hasher};
6use std::ops::Deref;
7use std::ops::DerefMut;
8use std::sync::atomic::AtomicIsize;
9
10#[cfg(not(debug_assertions))]
11use std::marker::PhantomData;
12
13/// A `RefCell` implementation which is thread safe. This type performs all the standard runtime
14/// borrow checking which would be familiar from using `RefCell`.
15///
16/// `UnsafeCell` is used in this type, but borrow checking is performed using atomic values,
17/// garunteeing safe access across threads.
18///
19/// # Safety
20/// Runtime borrow checking is only conducted in builds with `debug_assertions` enabled. Release
21/// builds assume proper resource access and will cause undefined behavior with improper use.
22pub struct AtomicRefCell<T> {
23    value: UnsafeCell<T>,
24    borrow_state: AtomicIsize,
25}
26
27impl<T: Default> Default for AtomicRefCell<T> {
28    fn default() -> Self { Self::new(T::default()) }
29}
30
31impl<T: std::fmt::Debug> std::fmt::Debug for AtomicRefCell<T> {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        write!(f, "({:?}) {:?}", self.borrow_state, self.value)
34    }
35}
36
37impl<T> AtomicRefCell<T> {
38    pub fn new(value: T) -> Self {
39        AtomicRefCell {
40            value: UnsafeCell::from(value),
41            borrow_state: AtomicIsize::from(0),
42        }
43    }
44
45    /// Retrieve an immutable `Ref` wrapped reference of `&T`.
46    ///
47    /// # Panics
48    ///
49    /// This method panics if this value is already mutably borrowed.
50    ///
51    /// # Safety
52    /// Runtime borrow checking is only conducted in builds with `debug_assertions` enabled. Release
53    /// builds assume proper resource access and will cause undefined behavior with improper use.
54    #[inline(always)]
55    pub fn get(&self) -> Ref<T> { self.try_get().unwrap() }
56
57    /// Unwrap the value from the RefCell and kill it, returning the value.
58    pub fn into_inner(self) -> T { self.value.into_inner() }
59
60    /// Retrieve an immutable `Ref` wrapped reference of `&T`. This is the safe version of `get`
61    /// providing an error result on failure.
62    ///
63    /// # Returns
64    ///
65    /// `Some(T)` if the value can be retrieved.
66    /// `Err` if the value is already mutably borrowed.
67    #[cfg(debug_assertions)]
68    pub fn try_get(&self) -> Result<Ref<T>, String> {
69        loop {
70            let read = self.borrow_state.load(std::sync::atomic::Ordering::SeqCst);
71            if read < 0 {
72                return Err(format!(
73                    "resource already borrowed as mutable: {}",
74                    std::any::type_name::<T>()
75                ));
76            }
77
78            if self.borrow_state.compare_and_swap(
79                read,
80                read + 1,
81                std::sync::atomic::Ordering::SeqCst,
82            ) == read
83            {
84                break;
85            }
86        }
87
88        Ok(Ref::new(Shared::new(&self.borrow_state), unsafe {
89            &*self.value.get()
90        }))
91    }
92
93    /// Retrieve an immutable `Ref` wrapped reference of `&T`. This is the safe version of `get`
94    /// providing an error result on failure.
95    ///
96    /// # Returns
97    ///
98    /// `Some(T)` if the value can be retrieved.
99    /// `Err` if the value is already mutably borrowed.
100    ///
101    /// # Safety
102    ///
103    /// This release version of this function does not perform runtime borrow checking and will
104    /// cause undefined behavior if borrow rules are violated. This means they should be enforced
105    /// on the use of this type.
106    #[cfg(not(debug_assertions))]
107    #[inline(always)]
108    pub fn try_get(&self) -> Result<Ref<T>, &'static str> {
109        Ok(Ref::new(Shared::new(&self.borrow_state), unsafe {
110            &*self.value.get()
111        }))
112    }
113
114    /// Retrieve an mutable `RefMut` wrapped reference of `&mut T`.
115    ///
116    /// # Panics
117    ///
118    /// This method panics if this value is already mutably borrowed.
119    ///
120    /// # Safety
121    /// Runtime borrow checking is only conducted in builds with `debug_assertions` enabled. Release
122    /// builds assume proper resource access and will cause undefined behavior with improper use.
123    #[inline(always)]
124    pub fn get_mut(&self) -> RefMut<T> { self.try_get_mut().unwrap() }
125
126    /// Retrieve a mutable `RefMut` wrapped reference of `&mut T`. This is the safe version of
127    /// `get_mut` providing an error result on failure.
128    ///
129    /// # Returns
130    ///
131    /// `Some(T)` if the value can be retrieved.
132    /// `Err` if the value is already mutably borrowed.
133    ///
134    /// # Safety
135    ///
136    /// This release version of this function does not perform runtime borrow checking and will
137    /// cause undefined behavior if borrow rules are violated. This means they should be enforced
138    /// on the use of this type.
139    #[cfg(debug_assertions)]
140    pub fn try_get_mut(&self) -> Result<RefMut<T>, String> {
141        let borrowed =
142            self.borrow_state
143                .compare_and_swap(0, -1, std::sync::atomic::Ordering::SeqCst);
144        match borrowed {
145            0 => Ok(RefMut::new(Exclusive::new(&self.borrow_state), unsafe {
146                &mut *self.value.get()
147            })),
148            x if x < 0 => Err(format!(
149                "resource already borrowed as mutable: {}",
150                std::any::type_name::<T>()
151            )),
152            _ => Err(format!(
153                "resource already borrowed as immutable: {}",
154                std::any::type_name::<T>()
155            )),
156        }
157    }
158
159    /// Retrieve a mutable `RefMut` wrapped reference of `&mut T`. This is the safe version of
160    /// `get_mut` providing an error result on failure.
161    ///
162    /// # Returns
163    ///
164    /// `Some(T)` if the value can be retrieved.
165    /// `Err` if the value is already mutably borrowed.
166    ///
167    /// # Safety
168    ///
169    /// This release version of this function does not perform runtime borrow checking and will
170    /// cause undefined behavior if borrow rules are violated. This means they should be enforced
171    /// on the use of this type.
172    #[cfg(not(debug_assertions))]
173    #[inline(always)]
174    pub fn try_get_mut(&self) -> Result<RefMut<T>, &'static str> {
175        Ok(RefMut::new(Exclusive::new(&self.borrow_state), unsafe {
176            &mut *self.value.get()
177        }))
178    }
179}
180
181unsafe impl<T: Send> Send for AtomicRefCell<T> {}
182
183unsafe impl<T: Sync> Sync for AtomicRefCell<T> {}
184
185/// Type used for allowing unsafe cloning of internal types
186pub trait UnsafeClone {
187    /// Clone this type unsafely
188    ///
189    /// # Safety
190    /// Types implementing this trait perform clones under an unsafe context.
191    unsafe fn clone(&self) -> Self;
192}
193
194impl<A: UnsafeClone, B: UnsafeClone> UnsafeClone for (A, B) {
195    unsafe fn clone(&self) -> Self { (self.0.clone(), self.1.clone()) }
196}
197
198#[derive(Debug)]
199pub struct Shared<'a> {
200    #[cfg(debug_assertions)]
201    state: &'a AtomicIsize,
202    #[cfg(not(debug_assertions))]
203    state: PhantomData<&'a ()>,
204}
205
206impl<'a> Shared<'a> {
207    #[cfg(debug_assertions)]
208    fn new(state: &'a AtomicIsize) -> Self { Self { state } }
209    #[cfg(not(debug_assertions))]
210    #[inline(always)]
211    fn new(_: &'a AtomicIsize) -> Self { Self { state: PhantomData } }
212}
213
214#[cfg(debug_assertions)]
215impl<'a> Drop for Shared<'a> {
216    fn drop(&mut self) { self.state.fetch_sub(1, std::sync::atomic::Ordering::SeqCst); }
217}
218
219impl<'a> Clone for Shared<'a> {
220    #[inline(always)]
221    fn clone(&self) -> Self {
222        #[cfg(debug_assertions)]
223        self.state.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
224        Shared { state: self.state }
225    }
226}
227
228impl<'a> UnsafeClone for Shared<'a> {
229    unsafe fn clone(&self) -> Self { Clone::clone(&self) }
230}
231
232#[derive(Debug)]
233pub struct Exclusive<'a> {
234    #[cfg(debug_assertions)]
235    state: &'a AtomicIsize,
236    #[cfg(not(debug_assertions))]
237    state: PhantomData<&'a ()>,
238}
239
240impl<'a> Exclusive<'a> {
241    #[cfg(debug_assertions)]
242    fn new(state: &'a AtomicIsize) -> Self { Self { state } }
243    #[cfg(not(debug_assertions))]
244    #[inline(always)]
245    fn new(_: &'a AtomicIsize) -> Self { Self { state: PhantomData } }
246}
247
248#[cfg(debug_assertions)]
249impl<'a> Drop for Exclusive<'a> {
250    fn drop(&mut self) { self.state.fetch_add(1, std::sync::atomic::Ordering::SeqCst); }
251}
252
253impl<'a> UnsafeClone for Exclusive<'a> {
254    #[inline(always)]
255    unsafe fn clone(&self) -> Self {
256        #[cfg(debug_assertions)]
257        self.state.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
258        Exclusive { state: self.state }
259    }
260}
261
262#[derive(Debug)]
263pub struct Ref<'a, T: 'a> {
264    #[allow(dead_code)]
265    // held for drop impl
266    borrow: Shared<'a>,
267    value: &'a T,
268}
269
270impl<'a, T: 'a> Clone for Ref<'a, T> {
271    #[inline(always)]
272    fn clone(&self) -> Self { Ref::new(Clone::clone(&self.borrow), self.value) }
273}
274
275impl<'a, T: 'a> Ref<'a, T> {
276    #[inline(always)]
277    pub fn new(borrow: Shared<'a>, value: &'a T) -> Self { Self { borrow, value } }
278
279    #[inline(always)]
280    pub fn map_into<K: 'a, F: FnMut(&'a T) -> K>(self, mut f: F) -> RefMap<'a, K> {
281        RefMap::new(self.borrow, f(&self.value))
282    }
283
284    #[inline(always)]
285    pub fn map<K: 'a, F: FnMut(&T) -> &K>(&self, mut f: F) -> Ref<'a, K> {
286        Ref::new(Clone::clone(&self.borrow), f(&self.value))
287    }
288
289    /// Deconstructs this mapped borrow to its underlying borrow state and value.
290    ///
291    /// # Safety
292    ///
293    /// Ensure that you still follow all safety guidelines of this mapped ref.
294    #[inline(always)]
295    pub unsafe fn deconstruct(self) -> (Shared<'a>, &'a T) { (self.borrow, self.value) }
296}
297
298impl<'a, T: 'a> Deref for Ref<'a, T> {
299    type Target = T;
300
301    #[inline(always)]
302    fn deref(&self) -> &Self::Target { self.value }
303}
304
305impl<'a, T: 'a> AsRef<T> for Ref<'a, T> {
306    #[inline(always)]
307    fn as_ref(&self) -> &T { self.value }
308}
309
310impl<'a, T: 'a> std::borrow::Borrow<T> for Ref<'a, T> {
311    #[inline(always)]
312    fn borrow(&self) -> &T { self.value }
313}
314
315impl<'a, T> PartialEq for Ref<'a, T>
316where
317    T: 'a + PartialEq,
318{
319    fn eq(&self, other: &Self) -> bool { self.value == other.value }
320}
321impl<'a, T> Eq for Ref<'a, T> where T: 'a + Eq {}
322
323impl<'a, T> PartialOrd for Ref<'a, T>
324where
325    T: 'a + PartialOrd,
326{
327    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
328        self.value.partial_cmp(&other.value)
329    }
330}
331impl<'a, T> Ord for Ref<'a, T>
332where
333    T: 'a + Ord,
334{
335    fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.value.cmp(&other.value) }
336}
337
338impl<'a, T> Hash for Ref<'a, T>
339where
340    T: 'a + Hash,
341{
342    fn hash<H: Hasher>(&self, state: &mut H) { self.value.hash(state); }
343}
344
345#[derive(Debug)]
346pub struct RefMut<'a, T: 'a> {
347    #[allow(dead_code)]
348    // held for drop impl
349    borrow: Exclusive<'a>,
350    value: &'a mut T,
351}
352
353impl<'a, T: 'a> RefMut<'a, T> {
354    #[inline(always)]
355    pub fn new(borrow: Exclusive<'a>, value: &'a mut T) -> Self { Self { borrow, value } }
356
357    #[inline(always)]
358    pub fn map_into<K: 'a, F: FnMut(&mut T) -> K>(mut self, mut f: F) -> RefMapMut<'a, K> {
359        RefMapMut::new(self.borrow, f(&mut self.value))
360    }
361
362    /// Deconstructs this mapped borrow to its underlying borrow state and value.
363    ///
364    /// # Safety
365    ///
366    /// Ensure that you still follow all safety guidelines of this mapped ref.
367    #[inline(always)]
368    pub unsafe fn deconstruct(self) -> (Exclusive<'a>, &'a mut T) { (self.borrow, self.value) }
369
370    #[inline(always)]
371    pub fn split<First, Rest, F: Fn(&'a mut T) -> (&'a mut First, &'a mut Rest)>(
372        self,
373        f: F,
374    ) -> (RefMut<'a, First>, RefMut<'a, Rest>) {
375        let (first, rest) = f(self.value);
376        (
377            RefMut::new(unsafe { self.borrow.clone() }, first),
378            RefMut::new(self.borrow, rest),
379        )
380    }
381}
382
383impl<'a, T: 'a> Deref for RefMut<'a, T> {
384    type Target = T;
385
386    #[inline(always)]
387    fn deref(&self) -> &Self::Target { self.value }
388}
389
390impl<'a, T: 'a> DerefMut for RefMut<'a, T> {
391    #[inline(always)]
392    fn deref_mut(&mut self) -> &mut Self::Target { self.value }
393}
394
395impl<'a, T: 'a> AsRef<T> for RefMut<'a, T> {
396    #[inline(always)]
397    fn as_ref(&self) -> &T { self.value }
398}
399
400impl<'a, T: 'a> AsMut<T> for RefMut<'a, T> {
401    #[inline(always)]
402    fn as_mut(&mut self) -> &mut T { self.value }
403}
404
405impl<'a, T: 'a> std::borrow::Borrow<T> for RefMut<'a, T> {
406    #[inline(always)]
407    fn borrow(&self) -> &T { self.value }
408}
409
410impl<'a, T> PartialEq for RefMut<'a, T>
411where
412    T: 'a + PartialEq,
413{
414    fn eq(&self, other: &Self) -> bool { self.value == other.value }
415}
416impl<'a, T> Eq for RefMut<'a, T> where T: 'a + Eq {}
417
418impl<'a, T> PartialOrd for RefMut<'a, T>
419where
420    T: 'a + PartialOrd,
421{
422    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
423        self.value.partial_cmp(&other.value)
424    }
425}
426impl<'a, T> Ord for RefMut<'a, T>
427where
428    T: 'a + Ord,
429{
430    fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.value.cmp(&other.value) }
431}
432
433impl<'a, T> Hash for RefMut<'a, T>
434where
435    T: 'a + Hash,
436{
437    fn hash<H: Hasher>(&self, state: &mut H) { self.value.hash(state); }
438}
439
440#[derive(Debug)]
441pub struct RefMap<'a, T: 'a> {
442    #[allow(dead_code)]
443    // held for drop impl
444    borrow: Shared<'a>,
445    value: T,
446}
447
448impl<'a, T: 'a> RefMap<'a, T> {
449    #[inline(always)]
450    pub fn new(borrow: Shared<'a>, value: T) -> Self { Self { borrow, value } }
451
452    #[inline(always)]
453    pub fn map_into<K: 'a, F: FnMut(&mut T) -> K>(mut self, mut f: F) -> RefMap<'a, K> {
454        RefMap::new(self.borrow, f(&mut self.value))
455    }
456
457    /// Deconstructs this mapped borrow to its underlying borrow state and value.
458    ///
459    /// # Safety
460    ///
461    /// Ensure that you still follow all safety guidelines of this  mapped ref.
462    #[inline(always)]
463    pub unsafe fn deconstruct(self) -> (Shared<'a>, T) { (self.borrow, self.value) }
464}
465
466impl<'a, T: 'a> Deref for RefMap<'a, T> {
467    type Target = T;
468
469    #[inline(always)]
470    fn deref(&self) -> &Self::Target { &self.value }
471}
472
473impl<'a, T: 'a> AsRef<T> for RefMap<'a, T> {
474    #[inline(always)]
475    fn as_ref(&self) -> &T { &self.value }
476}
477
478impl<'a, T: 'a> std::borrow::Borrow<T> for RefMap<'a, T> {
479    #[inline(always)]
480    fn borrow(&self) -> &T { &self.value }
481}
482
483#[derive(Debug)]
484pub struct RefMapMut<'a, T: 'a> {
485    #[allow(dead_code)]
486    // held for drop impl
487    borrow: Exclusive<'a>,
488    value: T,
489}
490
491impl<'a, T: 'a> RefMapMut<'a, T> {
492    #[inline(always)]
493    pub fn new(borrow: Exclusive<'a>, value: T) -> Self { Self { borrow, value } }
494
495    #[inline(always)]
496    pub fn map_into<K: 'a, F: FnMut(&mut T) -> K>(mut self, mut f: F) -> RefMapMut<'a, K> {
497        RefMapMut {
498            value: f(&mut self.value),
499            borrow: self.borrow,
500        }
501    }
502
503    /// Deconstructs this mapped borrow to its underlying borrow state and value.
504    ///
505    /// # Safety
506    ///
507    /// Ensure that you still follow all safety guidelines of this mutable mapped ref.
508    #[inline(always)]
509    pub unsafe fn deconstruct(self) -> (Exclusive<'a>, T) { (self.borrow, self.value) }
510}
511
512impl<'a, T: 'a> Deref for RefMapMut<'a, T> {
513    type Target = T;
514
515    #[inline(always)]
516    fn deref(&self) -> &Self::Target { &self.value }
517}
518
519impl<'a, T: 'a> DerefMut for RefMapMut<'a, T> {
520    #[inline(always)]
521    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.value }
522}
523
524impl<'a, T: 'a> AsRef<T> for RefMapMut<'a, T> {
525    #[inline(always)]
526    fn as_ref(&self) -> &T { &self.value }
527}
528
529impl<'a, T: 'a> AsMut<T> for RefMapMut<'a, T> {
530    #[inline(always)]
531    fn as_mut(&mut self) -> &mut T { &mut self.value }
532}
533
534impl<'a, T: 'a> std::borrow::Borrow<T> for RefMapMut<'a, T> {
535    #[inline(always)]
536    fn borrow(&self) -> &T { &self.value }
537}
538
539#[derive(Debug)]
540pub struct RefIter<'a, T: 'a, I: Iterator<Item = &'a T>> {
541    #[allow(dead_code)]
542    // held for drop impl
543    borrow: Shared<'a>,
544    iter: I,
545}
546
547impl<'a, T: 'a, I: Iterator<Item = &'a T>> RefIter<'a, T, I> {
548    #[inline(always)]
549    pub fn new(borrow: Shared<'a>, iter: I) -> Self { Self { borrow, iter } }
550}
551
552impl<'a, T: 'a, I: Iterator<Item = &'a T>> Iterator for RefIter<'a, T, I> {
553    type Item = Ref<'a, T>;
554
555    #[inline(always)]
556    fn next(&mut self) -> Option<Self::Item> {
557        if let Some(item) = self.iter.next() {
558            Some(Ref::new(Clone::clone(&self.borrow), item))
559        } else {
560            None
561        }
562    }
563
564    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
565}
566
567impl<'a, T: 'a, I: Iterator<Item = &'a T> + ExactSizeIterator> ExactSizeIterator
568    for RefIter<'a, T, I>
569{
570}
571
572#[derive(Debug)]
573enum TryIter<State, T> {
574    Found { borrow: State, iter: T },
575    Missing(usize),
576}
577
578#[derive(Debug)]
579pub struct TryRefIter<'a, T: 'a, I: Iterator<Item = &'a T>> {
580    inner: TryIter<Shared<'a>, I>,
581}
582
583impl<'a, T: 'a, I: Iterator<Item = &'a T>> TryRefIter<'a, T, I> {
584    #[inline(always)]
585    pub(crate) fn found(borrow: Shared<'a>, iter: I) -> Self {
586        Self {
587            inner: TryIter::Found { borrow, iter },
588        }
589    }
590
591    #[inline(always)]
592    pub(crate) fn missing(count: usize) -> Self {
593        Self {
594            inner: TryIter::Missing(count),
595        }
596    }
597}
598
599impl<'a, T: 'a, I: Iterator<Item = &'a T>> Iterator for TryRefIter<'a, T, I> {
600    type Item = Option<Ref<'a, T>>;
601
602    #[inline(always)]
603    fn next(&mut self) -> Option<Self::Item> {
604        Some(match self.inner {
605            TryIter::Found {
606                ref borrow,
607                ref mut iter,
608                ..
609            } => Some(Ref::new(Clone::clone(borrow), iter.next()?)),
610            TryIter::Missing(ref mut n) => {
611                *n = n.checked_sub(1)?;
612                None
613            }
614        })
615    }
616
617    fn size_hint(&self) -> (usize, Option<usize>) {
618        match self.inner {
619            TryIter::Found { ref iter, .. } => iter.size_hint(),
620            TryIter::Missing(n) => (n, Some(n)),
621        }
622    }
623}
624
625impl<'a, T: 'a, I: Iterator<Item = &'a T> + ExactSizeIterator> ExactSizeIterator
626    for TryRefIter<'a, T, I>
627{
628}
629
630#[derive(Debug)]
631pub struct RefIterMut<'a, T: 'a, I: Iterator<Item = &'a mut T>> {
632    #[allow(dead_code)]
633    // held for drop impl
634    borrow: Exclusive<'a>,
635    iter: I,
636}
637
638impl<'a, T: 'a, I: Iterator<Item = &'a mut T>> RefIterMut<'a, T, I> {
639    #[inline(always)]
640    pub fn new(borrow: Exclusive<'a>, iter: I) -> Self { Self { borrow, iter } }
641}
642
643impl<'a, T: 'a, I: Iterator<Item = &'a mut T>> Iterator for RefIterMut<'a, T, I> {
644    type Item = RefMut<'a, T>;
645
646    #[inline(always)]
647    fn next(&mut self) -> Option<Self::Item> {
648        if let Some(item) = self.iter.next() {
649            Some(RefMut::new(unsafe { self.borrow.clone() }, item))
650        } else {
651            None
652        }
653    }
654
655    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
656}
657
658impl<'a, T: 'a, I: Iterator<Item = &'a mut T> + ExactSizeIterator> ExactSizeIterator
659    for RefIterMut<'a, T, I>
660{
661}
662
663#[derive(Debug)]
664pub struct TryRefIterMut<'a, T: 'a, I: Iterator<Item = &'a mut T>> {
665    inner: TryIter<Exclusive<'a>, I>,
666}
667
668impl<'a, T: 'a, I: Iterator<Item = &'a mut T>> TryRefIterMut<'a, T, I> {
669    #[inline(always)]
670    pub(crate) fn found(borrow: Exclusive<'a>, iter: I) -> Self {
671        Self {
672            inner: TryIter::Found { borrow, iter },
673        }
674    }
675
676    #[inline(always)]
677    pub(crate) fn missing(count: usize) -> Self {
678        Self {
679            inner: TryIter::Missing(count),
680        }
681    }
682}
683
684impl<'a, T: 'a, I: Iterator<Item = &'a mut T>> Iterator for TryRefIterMut<'a, T, I> {
685    type Item = Option<RefMut<'a, T>>;
686
687    #[inline(always)]
688    fn next(&mut self) -> Option<Self::Item> {
689        Some(match self.inner {
690            TryIter::Found {
691                ref borrow,
692                ref mut iter,
693                ..
694            } => Some(RefMut::new(unsafe { borrow.clone() }, iter.next()?)),
695            TryIter::Missing(ref mut n) => {
696                *n = n.checked_sub(1)?;
697                None
698            }
699        })
700    }
701
702    fn size_hint(&self) -> (usize, Option<usize>) {
703        match self.inner {
704            TryIter::Found { ref iter, .. } => iter.size_hint(),
705            TryIter::Missing(n) => (n, Some(n)),
706        }
707    }
708}
709
710impl<'a, T: 'a, I: Iterator<Item = &'a mut T> + ExactSizeIterator> ExactSizeIterator
711    for TryRefIterMut<'a, T, I>
712{
713}
714
715/// A set of RefMaps
716#[derive(Debug)]
717pub struct RefMapSet<'a, T: 'a> {
718    #[allow(dead_code)]
719    // held for drop impl
720    borrow: Vec<Shared<'a>>,
721    value: T,
722}
723
724impl<'a, T: 'a> RefMapSet<'a, T> {
725    #[inline(always)]
726    pub fn new(borrow: Vec<Shared<'a>>, value: T) -> Self { Self { borrow, value } }
727
728    #[inline(always)]
729    pub fn map_into<K: 'a, F: FnMut(&mut T) -> K>(mut self, mut f: F) -> RefMapSet<'a, K> {
730        RefMapSet::new(self.borrow, f(&mut self.value))
731    }
732
733    /// Deconstructs this mapped borrow to its underlying borrow state and value.
734    ///
735    /// # Safety
736    ///
737    /// Ensure that you still follow all safety guidelines of this  mapped ref.
738    #[inline(always)]
739    pub unsafe fn deconstruct(self) -> (Vec<Shared<'a>>, T) { (self.borrow, self.value) }
740}
741
742impl<'a, T: 'a> Deref for RefMapSet<'a, T> {
743    type Target = T;
744
745    #[inline(always)]
746    fn deref(&self) -> &Self::Target { &self.value }
747}
748
749impl<'a, T: 'a> AsRef<T> for RefMapSet<'a, T> {
750    #[inline(always)]
751    fn as_ref(&self) -> &T { &self.value }
752}
753
754impl<'a, T: 'a> std::borrow::Borrow<T> for RefMapSet<'a, T> {
755    #[inline(always)]
756    fn borrow(&self) -> &T { &self.value }
757}
758
759/// A set of RefMapMuts
760#[derive(Debug)]
761pub struct RefMapMutSet<'a, T: 'a> {
762    #[allow(dead_code)]
763    // held for drop impl
764    borrow: Vec<Exclusive<'a>>,
765    value: T,
766}
767
768impl<'a, T: 'a> RefMapMutSet<'a, T> {
769    #[inline(always)]
770    pub fn new(borrow: Vec<Exclusive<'a>>, value: T) -> Self { Self { borrow, value } }
771
772    #[inline(always)]
773    pub fn map_into<K: 'a, F: FnMut(&mut T) -> K>(mut self, mut f: F) -> RefMapMutSet<'a, K> {
774        RefMapMutSet {
775            value: f(&mut self.value),
776            borrow: self.borrow,
777        }
778    }
779
780    /// Deconstructs this mapped borrow to its underlying borrow state and value.
781    ///
782    /// # Safety
783    ///
784    /// Ensure that you still follow all safety guidelines of this mutable mapped ref.
785    #[inline(always)]
786    pub unsafe fn deconstruct(self) -> (Vec<Exclusive<'a>>, T) { (self.borrow, self.value) }
787}
788
789impl<'a, T: 'a> Deref for RefMapMutSet<'a, T> {
790    type Target = T;
791
792    #[inline(always)]
793    fn deref(&self) -> &Self::Target { &self.value }
794}
795
796impl<'a, T: 'a> DerefMut for RefMapMutSet<'a, T> {
797    #[inline(always)]
798    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.value }
799}
800
801impl<'a, T: 'a> AsRef<T> for RefMapMutSet<'a, T> {
802    #[inline(always)]
803    fn as_ref(&self) -> &T { &self.value }
804}
805
806impl<'a, T: 'a> std::borrow::Borrow<T> for RefMapMutSet<'a, T> {
807    #[inline(always)]
808    fn borrow(&self) -> &T { &self.value }
809}