@@ -1712,6 +1712,9 @@ pub mod raw {
1712
1712
1713
1713
/// An owned, partially type-converted vector.
1714
1714
///
1715
+ /// This struct takes two type parameters `T` and `U` which must be of the
1716
+ /// same, non-zero size.
1717
+ ///
1715
1718
/// No allocations are performed by usage, only a deallocation happens in the
1716
1719
/// destructor which should only run when unwinding.
1717
1720
///
@@ -1725,13 +1728,13 @@ pub mod raw {
1725
1728
/// # Example
1726
1729
///
1727
1730
/// ```rust
1728
- /// let pv = PartialVec::new (vec![0u, 1]);
1731
+ /// let pv = PartialVec::from_vec (vec![0u, 1]);
1729
1732
/// assert_eq!(pv.pop(), Some(0));
1730
1733
/// assert_eq!(pv.pop(), Some(1));
1731
1734
/// assert_eq!(pv.pop(), None);
1732
1735
/// pv.push(2u);
1733
1736
/// pv.push(3);
1734
- /// assert_eq!(pv.into_vec(), vec! [2, 3]);
1737
+ /// assert_eq!(pv.into_vec().as_slice(), & [2, 3]);
1735
1738
/// ```
1736
1739
//
1737
1740
// Upheld invariants:
@@ -1751,6 +1754,8 @@ pub mod raw {
1751
1754
//
1752
1755
// (f) From `start_t` (incl.) to `end_t` (excl.) there are sequential instances
1753
1756
// of type `T`.
1757
+ //
1758
+ // (g) The size of `T` and `U` is equal and non-zero.
1754
1759
1755
1760
pub struct PartialVec < T , U > {
1756
1761
vec : Vec < T > ,
@@ -1763,8 +1768,14 @@ pub struct PartialVec<T,U> {
1763
1768
1764
1769
impl < T , U > PartialVec < T , U > {
1765
1770
/// 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 > {
1767
1776
// FIXME: Assert that the types `T` and `U` have the same size.
1777
+ //
1778
+ // These asserts make sure (g) is satisfied.
1768
1779
assert ! ( mem:: size_of:: <T >( ) != 0 ) ;
1769
1780
assert ! ( mem:: size_of:: <U >( ) != 0 ) ;
1770
1781
assert ! ( mem:: size_of:: <T >( ) == mem:: size_of:: <U >( ) ) ;
@@ -1793,24 +1804,24 @@ impl<T,U> PartialVec<T,U> {
1793
1804
let start_u = start as * mut U ;
1794
1805
let end_u = start as * mut U ;
1795
1806
let start_t = start;
1807
+
1808
+ // This points inside the vector, as the vector has length `offset`.
1796
1809
let end_t = unsafe { start_t. offset ( offset) } ;
1797
1810
1798
1811
// (b) is satisfied, `start_u` points to the start of `vec`.
1799
-
1812
+ //
1800
1813
// (c) is also satisfied, `end_t` points to the end of `vec`.
1801
-
1814
+ //
1802
1815
// `start_u == end_u == start_t <= end_t`, so also `start_u <= end_u <=
1803
1816
// start_t <= end_t`, thus (b).
1804
-
1817
+ //
1805
1818
// As `start_u == end_u`, it is represented correctly that there are no
1806
1819
// instances of `U` in `vec`, thus (e) is satisfied.
1807
-
1820
+ //
1808
1821
// At start, there are only elements of type `T` in `vec`, so (f) is
1809
1822
// satisfied, as `start_t` points to the start of `vec` and `end_t` to
1810
1823
// the end of it.
1811
1824
1812
- // This points inside the vector, as the vector has length `offset`.
1813
-
1814
1825
PartialVec {
1815
1826
// (a) is satisfied, `vec` isn't modified in the function.
1816
1827
vec : vec,
@@ -1823,8 +1834,8 @@ impl<T,U> PartialVec<T,U> {
1823
1834
1824
1835
/// Pops a `T` from the `PartialVec`.
1825
1836
///
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 .
1828
1839
fn pop ( & mut self ) -> Option < T > {
1829
1840
// The `if` ensures that there are more `T`s in `vec`.
1830
1841
if self . start_t < self . end_t {
@@ -1869,21 +1880,26 @@ impl<T,U> PartialVec<T,U> {
1869
1880
///
1870
1881
/// Fails if not all `T`s were popped, also fails if not the same amount of
1871
1882
/// `U`s was pushed before calling `unwrap`.
1872
- pub fn into_vec ( self ) -> Vec < U > {
1883
+ pub fn into_vec ( mut self ) -> Vec < U > {
1873
1884
// If `self.end_u == self.end_t`, we know from (e) that there are no
1874
1885
// 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.
1877
1888
1878
1889
assert ! ( self . end_u as * const ( ) == self . end_t as * const ( ) ,
1879
1890
"trying to unwrap a PartialVec before completing the writes to it" ) ;
1880
1891
1881
1892
// 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.
1883
1897
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 ;
1885
1901
mem:: forget ( self ) ;
1886
- mem :: transmute ( vec )
1902
+ Vec :: from_raw_parts ( vec_len , vec_cap , vec_ptr )
1887
1903
}
1888
1904
}
1889
1905
}
@@ -1923,24 +1939,29 @@ impl<T,U> Iterator<T> for PartialVec<T,U> {
1923
1939
}
1924
1940
1925
1941
impl < 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.
1927
1948
///
1928
1949
/// # Example
1929
1950
///
1930
1951
/// ```rust
1931
1952
/// let v = vec![0u, 1, 2];
1932
1953
/// 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]);
1934
1955
///
1935
1956
/// let big_endian_u16s = vec![0x1122u16, 0x3344];
1936
1957
/// let u8s = big_endian_u16s.map_inplace(|x| [
1937
1958
/// ((x >> 8) & 0xff) as u8,
1938
1959
/// (x & 0xff) as u8
1939
1960
/// ]);
1940
- /// assert_eq!(u8s.as_slice() == &[[0x11, 0x22], [0x33, 0x44]]);
1961
+ /// assert_eq!(u8s.as_slice(), &[[0x11, 0x22], [0x33, 0x44]]);
1941
1962
/// ```
1942
1963
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 ) ;
1944
1965
loop {
1945
1966
let maybe_t = pv. pop ( ) ;
1946
1967
match maybe_t {
@@ -2292,7 +2313,7 @@ mod tests {
2292
2313
#[ test]
2293
2314
fn test_map_inplace ( ) {
2294
2315
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 ] ) ;
2296
2317
}
2297
2318
2298
2319
#[ bench]
0 commit comments