@@ -1712,6 +1712,9 @@ pub mod raw {
17121712
17131713/// An owned, partially type-converted vector.
17141714///
1715+ /// This struct takes two type parameters `T` and `U` which must be of the
1716+ /// same, non-zero size.
1717+ ///
17151718/// No allocations are performed by usage, only a deallocation happens in the
17161719/// destructor which should only run when unwinding.
17171720///
@@ -1725,13 +1728,13 @@ pub mod raw {
17251728/// # Example
17261729///
17271730/// ```rust
1728- /// let pv = PartialVec::new (vec![0u, 1]);
1731+ /// let pv = PartialVec::from_vec (vec![0u, 1]);
17291732/// assert_eq!(pv.pop(), Some(0));
17301733/// assert_eq!(pv.pop(), Some(1));
17311734/// assert_eq!(pv.pop(), None);
17321735/// pv.push(2u);
17331736/// pv.push(3);
1734- /// assert_eq!(pv.into_vec(), vec! [2, 3]);
1737+ /// assert_eq!(pv.into_vec().as_slice(), & [2, 3]);
17351738/// ```
17361739//
17371740// Upheld invariants:
@@ -1751,6 +1754,8 @@ pub mod raw {
17511754//
17521755// (f) From `start_t` (incl.) to `end_t` (excl.) there are sequential instances
17531756// of type `T`.
1757+ //
1758+ // (g) The size of `T` and `U` is equal and non-zero.
17541759
17551760pub struct PartialVec < T , U > {
17561761 vec : Vec < T > ,
@@ -1763,8 +1768,14 @@ pub struct PartialVec<T,U> {
17631768
17641769impl < T , U > PartialVec < T , U > {
17651770 /// Creates a `PartialVec` from a `Vec`.
1766- pub fn new ( mut vec : Vec < T > ) -> PartialVec < T , U > {
1771+ ///
1772+ /// # Failure
1773+ ///
1774+ /// Fails if `T` and `U` have differing sizes or are zero-sized.
1775+ pub fn from_vec ( mut vec : Vec < T > ) -> PartialVec < T , U > {
17671776 // FIXME: Assert that the types `T` and `U` have the same size.
1777+ //
1778+ // These asserts make sure (g) is satisfied.
17681779 assert ! ( mem:: size_of:: <T >( ) != 0 ) ;
17691780 assert ! ( mem:: size_of:: <U >( ) != 0 ) ;
17701781 assert ! ( mem:: size_of:: <T >( ) == mem:: size_of:: <U >( ) ) ;
@@ -1793,24 +1804,24 @@ impl<T,U> PartialVec<T,U> {
17931804 let start_u = start as * mut U ;
17941805 let end_u = start as * mut U ;
17951806 let start_t = start;
1807+
1808+ // This points inside the vector, as the vector has length `offset`.
17961809 let end_t = unsafe { start_t. offset ( offset) } ;
17971810
17981811 // (b) is satisfied, `start_u` points to the start of `vec`.
1799-
1812+ //
18001813 // (c) is also satisfied, `end_t` points to the end of `vec`.
1801-
1814+ //
18021815 // `start_u == end_u == start_t <= end_t`, so also `start_u <= end_u <=
18031816 // start_t <= end_t`, thus (b).
1804-
1817+ //
18051818 // As `start_u == end_u`, it is represented correctly that there are no
18061819 // instances of `U` in `vec`, thus (e) is satisfied.
1807-
1820+ //
18081821 // At start, there are only elements of type `T` in `vec`, so (f) is
18091822 // satisfied, as `start_t` points to the start of `vec` and `end_t` to
18101823 // the end of it.
18111824
1812- // This points inside the vector, as the vector has length `offset`.
1813-
18141825 PartialVec {
18151826 // (a) is satisfied, `vec` isn't modified in the function.
18161827 vec : vec,
@@ -1823,8 +1834,8 @@ impl<T,U> PartialVec<T,U> {
18231834
18241835 /// Pops a `T` from the `PartialVec`.
18251836 ///
1826- /// Returns `Some(t)` if there are more `T`s in the vector, otherwise
1827- /// `None`.
1837+ /// Removes the next `T` from the vector and returns it as `Some(T)`, or
1838+ /// `None` if there are none left .
18281839 fn pop ( & mut self ) -> Option < T > {
18291840 // The `if` ensures that there are more `T`s in `vec`.
18301841 if self . start_t < self . end_t {
@@ -1869,21 +1880,26 @@ impl<T,U> PartialVec<T,U> {
18691880 ///
18701881 /// Fails if not all `T`s were popped, also fails if not the same amount of
18711882 /// `U`s was pushed before calling `unwrap`.
1872- pub fn into_vec ( self ) -> Vec < U > {
1883+ pub fn into_vec ( mut self ) -> Vec < U > {
18731884 // If `self.end_u == self.end_t`, we know from (e) that there are no
18741885 // more `T`s in `vec`, we also know that the whole length of `vec` is
1875- // now used by `U`s, thus we can just transmute `vec` from a vector of
1876- // `T`s to a vector of `U`s safely.
1886+ // now used by `U`s, thus we can just interpret `vec` as a vector of
1887+ // `U` safely.
18771888
18781889 assert ! ( self . end_u as * const ( ) == self . end_t as * const ( ) ,
18791890 "trying to unwrap a PartialVec before completing the writes to it" ) ;
18801891
18811892 // Extract `vec` and prevent the destructor of `PartialVec` from
1882- // running.
1893+ // running. Note that none of the function calls can fail, thus no
1894+ // resources can be leaked (as the `vec` member of `PartialVec` is the
1895+ // only one which holds allocations -- and it is returned from this
1896+ // function.
18831897 unsafe {
1884- let vec = ptr:: read ( & self . vec ) ;
1898+ let vec_len = self . vec . len ( ) ;
1899+ let vec_cap = self . vec . capacity ( ) ;
1900+ let vec_ptr = self . vec . as_mut_ptr ( ) as * mut U ;
18851901 mem:: forget ( self ) ;
1886- mem :: transmute ( vec )
1902+ Vec :: from_raw_parts ( vec_len , vec_cap , vec_ptr )
18871903 }
18881904 }
18891905}
@@ -1923,24 +1939,29 @@ impl<T,U> Iterator<T> for PartialVec<T,U> {
19231939}
19241940
19251941impl < T > Vec < T > {
1926- /// Converts a `Vec<T>` to a `Vec<U>` where `T` and `U` have the same size.
1942+ /// Converts a `Vec<T>` to a `Vec<U>` where `T` and `U` have the same
1943+ /// non-zero size.
1944+ ///
1945+ /// # Failure
1946+ ///
1947+ /// Fails if `T` and `U` have differing sizes or are zero-sized.
19271948 ///
19281949 /// # Example
19291950 ///
19301951 /// ```rust
19311952 /// let v = vec![0u, 1, 2];
19321953 /// let w = v.map_inplace(|i| i + 3);
1933- /// assert_eq!(w.as_slice() == &[3, 4, 5]);
1954+ /// assert_eq!(w.as_slice(), &[3, 4, 5]);
19341955 ///
19351956 /// let big_endian_u16s = vec![0x1122u16, 0x3344];
19361957 /// let u8s = big_endian_u16s.map_inplace(|x| [
19371958 /// ((x >> 8) & 0xff) as u8,
19381959 /// (x & 0xff) as u8
19391960 /// ]);
1940- /// assert_eq!(u8s.as_slice() == &[[0x11, 0x22], [0x33, 0x44]]);
1961+ /// assert_eq!(u8s.as_slice(), &[[0x11, 0x22], [0x33, 0x44]]);
19411962 /// ```
19421963 pub fn map_inplace < U > ( self , f: |T | -> U ) -> Vec < U > {
1943- let mut pv = PartialVec :: new ( self ) ;
1964+ let mut pv = PartialVec :: from_vec ( self ) ;
19441965 loop {
19451966 let maybe_t = pv. pop ( ) ;
19461967 match maybe_t {
@@ -2292,7 +2313,7 @@ mod tests {
22922313 #[ test]
22932314 fn test_map_inplace ( ) {
22942315 let v = vec ! [ 0 u, 1 , 2 ] ;
2295- assert_eq ! ( v. map_inplace( |i: uint| i as int - 1 ) . as_slice, & [ -1 i, 0 , 1 ] ) ;
2316+ assert_eq ! ( v. map_inplace( |i: uint| i as int - 1 ) . as_slice( ) , & [ -1 i, 0 , 1 ] ) ;
22962317 }
22972318
22982319 #[ bench]
0 commit comments