NonDeDuplicatedFlexible

Struct NonDeDuplicatedFlexible 

Source
pub struct NonDeDuplicatedFlexible<OWN: Any + Send + Sync, TO: Any + Send + Sync + ?Sized> { /* private fields */ }
Expand description

A zero-cost wrapper guaranteed not to share its memory location with any other valid (in-scope) variable (even const equal to the inner value). Use for static variables that have their addresses compared with core::ptr::eq.

It has same size, layout and alignment as type parameter OWN.

T must implement Any. That is automatic for any types that don’t have any lifetimes (other than 'static). This requirement gives an earlier error when NonDeDuplicated is used other than intended.

We don’t just limit to be :'static, because then NonDeDuplicated could still be somewhat used with non-static lifetimes, and the error would surface only later. The following would compile:


pub struct NonDeDuplicatedStatic<T: 'static> {
   cell: Cell<T>,
}

type NddU8ref<'a> = NonDeDuplicatedStatic<&'a u8>;

fn callee<'a>(r: NddU8ref<'a>) {}

Only the following would then fail (to compile):

fn caller<'a>(r: &'a u8) { let u = 0u8; callee(NonDeDuplicatedStatic::new(uref)); }

But, by requiring NonDeDuplicatedFlexible’s generic parameter OWN (or NonDeDuplicated’s generic parameter T) to implement Any the first example above fails, too. That prevents mistakes earlier.

Do not use NonDeDuplicatedFlexible directly. Instead, use NonDeDuplicated, NonDeDuplicatedStr and NonDeDuplicatedCStr.

Implementations§

Source§

impl<T: Any + Send + Sync> NonDeDuplicatedFlexible<T, T>

Source

pub const fn new(value: T) -> Self

Construct a new instance.

Source

pub const fn get(&self) -> &T

Get a reference.

Source§

impl<const N: usize> NonDeDuplicatedFlexible<[u8; N], str>

Source

pub const fn new(s: &str) -> Self

Construct a new instance.

Source

pub const fn get(&self) -> &str

Get a reference.

Implementation details: Since this type, and this function, is intended to be used for static variables only, speed doesn’t matter here. So, we use core::str::from_utf8 (instead of core::str::from_utf8_unchecked).

Source§

impl<const N: usize> NonDeDuplicatedFlexible<[u8; N], CStr>

Source

pub const fn new(s: &CStr) -> Self

Construct a new instance.

Source

pub const fn new_from_bytes(arr: [u8; N]) -> Self

The given arr must be a well-formed C string, that is,

  • not containing any internal NUL bytes, and
  • end with a NUL byte, like b"abc\0".
Source

pub const fn new_from_str(s: &str) -> Self

The given &str must, like C string, not contain any internal NUL bytes. However, do not include the trailing NUL byte - that is added automatically.

Source

pub const fn get(&self) -> &CStr

Get a reference.

Implementation details: Since this type, and this function, is intended to be used for static variables only, speed doesn’t matter here. So, we use CStr::from_bytes_with_nul (instead of CStr::from_bytes_with_nul_unchecked).

Trait Implementations§

Source§

impl<OWN: Any + Send + Sync, TO: Any + Send + Sync + ?Sized> Drop for NonDeDuplicatedFlexible<OWN, TO>

NonDeDuplicated and friends are intended for static (immutable) variables only. So Drop::drop panics in debug/miri builds.

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<OWN: Any + Send + Sync, TO: Any + Send + Sync + ?Sized> Sync for NonDeDuplicatedFlexible<OWN, TO>

For now, Sync (and NonDeDuplicatedFlexible in general) requires that OWN is both Sync AND Send, following std::sync::Mutex. However, from https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html it seems that T: Send may be unnecessary? Please advise.

Either way, NonDeDuplicated, NonDeDuplicatedStr and NonDeDuplicatedCStr (and underlying NonDeDuplicatedFlexible) exist specifically for static variables. Those get never moved out. So, (unlike std::sync::Mutex) they do not need to implement Send.

Also, unclear if TO needs to be Send and Sync.

Auto Trait Implementations§

§

impl<OWN, TO> !Freeze for NonDeDuplicatedFlexible<OWN, TO>

§

impl<OWN, TO> !RefUnwindSafe for NonDeDuplicatedFlexible<OWN, TO>

§

impl<OWN, TO> Send for NonDeDuplicatedFlexible<OWN, TO>
where TO: ?Sized,

§

impl<OWN, TO> Unpin for NonDeDuplicatedFlexible<OWN, TO>
where TO: Unpin + ?Sized, OWN: Unpin,

§

impl<OWN, TO> UnwindSafe for NonDeDuplicatedFlexible<OWN, TO>
where TO: UnwindSafe + ?Sized, OWN: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.