qcell/
qcell.rs

1use core::cell::UnsafeCell;
2use core::marker::PhantomPinned;
3use core::pin::Pin;
4use core::sync::atomic::{AtomicUsize, Ordering};
5
6#[cfg(feature = "alloc")]
7use alloc::boxed::Box;
8
9// Ensure the alignment is 2 so we can use odd-numbered IDs for those
10// created via `QCellOwnerSeq`.
11#[repr(align(2))]
12#[derive(Clone, Copy)]
13struct OwnerIDTarget {
14    _data: u16,
15}
16
17const MAGIC_OWNER_ID_TARGET: OwnerIDTarget = OwnerIDTarget { _data: 0xCE11 };
18
19#[cold]
20#[inline(never)]
21fn bad_owner_panic() -> ! {
22    panic!("QCell accessed with incorrect owner");
23}
24
25macro_rules! owner_check {
26    ($owner:expr $(, $qcell:expr)+) => {
27        $(
28            if $qcell.owner.0 != $owner.id().0 {
29                bad_owner_panic();
30            }
31        )+
32    }
33}
34
35#[cold]
36#[inline(never)]
37fn not_distinct_panic() -> ! {
38    panic!("Illegal to borrow same QCell twice with rw2() or rw3()");
39}
40
41macro_rules! distinct_check {
42    ($qc1:expr, $qc2:expr) => {{
43        let qc1 = $qc1 as *const _ as *const () as usize;
44        let qc2 = $qc2 as *const _ as *const () as usize;
45        if qc1 == qc2 {
46            not_distinct_panic();
47        }
48    }};
49    ($qc1:expr, $qc2:expr, $qc3:expr) => {{
50        let qc1 = $qc1 as *const _ as *const () as usize;
51        let qc2 = $qc2 as *const _ as *const () as usize;
52        let qc3 = $qc3 as *const _ as *const () as usize;
53        if qc1 == qc2 || qc2 == qc3 || qc3 == qc1 {
54            not_distinct_panic();
55        }
56    }};
57}
58
59/// Internal ID associated with a [`QCell`] owner.
60///
61/// The only purpose of this is to create [`QCell`] instances without
62/// requiring a borrow on the owner.  A [`QCellOwnerID`] can be passed
63/// to any code that needs to create [`QCell`] instances.  However to
64/// access those [`QCell`] instances after creation will still require
65/// a borrow on the original owner.  Create a [`QCellOwnerID`] from an
66/// owner using `owner.into()` or `owner.id()`.
67///
68/// # Safety
69///
70/// Whilst the existence of this type does mean that an ID can exist
71/// longer than than the owner, all that allows is new [`QCell`]
72/// instances to be created after the owner has gone.  But [`QCell`]
73/// instances can outlive the owner in any case, so this makes no
74/// difference to safety.
75#[derive(Clone, Copy, PartialEq, Eq, Hash)]
76pub struct QCellOwnerID(usize);
77
78impl QCellOwnerID {
79    /// Create a new cell owned by this owner-ID.  See also
80    /// [`QCell::new`].
81    ///
82    /// [`QCell::new`]: struct.QCell.html
83    pub fn cell<T>(self, value: T) -> QCell<T> {
84        QCell {
85            value: UnsafeCell::new(value),
86            owner: self,
87        }
88    }
89}
90
91#[cfg(feature = "alloc")]
92impl From<&QCellOwner> for QCellOwnerID {
93    fn from(owner: &QCellOwner) -> Self {
94        owner.id()
95    }
96}
97
98impl From<&QCellOwnerSeq> for QCellOwnerID {
99    fn from(owner: &QCellOwnerSeq) -> Self {
100        owner.id()
101    }
102}
103
104impl From<Pin<&QCellOwnerPinned>> for QCellOwnerID {
105    fn from(owner: Pin<&QCellOwnerPinned>) -> Self {
106        owner.id()
107    }
108}
109
110/// Cell whose contents is owned (for borrowing purposes) by a
111/// [`QCellOwner`], a [`QCellOwnerSeq`] or a [`QCellOwnerPinned`].
112///
113/// To borrow from this cell, use the borrowing calls on the owner
114/// instance that was used to create it.  For [`QCellOwner`], there
115/// are also convenience methods [`QCell::ro`] and [`QCell::rw`].  See
116/// also [crate documentation](index.html).
117///
118/// [`QCellOwner`]: struct.QCellOwner.html
119/// [`QCell::ro`]: struct.QCell.html#method.ro
120/// [`QCell::rw`]: struct.QCell.html#method.rw
121pub struct QCell<T: ?Sized> {
122    owner: QCellOwnerID,
123    value: UnsafeCell<T>,
124}
125
126// QCell already automatically implements Send, but not Sync.
127// We can add this implementation though, since it's fine to
128// send a &QCell to another thread, and even mutably borrow the value
129// there, as long as T is Send and Sync.
130//
131// The reason why QCell<T>'s impl of Sync requires T: Send + Sync
132// instead of just T: Sync is that QCell provides interior mutability.
133// If you send a &QCell<T> (and its owner) to a different thread, you
134// can call .rw() to get a &mut T, and use std::mem::swap() to move
135// the T, effectively sending the T to that other thread. That's not
136// allowed if T: !Send.
137//
138// Note that the bounds on T for QCell<T>'s impl of Sync are the same
139// as those of std::sync::RwLock<T>. That's not a coincidence.
140// The way these types let you access T concurrently is the same,
141// even though the locking mechanisms are different.
142unsafe impl<T: Send + Sync + ?Sized> Sync for QCell<T> {}
143
144impl<T> QCell<T> {
145    /// Create a new [`QCell`] owned for borrowing purposes by the
146    /// owner with the given [`QCellOwnerID`], or a type that can be
147    /// converted into a [`QCellOwnerID`], such as `&owner`.  So calls
148    /// will typically take the form `QCell::new(&owner, value)` or
149    /// `QCell::new(owner_id, value)`.
150    #[inline]
151    pub fn new(id: impl Into<QCellOwnerID>, value: T) -> QCell<T> {
152        QCell {
153            value: UnsafeCell::new(value),
154            owner: id.into(),
155        }
156    }
157
158    /// Destroy the cell and return the contained value
159    ///
160    /// Safety: Since this consumes the cell, there can be no other
161    /// references to the cell or the data at this point.
162    #[inline]
163    pub fn into_inner(self) -> T {
164        self.value.into_inner()
165    }
166}
167
168#[cfg(feature = "alloc")]
169impl<T: ?Sized> QCell<T> {
170    /// Convenience method to borrow a cell immutably when the owner
171    /// is a [`QCellOwner`].  Equivalent to [`QCellOwner::ro`].  See
172    /// [`QCellOwnerSeq::ro`] or [`QCellOwnerPinned::ro`] to borrow
173    /// for other owner types.
174    #[inline]
175    pub fn ro<'a>(&'a self, owner: &'a QCellOwner) -> &'a T {
176        owner.ro(self)
177    }
178
179    /// Convenience method to borrow a cell mutably when the owner is
180    /// a [`QCellOwner`].  Equivalent to [`QCellOwner::rw`].  See
181    /// [`QCellOwnerSeq::rw`] or [`QCellOwnerPinned::rw`] to borrow
182    /// for other owner types.
183    #[inline]
184    pub fn rw<'a>(&'a self, owner: &'a mut QCellOwner) -> &'a mut T {
185        owner.rw(self)
186    }
187
188    /// Returns a mutable reference to the underlying data
189    ///
190    /// Note that this is only useful at the beginning-of-life or
191    /// end-of-life of the cell when you have exclusive access to it.
192    /// Normally you'd use [`QCell::rw`] or [`QCellOwner::rw`] to get
193    /// a mutable reference to the contents of the cell.
194    ///
195    /// Safety: This call borrows `QCell` mutably which guarantees
196    /// that we possess the only reference.  This means that there can
197    /// be no active borrows of other forms, even ones obtained using
198    /// an immutable reference.
199    #[inline]
200    pub fn get_mut(&mut self) -> &mut T {
201        self.value.get_mut()
202    }
203}
204
205/// Borrowing-owner of zero or more [`QCell`] instances.
206///
207/// The owner will have a temporally unique ID associated with it to
208/// detect use of the wrong owner to access a cell at runtime, which
209/// is a programming error.  Temporally unique means that at any one
210/// time, only one owner will hold that ID.  This type derives the
211/// owner ID from the address of an internal memory allocation which
212/// this owner holds until it is dropped, which ensures that the ID is
213/// temporally unique.  The allocation is aligned to ensure that its
214/// ID cannot collide with those created using [`QCellOwnerSeq`].
215///
216/// In a `no_std` environment this requires the `alloc` feature
217/// because it allocates memory.  For a `no_std` environment without
218/// `alloc`, consider using [`QCellOwnerSeq`] or [`QCellOwnerPinned`].
219///
220/// # Safety
221///
222/// This should successfully defend against all malicious and unsafe
223/// use.  If not, please raise an issue.  The same unique ID may later
224/// be allocated to someone else once you drop the returned owner, but
225/// this cannot be abused to cause unsafe access to cells because
226/// there will still be only one owner active at any one time with
227/// that ID.  Also it cannot be used maliciously to access cells which
228/// don't belong to the new caller, because you also need a reference
229/// to the cells.  So for example if you have a graph of cells that is
230/// only accessible through a private structure, then if someone else
231/// gets the same owner ID later, it makes no difference, because they
232/// have no way to get a reference to those cells.  In any case, you
233/// are probably going to drop all those cells at the same time as
234/// dropping the owner, because they are no longer of any use without
235/// the owner ID.
236///
237/// See [crate documentation](index.html).
238#[cfg(feature = "alloc")]
239#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
240pub struct QCellOwner {
241    // `Box` should be enough to ensure that the address is unique and
242    // stable, but add `Pin` as a safeguard against any future
243    // optimisation of `Box`.
244    handle: Pin<Box<OwnerIDTarget>>,
245}
246
247#[cfg(feature = "alloc")]
248#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
249impl Default for QCellOwner {
250    fn default() -> Self {
251        QCellOwner::new()
252    }
253}
254
255#[cfg(feature = "alloc")]
256#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
257impl QCellOwner {
258    /// Create an owner that can be used for creating many [`QCell`]
259    /// instances.
260    #[inline]
261    pub fn new() -> Self {
262        let handle = Box::pin(MAGIC_OWNER_ID_TARGET);
263        Self { handle }
264    }
265
266    /// Get the internal owner ID.  This may be used to create [`QCell`]
267    /// instances without needing a borrow on this structure, which is
268    /// useful if this structure is already borrowed.
269    #[inline]
270    pub fn id(&self) -> QCellOwnerID {
271        let raw_ptr: *const OwnerIDTarget = &*self.handle;
272        QCellOwnerID(raw_ptr as usize)
273    }
274
275    /// Create a new cell owned by this owner instance.  See also
276    /// [`QCell::new`].
277    #[inline]
278    pub fn cell<T>(&self, value: T) -> QCell<T> {
279        let id: QCellOwnerID = self.into();
280        id.cell(value)
281    }
282
283    /// Borrow contents of a [`QCell`] immutably (read-only).  Many
284    /// [`QCell`] instances can be borrowed immutably at the same time
285    /// from the same owner.  Panics if the [`QCell`] is not owned by
286    /// this [`QCellOwner`].
287    #[inline]
288    pub fn ro<'a, T: ?Sized>(&'a self, qc: &'a QCell<T>) -> &'a T {
289        owner_check!(self, qc);
290        unsafe { &*qc.value.get() }
291    }
292
293    /// Borrow contents of a [`QCell`] mutably (read-write).  Only one
294    /// [`QCell`] at a time can be borrowed from the owner using this
295    /// call.  The returned reference must go out of scope before
296    /// another can be borrowed.  Panics if the [`QCell`] is not owned
297    /// by this [`QCellOwner`].
298    #[inline]
299    pub fn rw<'a, T: ?Sized>(&'a mut self, qc: &'a QCell<T>) -> &'a mut T {
300        owner_check!(self, qc);
301        unsafe { &mut *qc.value.get() }
302    }
303
304    /// Borrow contents of two [`QCell`] instances mutably.  Panics if
305    /// the two [`QCell`] instances point to the same memory.  Panics
306    /// if either [`QCell`] is not owned by this [`QCellOwner`].
307    #[inline]
308    pub fn rw2<'a, T: ?Sized, U: ?Sized>(
309        &'a mut self,
310        qc1: &'a QCell<T>,
311        qc2: &'a QCell<U>,
312    ) -> (&'a mut T, &'a mut U) {
313        owner_check!(self, qc1, qc2);
314        distinct_check!(qc1, qc2);
315        unsafe { (&mut *qc1.value.get(), &mut *qc2.value.get()) }
316    }
317
318    /// Borrow contents of three [`QCell`] instances mutably.  Panics
319    /// if any pair of [`QCell`] instances point to the same memory.
320    /// Panics if any [`QCell`] is not owned by this [`QCellOwner`].
321    #[inline]
322    pub fn rw3<'a, T: ?Sized, U: ?Sized, V: ?Sized>(
323        &'a mut self,
324        qc1: &'a QCell<T>,
325        qc2: &'a QCell<U>,
326        qc3: &'a QCell<V>,
327    ) -> (&'a mut T, &'a mut U, &'a mut V) {
328        owner_check!(self, qc1, qc2, qc3);
329        distinct_check!(qc1, qc2, qc3);
330        unsafe {
331            (
332                &mut *qc1.value.get(),
333                &mut *qc2.value.get(),
334                &mut *qc3.value.get(),
335            )
336        }
337    }
338}
339
340// Used to generate a unique QCellOwnerID number for each
341// QCellOwnerSeq.  Start at index 1 and increment by 2 each time so
342// the number is always odd to ensure it will never conflict with the
343// address of a OwnerIDTarget.
344static FAST_QCELLOWNER_ID: AtomicUsize = AtomicUsize::new(1);
345
346/// Borrowing-owner of zero or more [`QCell`] instances, using an ID
347/// sequence.
348///
349/// The owner will have a unique(-ish) ID associated with it to detect
350/// use of the wrong owner to access a cell at runtime, which is a
351/// programming error.  This type allocates the owner ID from a
352/// wrapping sequence sourced from a global atomic variable, so it is
353/// very fast to allocate.
354///
355/// # Safety
356///
357/// A malicious coder could cause an intentional ID collision, e.g. by
358/// creating 2^63 owners on a 64-bit build (or 2^31 on 32-bit, etc),
359/// which would cause the ID to wrap.  This would allow that coder to
360/// cause undefined behaviour in their own code.  So at a stretch this
361/// could allow a coder to hide unsound code from a safety review.
362/// Because of that the [`QCellOwnerSeq::new`] method is marked as
363/// `unsafe`.  However it is not possible to use it unsafely by
364/// accident, only through making an intentional, determined and
365/// CPU-intensive effort to exploit it.
366///
367/// See [crate documentation](index.html).
368pub struct QCellOwnerSeq {
369    id: QCellOwnerID,
370}
371
372// Default implementation not possible, due to `unsafe`
373
374impl QCellOwnerSeq {
375    /// Create an owner that can be used for creating many [`QCell`]
376    /// instances.
377    ///
378    /// # Safety
379    ///
380    /// The contract with the caller is that the caller must not
381    /// intentionally create an owner-ID collision and exploit it to
382    /// create undefined behaviour.  The caller could do this by
383    /// creating 2^63 more owners on a 64-bit build (or 2^31 on
384    /// 32-bit, etc), causing the ID to wrap, and then using two
385    /// owners that they know to have the same ID to access the same
386    /// memory mutably from two references at the same time.  This is
387    /// totally impossible to do by accident, so any normal use of
388    /// this call will be 100% safe.
389    ///
390    /// To get unsound behaviour requires both an owner ID collision
391    /// (which might just about happen by accident in very unusual
392    /// situations), and then also intentionally using the wrong owner
393    /// to access a cell.  Usually using the wrong owner to access a
394    /// cell would cause an immediate panic because it is a
395    /// programming error.  It is extremely unlikely that there would
396    /// always be the same ID collision in testing, so this panic
397    /// would soon be fixed.  Once it is fixed, there is absolutely no
398    /// way that even an accidental collision could cause any unsound
399    /// behaviour, because the bug has been eliminated, and the
400    /// correct owner is always used to access each cell.
401    #[inline]
402    pub unsafe fn new() -> Self {
403        // Must increment by 2 to ensure we never collide with an ID
404        // derived from the address of an `OwnerIDTarget`.  Use
405        // `Relaxed` ordering because we don't care who gets which ID,
406        // just that they are different.
407        Self {
408            id: QCellOwnerID(FAST_QCELLOWNER_ID.fetch_add(2, Ordering::Relaxed)),
409        }
410    }
411
412    /// Get the internal owner ID.  This may be used to create
413    /// [`QCell`] instances without needing a borrow on this
414    /// structure, which is useful if this structure is already
415    /// borrowed.
416    #[inline]
417    pub fn id(&self) -> QCellOwnerID {
418        self.id
419    }
420
421    /// Create a new cell owned by this owner instance.  See also
422    /// [`QCell::new`].
423    ///
424    /// [`QCell::new`]: struct.QCell.html
425    #[inline]
426    pub fn cell<T>(&self, value: T) -> QCell<T> {
427        self.id.cell(value)
428    }
429
430    /// Borrow contents of a [`QCell`] immutably (read-only).  Many
431    /// [`QCell`] instances can be borrowed immutably at the same time
432    /// from the same owner.  Panics if the [`QCell`] is not owned by
433    /// this [`QCellOwnerSeq`].
434    #[inline]
435    pub fn ro<'a, T: ?Sized>(&'a self, qc: &'a QCell<T>) -> &'a T {
436        owner_check!(self, qc);
437        unsafe { &*qc.value.get() }
438    }
439
440    /// Borrow contents of a [`QCell`] mutably (read-write).  Only one
441    /// [`QCell`] at a time can be borrowed from the owner using this
442    /// call.  The returned reference must go out of scope before
443    /// another can be borrowed.  Panics if the [`QCell`] is not owned
444    /// by this [`QCellOwnerSeq`].
445    #[inline]
446    pub fn rw<'a, T: ?Sized>(&'a mut self, qc: &'a QCell<T>) -> &'a mut T {
447        owner_check!(self, qc);
448        unsafe { &mut *qc.value.get() }
449    }
450
451    /// Borrow contents of two [`QCell`] instances mutably.  Panics if
452    /// the two [`QCell`] instances point to the same memory.  Panics
453    /// if either [`QCell`] is not owned by this [`QCellOwnerSeq`].
454    #[inline]
455    pub fn rw2<'a, T: ?Sized, U: ?Sized>(
456        &'a mut self,
457        qc1: &'a QCell<T>,
458        qc2: &'a QCell<U>,
459    ) -> (&'a mut T, &'a mut U) {
460        owner_check!(self, qc1, qc2);
461        distinct_check!(qc1, qc2);
462        unsafe { (&mut *qc1.value.get(), &mut *qc2.value.get()) }
463    }
464
465    /// Borrow contents of three [`QCell`] instances mutably.  Panics
466    /// if any pair of [`QCell`] instances point to the same memory.
467    /// Panics if any [`QCell`] is not owned by this
468    /// [`QCellOwnerSeq`].
469    #[inline]
470    pub fn rw3<'a, T: ?Sized, U: ?Sized, V: ?Sized>(
471        &'a mut self,
472        qc1: &'a QCell<T>,
473        qc2: &'a QCell<U>,
474        qc3: &'a QCell<V>,
475    ) -> (&'a mut T, &'a mut U, &'a mut V) {
476        owner_check!(self, qc1, qc2, qc3);
477        distinct_check!(qc1, qc2, qc3);
478        unsafe {
479            (
480                &mut *qc1.value.get(),
481                &mut *qc2.value.get(),
482                &mut *qc3.value.get(),
483            )
484        }
485    }
486}
487
488/// Borrowing-owner of zero or more [`QCell`] instances, based on a
489/// pinned struct
490///
491/// This type uses its own memory address to provide a unique owner
492/// ID, which requires no allocations and only 2 bytes of storage.  So
493/// this is suitable for a `no_std` environment without an allocator.
494/// The owner can be created on the stack, or on the heap, as
495/// required.  To ensure its memory address cannot change while cells
496/// exist that are owned by it, it requires itself to be pinned before
497/// any operation interacting with the ID is attempted.
498///
499/// There are many ways to safely pin a value, such as
500/// [`Box::pin`](https://doc.rust-lang.org/std/boxed/struct.Box.html#method.pin),
501/// [`pin-utils::pin_mut!`](https://docs.rs/pin-utils/latest/pin_utils/macro.pin_mut.html),
502/// [`tokio::pin!`](https://docs.rs/tokio/latest/tokio/macro.pin.html),
503/// or the [`pin-project`](https://github.com/taiki-e/pin-project)
504/// crate.
505///
506/// The following example uses the `pin_mut!` macro from the
507/// `pin-utils` crate:
508///
509/// ```
510/// use pin_utils::pin_mut;
511/// use qcell::{QCell, QCellOwnerPinned};
512///# use std::rc::Rc;
513///# use std::pin::Pin;
514/// let mut owner = QCellOwnerPinned::new();
515/// pin_mut!(owner);
516/// let item = Rc::new(owner.as_ref().cell(Vec::<u8>::new()));
517/// owner.as_mut().rw(&item).push(1);
518/// test(owner, &item);
519///
520/// fn test(owner: Pin<&mut QCellOwnerPinned>, item: &Rc<QCell<Vec<u8>>>) {
521///     owner.rw(&item).push(2);
522/// }
523/// ```
524///
525/// This example incorporates the [`QCellOwnerPinned`] into a larger
526/// structure kept on the stack, and accesses it using the
527/// [`pin-project`](https://github.com/taiki-e/pin-project) crate:
528///
529/// ```
530/// use crate::qcell::{QCell, QCellOwnerPinned};
531/// use pin_project::pin_project;
532/// use pin_utils::pin_mut;
533///# use std::pin::Pin;
534///# use std::rc::Rc;
535///
536/// #[pin_project]
537/// struct MyStruct {
538///     _misc: usize,  // Unpinned value
539///     #[pin]
540///     owner: QCellOwnerPinned,
541/// }
542///
543/// let mystruct = MyStruct {
544///     _misc: 0,
545///     owner: QCellOwnerPinned::new(),
546/// };
547///
548/// pin_mut!(mystruct);
549///
550/// let item = Rc::new(
551///     mystruct.as_mut().project().owner.as_ref().cell(Vec::<u8>::new())
552/// );
553/// mystruct.as_mut().project().owner.rw(&item).push(1);
554/// test(mystruct.as_mut().project().owner, &item);
555///
556/// fn test(owner: Pin<&mut QCellOwnerPinned>, item: &Rc<QCell<Vec<u8>>>) {
557///     owner.rw(&item).push(2);
558/// }
559/// ```
560///
561/// # Safety
562///
563/// After the owner is pinned, its address is used as a temporally
564/// unique ID.  This detects use of the wrong owner to access a cell
565/// at runtime, which is a programming error.
566///
567/// Note that even without `Pin`, this would still be sound, because
568/// there would still be only one owner valid at any one time with the
569/// same ID, because two owners cannot occupy the same memory.
570/// However `Pin` is useful because it helps the coder avoid
571/// accidentally moving an owner from one address to another without
572/// realizing it, and causing panics due to the changed owner ID.
573///
574/// The ID generated from this type cannot clash with IDs generated by
575/// [`QCellOwner`] (which is also based on the addresses of occupied
576/// memory, but always on the heap), or [`QCellOwnerSeq`] (which only
577/// allocates odd IDs, which cannot clash with addresses from this
578/// type which always have an alignment of 2).  So this should
579/// successfully defend against all malicious and unsafe use.  If not,
580/// please raise an issue.
581///
582/// The same unique ID may later be allocated to someone else once you
583/// drop the returned owner, but this cannot be abused to cause unsafe
584/// access to cells because there will still be only one owner active
585/// at any one time with that ID.  Also it cannot be used maliciously
586/// to access cells which don't belong to the new caller, because you
587/// also need a reference to the cells.  So for example if you have a
588/// graph of cells that is only accessible through a private
589/// structure, then someone else getting the same owner ID makes no
590/// difference, because they have no way to get a reference to those
591/// cells.  In any case, you are probably going to drop all those
592/// cells at the same time as dropping the owner, because they are no
593/// longer of any use without the owner ID.
594///
595/// [`QCellOwner`]: struct.QCellOwner.html
596pub struct QCellOwnerPinned {
597    target: OwnerIDTarget,
598    // ensure this type is !Unpin
599    _marker: PhantomPinned,
600}
601
602impl Default for QCellOwnerPinned {
603    fn default() -> Self {
604        QCellOwnerPinned::new()
605    }
606}
607
608impl QCellOwnerPinned {
609    /// Create an owner that can be used for creating many [`QCell`]
610    /// instances.
611    #[inline]
612    pub fn new() -> Self {
613        Self {
614            target: MAGIC_OWNER_ID_TARGET,
615            _marker: PhantomPinned,
616        }
617    }
618
619    /// Get the internal owner ID.  This may be used to create
620    /// [`QCell`] instances without needing a borrow on this
621    /// structure, which is useful if this structure is already
622    /// borrowed.
623    ///
624    /// Requires this owner to be pinned before use.
625    pub fn id(self: Pin<&Self>) -> QCellOwnerID {
626        // Pin guarantees that our address will not change until we
627        // are dropped, so we can use it as a unique ID.
628        let raw_ptr: *const OwnerIDTarget = &self.target;
629        QCellOwnerID(raw_ptr as usize)
630    }
631
632    /// Create a new cell owned by this owner instance.
633    ///
634    /// Requires this owner to be pinned before use.
635    #[inline]
636    pub fn cell<T>(self: Pin<&Self>, value: T) -> QCell<T> {
637        let id: QCellOwnerID = self.into();
638        id.cell(value)
639    }
640
641    /// Borrow contents of a [`QCell`] immutably (read-only).  Many
642    /// [`QCell`] instances can be borrowed immutably at the same time
643    /// from the same owner.  Panics if the [`QCell`] is not owned by
644    /// this [`QCellOwnerPinned`].
645    ///
646    /// Requires this owner to be pinned before use.
647    #[inline]
648    pub fn ro<'a, T: ?Sized>(self: Pin<&'a Self>, qc: &'a QCell<T>) -> &'a T {
649        owner_check!(self, qc);
650        unsafe { &*qc.value.get() }
651    }
652
653    /// Borrow contents of a [`QCell`] mutably (read-write).  Only one
654    /// [`QCell`] at a time can be borrowed from the owner using this
655    /// call.  The returned reference must go out of scope before
656    /// another can be borrowed.  Panics if the [`QCell`] is not owned
657    /// by this [`QCellOwnerPinned`].
658    ///
659    /// Requires this owner to be pinned before use.
660    #[inline]
661    #[allow(clippy::mut_from_ref)]
662    pub fn rw<'a, T: ?Sized>(self: Pin<&'a mut Self>, qc: &'a QCell<T>) -> &'a mut T {
663        owner_check!(self.as_ref(), qc);
664        unsafe { &mut *qc.value.get() }
665    }
666
667    /// Borrow contents of two [`QCell`] instances mutably.  Panics if
668    /// the two [`QCell`] instances point to the same memory.  Panics
669    /// if either [`QCell`] is not owned by this [`QCellOwnerPinned`].
670    ///
671    /// Requires this owner to be pinned before use.
672    #[inline]
673    pub fn rw2<'a, T: ?Sized, U: ?Sized>(
674        self: Pin<&'a mut Self>,
675        qc1: &'a QCell<T>,
676        qc2: &'a QCell<U>,
677    ) -> (&'a mut T, &'a mut U) {
678        owner_check!(self.as_ref(), qc1, qc2);
679        distinct_check!(qc1, qc2);
680        unsafe { (&mut *qc1.value.get(), &mut *qc2.value.get()) }
681    }
682
683    /// Borrow contents of three [`QCell`] instances mutably.  Panics
684    /// if any pair of [`QCell`] instances point to the same memory.
685    /// Panics if any [`QCell`] is not owned by this
686    /// [`QCellOwnerPinned`].
687    ///
688    /// Requires this owner to be pinned before use.
689    #[inline]
690    pub fn rw3<'a, T: ?Sized, U: ?Sized, V: ?Sized>(
691        self: Pin<&'a mut Self>,
692        qc1: &'a QCell<T>,
693        qc2: &'a QCell<U>,
694        qc3: &'a QCell<V>,
695    ) -> (&'a mut T, &'a mut U, &'a mut V) {
696        owner_check!(self.as_ref(), qc1, qc2, qc3);
697        distinct_check!(qc1, qc2, qc3);
698        unsafe {
699            (
700                &mut *qc1.value.get(),
701                &mut *qc2.value.get(),
702                &mut *qc3.value.get(),
703            )
704        }
705    }
706}
707
708#[cfg(test)]
709mod tests {
710    use core::pin::Pin;
711
712    use pin_utils::pin_mut;
713
714    use super::{QCell, QCellOwnerPinned, QCellOwnerSeq};
715
716    #[test]
717    fn qcell_pinned() {
718        let owner = QCellOwnerPinned::new();
719        pin_mut!(owner);
720        let c1 = owner.as_ref().cell(100u32);
721        let c2 = owner.as_ref().cell(200u32);
722        (*owner.as_mut().rw(&c1)) += 1;
723        (*owner.as_mut().rw(&c2)) += 2;
724        let c1ref = owner.as_ref().ro(&c1);
725        let c2ref = owner.as_ref().ro(&c2);
726        let total = *c1ref + *c2ref;
727        assert_eq!(total, 303);
728    }
729
730    #[test]
731    fn qcell_fast_ids_pinned() {
732        let owner1 = QCellOwnerPinned::new();
733        pin_mut!(owner1);
734        let id1 = owner1.as_ref().id();
735        let owner2 = unsafe { QCellOwnerSeq::new() };
736        let id2 = owner2.id;
737        assert_ne!(id1.0, id2.0, "Expected ID 1/2 to be different");
738        let owner3 = unsafe { QCellOwnerSeq::new() };
739        let id3 = owner3.id;
740        assert_ne!(id2.0, id3.0, "Expected ID 2/3 to be different");
741        drop(owner2);
742        drop(owner3);
743        let owner4 = QCellOwnerPinned::new();
744        pin_mut!(owner4);
745        let id4 = owner4.as_ref().id();
746        assert_ne!(id1.0, id4.0, "Expected ID 1/4 to be different");
747        assert_ne!(id2.0, id4.0, "Expected ID 2/4 to be different");
748        assert_ne!(id3.0, id4.0, "Expected ID 3/4 to be different");
749    }
750
751    #[test]
752    fn qcell_sep_ids_pinned() {
753        let owner1 = QCellOwnerPinned::new();
754        let owner2 = QCellOwnerPinned::new();
755        pin_mut!(owner1);
756        pin_mut!(owner2);
757        let id1 = owner1.as_ref().id();
758        let id2 = owner2.as_ref().id();
759        let c11 = id1.cell(1u32);
760        let c12 = id2.cell(2u32);
761        let c21 = owner1.as_ref().cell(4u32);
762        let c22 = owner2.as_ref().cell(8u32);
763        assert_eq!(
764            15,
765            owner1.as_ref().ro(&c11)
766                + owner2.as_ref().ro(&c12)
767                + owner1.as_ref().ro(&c21)
768                + owner2.as_ref().ro(&c22)
769        );
770    }
771
772    #[test]
773    fn qcell_unsized_pinned() {
774        let owner = QCellOwnerPinned::new();
775        struct Squares(u32);
776        struct Integers(u64);
777        trait Series {
778            fn step(&mut self);
779            fn value(&self) -> u64;
780        }
781        impl Series for Squares {
782            fn step(&mut self) {
783                self.0 += 1;
784            }
785            fn value(&self) -> u64 {
786                (self.0 as u64) * (self.0 as u64)
787            }
788        }
789        impl Series for Integers {
790            fn step(&mut self) {
791                self.0 += 1;
792            }
793            fn value(&self) -> u64 {
794                self.0
795            }
796        }
797        fn series(
798            init: u32,
799            is_squares: bool,
800            owner: Pin<&QCellOwnerPinned>,
801        ) -> Box<QCell<dyn Series>> {
802            if is_squares {
803                Box::new(owner.cell(Squares(init)))
804            } else {
805                Box::new(owner.cell(Integers(init as u64)))
806            }
807        }
808
809        pin_mut!(owner);
810        let cell1 = series(4, false, owner.as_ref());
811        let cell2 = series(7, true, owner.as_ref());
812        let cell3 = series(3, true, owner.as_ref());
813        assert_eq!(owner.as_ref().ro(&cell1).value(), 4);
814        owner.as_mut().rw(&cell1).step();
815        assert_eq!(owner.as_ref().ro(&cell1).value(), 5);
816        assert_eq!(owner.as_ref().ro(&cell2).value(), 49);
817        owner.as_mut().rw(&cell2).step();
818        assert_eq!(owner.as_ref().ro(&cell2).value(), 64);
819        let (r1, r2, r3) = owner.as_mut().rw3(&cell1, &cell2, &cell3);
820        r1.step();
821        r2.step();
822        r3.step();
823        assert_eq!(owner.as_ref().ro(&cell1).value(), 6);
824        assert_eq!(owner.as_ref().ro(&cell2).value(), 81);
825        assert_eq!(owner.as_ref().ro(&cell3).value(), 16);
826        let (r1, r2) = owner.as_mut().rw2(&cell1, &cell2);
827        r1.step();
828        r2.step();
829        assert_eq!(owner.as_ref().ro(&cell1).value(), 7);
830        assert_eq!(owner.as_ref().ro(&cell2).value(), 100);
831    }
832}
833
834#[cfg(all(test, feature = "alloc"))]
835mod tests_with_alloc {
836    use super::{QCell, QCellOwner, QCellOwnerSeq};
837
838    #[test]
839    fn qcell() {
840        let mut owner = QCellOwner::new();
841        let c1 = QCell::new(&owner, 100u32);
842        let c2 = QCell::new(&owner, 200u32);
843        (*owner.rw(&c1)) += 1;
844        (*owner.rw(&c2)) += 2;
845        let c1ref = owner.ro(&c1);
846        let c2ref = owner.ro(&c2);
847        let total = *c1ref + *c2ref;
848        assert_eq!(total, 303);
849    }
850
851    #[test]
852    fn qcell_ids() {
853        let owner1 = QCellOwner::new();
854        let id1 = owner1.id();
855        let owner2 = QCellOwner::new();
856        let id2 = owner2.id();
857        assert_ne!(id1.0, id2.0, "Expected ID 1/2 to be different");
858        drop(owner2);
859        let owner3 = QCellOwner::new();
860        let id3 = owner3.id();
861        assert_ne!(id1.0, id3.0, "Expected ID 1/3 to be different");
862        drop(owner3);
863        drop(owner1);
864        let owner4 = QCellOwner::new();
865        let id4 = owner4.id();
866        let owner5 = QCellOwner::new();
867        let id5 = owner5.id();
868        assert_ne!(id4.0, id5.0, "Expected ID 4/5 to be different");
869    }
870
871    #[test]
872    fn qcell_fast_ids() {
873        let owner1 = QCellOwner::new();
874        let id1 = owner1.id();
875        let owner2 = unsafe { QCellOwnerSeq::new() };
876        let id2 = owner2.id();
877        assert_ne!(id1.0, id2.0, "Expected ID 1/2 to be different");
878        let owner3 = unsafe { QCellOwnerSeq::new() };
879        let id3 = owner3.id();
880        assert_ne!(id2.0, id3.0, "Expected ID 2/3 to be different");
881        drop(owner2);
882        drop(owner3);
883        let owner4 = QCellOwner::new();
884        let id4 = owner4.id();
885        assert_ne!(id1.0, id4.0, "Expected ID 1/4 to be different");
886        assert_ne!(id2.0, id4.0, "Expected ID 2/4 to be different");
887        assert_ne!(id3.0, id4.0, "Expected ID 3/4 to be different");
888    }
889
890    #[test]
891    fn qcell_sep_ids() {
892        let owner1 = QCellOwner::new();
893        let owner2 = QCellOwner::new();
894        let id1 = owner1.id();
895        let id2 = owner2.id();
896        let c11 = id1.cell(1u32);
897        let c12 = id2.cell(2u32);
898        let c21 = owner1.cell(4u32);
899        let c22 = owner2.cell(8u32);
900        assert_eq!(
901            15,
902            owner1.ro(&c11) + owner2.ro(&c12) + owner1.ro(&c21) + owner2.ro(&c22)
903        );
904    }
905
906    #[test]
907    fn qcell_get_mut() {
908        let owner = QCellOwner::new();
909        let mut cell = QCell::new(&owner, 100u32);
910        let mut_ref = cell.get_mut();
911        *mut_ref = 50;
912        let cell_ref = owner.ro(&cell);
913        assert_eq!(*cell_ref, 50);
914    }
915
916    #[test]
917    fn qcell_into_inner() {
918        let owner = QCellOwner::new();
919        let cell = QCell::new(&owner, 100u32);
920        assert_eq!(cell.into_inner(), 100);
921    }
922
923    #[test]
924    fn qcell_unsized() {
925        let mut owner = QCellOwner::new();
926        struct Squares(u32);
927        struct Integers(u64);
928        trait Series {
929            fn step(&mut self);
930            fn value(&self) -> u64;
931        }
932        impl Series for Squares {
933            fn step(&mut self) {
934                self.0 += 1;
935            }
936            fn value(&self) -> u64 {
937                (self.0 as u64) * (self.0 as u64)
938            }
939        }
940        impl Series for Integers {
941            fn step(&mut self) {
942                self.0 += 1;
943            }
944            fn value(&self) -> u64 {
945                self.0
946            }
947        }
948        fn series(init: u32, is_squares: bool, owner: &QCellOwner) -> Box<QCell<dyn Series>> {
949            if is_squares {
950                Box::new(QCell::new(owner, Squares(init)))
951            } else {
952                Box::new(QCell::new(owner, Integers(init as u64)))
953            }
954        }
955
956        let own = &mut owner;
957        let cell1 = series(4, false, own);
958        let cell2 = series(7, true, own);
959        let cell3 = series(3, true, own);
960        assert_eq!(cell1.ro(own).value(), 4);
961        cell1.rw(own).step();
962        assert_eq!(cell1.ro(own).value(), 5);
963        assert_eq!(own.ro(&cell2).value(), 49);
964        own.rw(&cell2).step();
965        assert_eq!(own.ro(&cell2).value(), 64);
966        let (r1, r2, r3) = own.rw3(&cell1, &cell2, &cell3);
967        r1.step();
968        r2.step();
969        r3.step();
970        assert_eq!(cell1.ro(own).value(), 6);
971        assert_eq!(cell2.ro(own).value(), 81);
972        assert_eq!(cell3.ro(own).value(), 16);
973        let (r1, r2) = own.rw2(&cell1, &cell2);
974        r1.step();
975        r2.step();
976        assert_eq!(cell1.ro(own).value(), 7);
977        assert_eq!(cell2.ro(own).value(), 100);
978    }
979}