clone_behavior/
mixed.rs

1#![expect(clippy::absolute_paths, reason = "there's a lot of random types used")]
2#![warn(clippy::missing_inline_in_public_items, reason = "almost everything is very short")]
3
4use crate::speed::{Speed, NearInstant};
5
6
7/// Get clones that could share some but not all semantically-important mutable state.
8///
9/// This marker is useful for cases where a user needs to check documentation to figure out what
10/// happens.
11///
12/// It is not *strictly* necessary that the clone function doesn't behave like
13/// [`IndependentClone::independent_clone`] or [`MirroredClone::mirrored_clone`], but this type is
14/// not a catch-all for "some sort of clone, maybe also implements [`IndependentClone`] or
15/// [`MirroredClone`]".
16///
17/// This crate *will* provide a better tool for abstracting over all three modes of cloning
18/// provided. It just isn't provided yet. This isn't it.
19///
20/// [`IndependentClone`]: crate::IndependentClone
21/// [`IndependentClone::independent_clone`]: crate::IndependentClone::independent_clone
22/// [`MirroredClone`]: crate::MirroredClone
23/// [`MirroredClone::mirrored_clone`]: crate::MirroredClone::mirrored_clone
24pub trait MixedClone<S: Speed>: Sized {
25    /// Get a clone that could share some but not all semantically-important mutable state.
26    ///
27    /// Exact behavior is very implementation-dependent.
28    ///
29    /// Read [`MixedClone`] for more.
30    #[must_use]
31    fn mixed_clone(&self) -> Self;
32}
33
34
35macro_rules! non_recursive_near_instant {
36    ($($({for $($bounds:tt)+})? $type:ty),* $(,)?) => {
37        $(
38            impl<$($($bounds)+)?> MixedClone<NearInstant> for $type {
39                #[inline]
40                fn mixed_clone(&self) -> Self {
41                    self.clone()
42                }
43            }
44        )*
45    };
46}
47
48non_recursive_near_instant! {
49    {for T: ?Sized} &T,
50    {for T: ?Sized} *const T,
51    {for T: ?Sized} *mut T,
52    {for T: ?Sized} core::ptr::NonNull<T>,
53}
54
55#[cfg(target_has_atomic = "ptr")]
56impl<T> MixedClone<NearInstant> for core::sync::atomic::AtomicPtr<T> {
57    #[inline]
58    fn mixed_clone(&self) -> Self {
59        Self::new(self.load(core::sync::atomic::Ordering::Relaxed))
60    }
61}
62
63#[cfg(feature = "alloc")]
64impl<S: Speed, T: ?Sized + alloc::borrow::ToOwned> MixedClone<S> for alloc::borrow::Cow<'_, T> {
65    #[inline]
66    fn mixed_clone(&self) -> Self {
67        self.clone()
68    }
69}
70
71// TODO: consider implementing ones with recursive constraints