#![expect(clippy::absolute_paths, reason = "there's a lot of random types used")]
#![warn(clippy::missing_inline_in_public_items, reason = "almost everything is very short")]
use crate::call_varargs_macro;
use crate::speed::{Fast, MaybeSlow, Speed};
pub trait MirroredClone<S: Speed>: Sized {
#[must_use]
fn mirrored_clone(&self) -> Self;
}
pub trait FastMirroredClone: MirroredClone<Fast> {
#[must_use]
fn fast_mirrored_clone(&self) -> Self;
}
impl<T: MirroredClone<Fast>> FastMirroredClone for T {
#[inline]
fn fast_mirrored_clone(&self) -> Self {
self.mirrored_clone()
}
}
macro_rules! non_recursive_fast {
($($({for $($bounds:tt)+})? $type:ty),* $(,)?) => {
$(
impl<S: Speed, $($($bounds)+)?> MirroredClone<S> for $type {
#[inline]
fn mirrored_clone(&self) -> Self {
self.clone()
}
}
)*
};
}
non_recursive_fast! {
(),
{for T} core::iter::Empty<T>,
{for T: ?Sized} core::marker::PhantomData<T>,
core::marker::PhantomPinned,
core::ops::RangeFull,
}
#[cfg(feature = "alloc")]
macro_rules! refcounted {
($($t:ident $refcounted:ty),* $(,)?) => {
$(
impl<S: Speed, $t: ?Sized> MirroredClone<S> for $refcounted {
#[inline]
fn mirrored_clone(&self) -> Self {
self.clone()
}
}
)*
};
}
#[cfg(feature = "alloc")]
refcounted!(
T alloc::rc::Rc<T>,
T alloc::rc::Weak<T>,
T alloc::sync::Arc<T>,
T alloc::sync::Weak<T>,
);
macro_rules! function {
($($args:ident),*) => {
impl<S: Speed, R, $($args),*> MirroredClone<S> for fn($($args),*) -> R {
#[inline]
fn mirrored_clone(&self) -> Self {
*self
}
}
};
}
macro_rules! pinned_refcounted {
($($t:ident $refcounted:ty),* $(,)?) => {
$(
#[cfg(feature = "alloc")]
impl<S: Speed, $t: ?Sized> MirroredClone<S> for core::pin::Pin<$refcounted> {
#[inline]
fn mirrored_clone(&self) -> Self {
self.clone()
}
}
)*
};
}
pinned_refcounted! {
T alloc::rc::Rc<T>,
T alloc::rc::Weak<T>,
T alloc::sync::Arc<T>,
T alloc::sync::Weak<T>,
}
function!();
call_varargs_macro!(function);
macro_rules! make_tuple_macro {
($name:ident, $speed:ident, $dollar:tt) => {
macro_rules! $name {
($dollar($dollar args:ident),+) => {
impl<$dollar($dollar args: MirroredClone<$speed>),+> MirroredClone<$speed>
for ($dollar($dollar args,)+)
{
#[inline]
fn mirrored_clone(&self) -> Self {
#[expect(
non_snake_case,
reason = "using `Tn` as the variable of type `Tn`",
)]
let ($dollar($dollar args,)+) = self;
(
$dollar($dollar args.mirrored_clone(),)+
)
}
}
};
}
};
}
make_tuple_macro!(tuple_fast, Fast, $);
make_tuple_macro!(tuple_slow, MaybeSlow, $);
call_varargs_macro!(tuple_fast);
call_varargs_macro!(tuple_slow);
impl<S: Speed> MirroredClone<S> for core::convert::Infallible {
#[expect(
clippy::missing_inline_in_public_items,
clippy::uninhabited_references,
reason = "this is unreachable",
)]
fn mirrored_clone(&self) -> Self {
*self
}
}