//! `PhantomData`-related items. //! use std_::{ cell::Cell, marker::PhantomData, }; /// Type alias for a variant `PhantomData` with drop check. /// /// # Example /// /// ```rust /// use core_extensions::VariantDropPhantom; /// use std::marker::PhantomData; /// /// let _: VariantDropPhantom = PhantomData; /// /// ``` /// pub type VariantDropPhantom = PhantomData; /// Type alias for a variant `PhantomData`, without drop check. /// /// # Example /// /// ```rust /// use core_extensions::{AsPhantomData, CovariantPhantom}; /// /// let _: CovariantPhantom = u32::PHANTOM_COVARIANT; /// /// ``` /// pub type CovariantPhantom = PhantomData T>; /// Type alias for a contravariant `PhantomData`, without drop check. /// /// # Example /// /// ```rust /// use core_extensions::{ContraVariantPhantom, AsPhantomData}; /// /// let _: ContraVariantPhantom = u32::PHANTOM_CONTRA; /// /// ``` /// pub type ContraVariantPhantom = PhantomData; /// Type alias for an invariant `PhantomData`. /// /// # Example /// /// ```rust /// use core_extensions::{InvariantPhantom, AsPhantomData}; /// /// let _: InvariantPhantom = u32::PHANTOM_INVARIANT; /// /// ``` /// pub type InvariantPhantom = PhantomData T>; /// Type alias for an `PhantomData` with an invariant lifetime. /// /// # Example /// /// ```rust /// use core_extensions::InvariantRefPhantom; /// use std::marker::PhantomData; /// /// let _: InvariantRefPhantom = PhantomData; /// /// ``` /// pub type InvariantRefPhantom<'a, T> = PhantomData>; /////////////////////////////////////////////////////////////////////////// /// For getting a `PhantomData` with a variety of lifetime variances. pub trait AsPhantomData { #[doc(hidden)] const PHANTOM_QFEO7CXJP2HJSGYWRZFRBHDTHU: PhantomData = PhantomData; /// Gets a `PhantomData`. /// /// # Example /// /// ```rust /// use core_extensions::AsPhantomData; /// /// use std::marker::PhantomData; /// /// fn get_default(_type: PhantomData) -> T { /// Default::default() /// } /// /// let string = String::new(); /// let vector = vec![0u8]; /// /// assert_eq!(get_default(string.as_phantom()), ""); /// assert_eq!(get_default(vector.as_phantom()), vec![]); /// /// ``` #[inline(always)] fn as_phantom(&self) -> PhantomData { PhantomData } /// Gets a `PhantomData Self>`, a covariant `PhantomData`. #[inline(always)] fn as_phantom_covariant(&self) -> PhantomData Self> { PhantomData } /// Gets a `PhantomData`, a contravariant `PhantomData`. #[inline(always)] fn as_phantom_contra(&self) -> PhantomData { PhantomData } /// Gets a `PhantomData Self>`, an invariant `PhantomData`. #[inline(always)] fn as_phantom_invariant(&self) -> PhantomData Self> { PhantomData } /// Gets a `PhantomData`. /// /// # Example /// /// ```rust /// use core_extensions::AsPhantomData; /// /// use std::marker::PhantomData; /// /// fn get_default(_type: PhantomData) -> T { /// Default::default() /// } /// /// assert_eq!(get_default(String::PHANTOM), ""); /// assert_eq!(get_default(Vec::<()>::PHANTOM), vec![]); /// /// ``` const PHANTOM: PhantomData = PhantomData; /// Constructs a `PhantomData T>`, a covariant `PhantomData`. /// /// # Example /// /// ```rust /// use core_extensions::{AsPhantomData, CovariantPhantom}; /// /// struct WithGhost { /// value: T, /// _ghost: CovariantPhantom, /// } /// /// impl WithGhost { /// const fn new(value: T) -> Self { /// Self { /// value, /// _ghost: T::PHANTOM_COVARIANT, /// } /// } /// } /// ``` /// const PHANTOM_COVARIANT: PhantomData Self> = PhantomData; /// Gets a `PhantomData`, a contravariant `PhantomData`. /// /// # Example /// /// ```rust /// use core_extensions::{AsPhantomData, ContraVariantPhantom}; /// /// struct WithGhost { /// value: T, /// _ghost: ContraVariantPhantom, /// } /// /// impl WithGhost { /// const fn new(value: T) -> Self { /// Self { /// value, /// _ghost: T::PHANTOM_CONTRA, /// } /// } /// } /// ``` /// const PHANTOM_CONTRA: PhantomData = PhantomData; /// Gets a `PhantomData Self>`, an invariant `PhantomData`. /// /// # Example /// /// ```rust /// use core_extensions::{AsPhantomData, InvariantPhantom}; /// /// struct WithGhost { /// value: T, /// _ghost: InvariantPhantom, /// } /// /// impl WithGhost { /// const fn new(value: T) -> Self { /// Self { /// value, /// _ghost: T::PHANTOM_INVARIANT, /// } /// } /// } /// ``` /// const PHANTOM_INVARIANT: PhantomData Self> = PhantomData; } impl AsPhantomData for T {} /////////////////////////////////////////////////////////////////////////// /// Gets the `PhantomData` of the passed in type. /// /// # Example /// /// ```rust /// use core_extensions::as_phantom; /// /// use std::marker::PhantomData; /// /// fn get_default(_type: PhantomData) -> T { /// Default::default() /// } /// /// let string = String::new(); /// let vector = vec![0u8]; /// /// assert_eq!(get_default(as_phantom(&string)), "".to_string()); /// assert_eq!(get_default(as_phantom(&vector)), vec![]); /// /// ``` #[inline(always)] pub const fn as_phantom(_: &T) -> PhantomData { PhantomData } /////////////////////////////////////////////////////////////////////////// /// Contains `PhantomData T>`, /// required to return a `PhantomData T>` from the /// [`as_covariant_phantom`] const function. /// /// [`as_covariant_phantom`]: ./fn.as_covariant_phantom.html /// #[must_use = "unwrap this into a PhantomData with .0"] pub struct CovariantPhantomData(pub PhantomData T>); impl CovariantPhantomData { /// Constructs a `CovariantPhantomData` pub const NEW: Self = Self(PhantomData); } /// Gets the `PhantomData T>` of the passed in `T`. /// /// # Example /// #[cfg_attr(feature = "const_default", doc = " ```rust")] #[cfg_attr(not(feature = "const_default"), doc = " ```ignore")] /// use core_extensions::{AndPhantomCov, ConstDefault, as_covariant_phantom}; /// /// const SLICE: &[u8] = { /// let array = [0, 1, 2]; /// /// // phantom is a PhantomData [i32; 3]>; /// let phantom = as_covariant_phantom(&array).0; /// /// &AndPhantomCov(phantom, ConstDefault::DEFAULT).1 /// }; /// /// /// assert_eq!(SLICE, [0, 0, 0]); /// /// ``` /// pub const fn as_covariant_phantom(_: &T) -> CovariantPhantomData { CovariantPhantomData::NEW } /////////////////////////////////////////////////////////////////////////// /// A pair of `PhantomData` and `T`. /// useful for infering the type of the value from a `PhantomData`. /// /// # Example /// /// ```rust /// use core_extensions::{AndPhantom, AsPhantomData}; /// /// use std::marker::PhantomData; /// /// let foo = vec![0, 1, 2]; /// /// let mut bar = AndPhantom(foo.as_phantom(), Default::default()).1; /// /// bar.push(3); /// bar.push(4); /// /// assert_eq!(bar[..], [3, 4]); /// /// ``` #[repr(transparent)] pub struct AndPhantom(pub PhantomData, pub T); /// A pair of `PhantomData T>` and `T`. /// useful for infering the type of the value from a `PhantomData`. /// /// # Example /// /// ```rust /// use core_extensions::{AndPhantomCov, AsPhantomData}; /// /// use std::marker::PhantomData; /// /// let foo = [0, 1, 2]; /// /// let mut bar = AndPhantomCov(foo.as_phantom_covariant(), Default::default()).1; /// /// bar[0] = 3; /// bar[1] = 5; /// bar[2] = 8; /// /// assert_eq!(bar[..], [3, 5, 8]); /// /// ``` #[repr(transparent)] pub struct AndPhantomCov(pub PhantomData T>, pub T);