[][src]Module core_extensions::transparent_newtype

Contains the TransparentNewtype trait to enable safer transmutation between types.

Safety for Users

Given that T impls TransparentNewtype<Inner=I>.

It is always safe to convert from I to T directly.

It is always safe to convert from pointers to I,eg.:*const I,*mut I,&I,&mut I, to pointers to T (the same kind of pointer/reference). This also includes all smart pointers (Box,Rc,Arc,etc) in the standard library.

Transmuting a generic type C<I> to C<T> is not always safe ,because some may store a <I as SomeTrait>::AssocType instead of storing I directly. This has to be evaluated on an individual basis.

Example

Casting a Vec<T> to a Vec<Wrapper<T>>,to use its Debug implementation.

use core_extensions::{SelfOps,TransparentNewtype};
use std::fmt;

pub struct DebugFromDisplay<T:?Sized>(pub T);

impl<T:?Sized+fmt::Display> fmt::Debug for DebugFromDisplay<T>{
    fn fmt(&self,f:&mut fmt::Formatter)->fmt::Result{
        fmt::Display::fmt(&self.0,f)
    }
}
unsafe impl<T:?Sized> TransparentNewtype for DebugFromDisplay<T>{
    type Inner=T;
}
fn vec_as<T>(v:&Vec<T>)->&Vec<DebugFromDisplay<T>>{
    unsafe{ ::std::mem::transmute(v) }
}
let list=vec!["\"hello\"","\"world\""];
for elem in list.piped_ref(vec_as) {
    assert_eq!(elem.0,format!("{:?}",elem));
}

Example

A totally ordered 32 bit float.

use core_extensions::{SelfOps,TransparentNewtype};

pub struct TotalF32(pub f32);

//Eq,Ord,PartialEq,PartialOrd impls not shown

unsafe impl TransparentNewtype for TotalF32{
    type Inner=f32;
}

fn vec_to(v:&mut Vec<f32>)->&mut Vec<TotalF32>{
    unsafe{ ::std::mem::transmute(v) }
}

let mut list=vec![1.0,0.0,2.0];

// This avoids the problem with using sort_by_key ,
// in which the borrow can't be returned from the closure.
list.piped_mut(vec_to).sort();

assert_eq!(list,vec![0.0,1.0,2.0]);

Traits

TransparentNewtype

Trait for #[repr(transparent)] newtypes (stable since Rust 1.28) which are safe to transmute to/from their contents.