Skip to content

Commit 37fd4ec

Browse files
committed
---
yaml --- r: 133710 b: refs/heads/try c: 23f2c78 h: refs/heads/master v: v3
1 parent ee3913d commit 37fd4ec

File tree

2 files changed

+44
-23
lines changed

2 files changed

+44
-23
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 0e784e16840e8a0c623cc6166de26da9334db3d6
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 828e075abd8ee2f8c16f6cb1b93c0d99307e704d
5-
refs/heads/try: af293372e4ea9578840338bdd1b765bfc3c80352
5+
refs/heads/try: 23f2c78d21440a8699cfa917b422795b5ec4adc7
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libcollections/vec.rs

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

17551760
pub struct PartialVec<T,U> {
17561761
vec: Vec<T>,
@@ -1763,8 +1768,14 @@ pub struct PartialVec<T,U> {
17631768

17641769
impl<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

19251941
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.
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![0u, 1, 2];
2295-
assert_eq!(v.map_inplace(|i: uint| i as int - 1).as_slice, &[-1i, 0, 1]);
2316+
assert_eq!(v.map_inplace(|i: uint| i as int - 1).as_slice(), &[-1i, 0, 1]);
22962317
}
22972318

22982319
#[bench]

0 commit comments

Comments
 (0)