1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//! 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};
//! # use std::cmp::{Eq,Ord,PartialOrd,PartialEq,Ordering};
//! 
//! pub struct TotalF32(pub f32);
//! 
//! //Eq,Ord,PartialEq,PartialOrd impls not shown
//! # impl Eq for TotalF32{}
//! #
//! # impl Ord for TotalF32{
//! #     fn cmp(&self, other: &Self) -> Ordering {
//! #         self.0.partial_cmp(&other.0).unwrap_or_else(||{
//! #             match (self.0.is_nan(),other.0.is_nan()) {
//! #                 (false,_    )=>Ordering::Less,
//! #                 (true ,false)=>Ordering::Greater,
//! #                 (true ,true )=>Ordering::Equal,
//! #             }
//! #         })
//! #     }
//! # }
//! # impl PartialOrd for TotalF32{
//! #     fn partial_cmp(&self, other: &Self) -> Option<Ordering>{
//! #         Some(self.cmp(other))
//! #     }
//! # }
//! # impl PartialEq for TotalF32 {
//! #     fn eq(&self, other: &Self) -> bool {
//! #         self.cmp(other)==Ordering::Equal
//! #     }
//! # }
//! 
//! 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]);
//! 
//! ```

use std_::mem;
use utils::transmute_ignore_size;

/// Trait for newtypes which are safe to transmute to/from their contents.
///
/// Examples of such types:
///
/// - \#[repr(transparent)] types (stable since Rust 1.28).
///
/// - Newtypes whose only non-zero sized field is T,in which the alignment is the same as T.
/// 
/// # Safety,for implementors
///
/// The size and alignment of Self must be the same as T.
///
/// To ensure this trait is properly implemented for a newtype wrapping a T:
/// - don't use an align attribute:
/// - require that the types of the other fields implement MarkerType.
///
/// # Safety,for users
///
/// Look at the [module-level documentation](index.html#safety-pitfalls)
///
pub unsafe trait TransparentNewtype{
    /// The wrapped type
    type Inner:?Sized;

    /// Converts a T value to Self.
    #[inline(always)]
    fn convert_from(v:Self::Inner)->Self
    where 
        Self:Sized,
        Self::Inner:Sized,
    {
        check_same_size_alignment::<Self::Inner,Self>();
        unsafe{ transmute_ignore_size::<Self::Inner,Self>(v) }
    }
    /// Converts a reference to T to a reference to Self.
    #[inline(always)]
    fn convert_ref_from(v:&Self::Inner)->&Self {
        unsafe{ transmute_ignore_size(v) }
    }
    /// Converts a mutable reference to T to a mutable reference to Self.
    #[inline(always)]
    fn convert_mut_from(v:&mut Self::Inner)->&mut Self {
        unsafe{ transmute_ignore_size(v) }
    }
    /// Converts self to a T value.
    #[inline(always)]
    fn convert_into(self)->Self::Inner
    where 
        Self:Sized,
        Self::Inner:Sized,
    {
        check_same_size_alignment::<Self::Inner,Self>();
        unsafe{ transmute_ignore_size::<Self,Self::Inner>(self) }
    }
    /// Converts a reference to Self to a reference to T.
    #[inline(always)]
    fn convert_ref_to(&self)->&Self::Inner{
        unsafe{ transmute_ignore_size(self) }
    }
    /// Converts a mutable reference to Self to a mutable reference to T.
    #[inline(always)]
    fn convert_mut_to(&mut self)->&mut Self::Inner{
        unsafe{ transmute_ignore_size(self) }
    }
}


///////////////////////////////////////////////////////////////////////////////


#[inline(always)]
fn check_same_size_alignment<T,U>(){
    assert_eq!(mem::size_of::<T>(),mem::size_of::<U>());
    assert_eq!(mem::align_of::<T>(),mem::align_of::<U>());
}