Skip to content

Commit da05cb5

Browse files
committed
---
yaml --- r: 151473 b: refs/heads/try2 c: 300d865 h: refs/heads/master i: 151471: 158be28 v: v3
1 parent 7a16ca8 commit da05cb5

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: dbbb847bf033003c89e105e337419649dae5384c
8+
refs/heads/try2: 300d865fa4642f0a76b2676539efa3155ceaeddf
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libstd/vec.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use ptr::RawPtr;
2828
use ptr;
2929
use rt::global_heap::{malloc_raw, realloc_raw};
3030
use raw::Slice;
31+
use RawVec = raw::Vec;
3132
use slice::{ImmutableEqVector, ImmutableVector, Items, MutItems, MutableVector};
3233
use slice::{MutableTotalOrdVector, OwnedVector, Vector};
3334
use slice::{MutableVectorAllocating};
@@ -1465,6 +1466,50 @@ pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (Vec<T>, Vec<U>) {
14651466
(ts, us)
14661467
}
14671468

1469+
/// Mechanism to convert from a `Vec<T>` to a `[T]`.
1470+
///
1471+
/// In a post-DST world this will be used to convert to any `Ptr<[T]>`.
1472+
///
1473+
/// This could be implemented on more types than just pointers to vectors, but
1474+
/// the recommended approach for those types is to implement `FromIterator`.
1475+
// FIXME(#12938): Update doc comment when DST lands
1476+
pub trait FromVec<T> {
1477+
/// Convert a `Vec<T>` into the receiver type.
1478+
fn from_vec(v: Vec<T>) -> Self;
1479+
}
1480+
1481+
impl<T> FromVec<T> for ~[T] {
1482+
fn from_vec(mut v: Vec<T>) -> ~[T] {
1483+
let len = v.len();
1484+
let data_size = len.checked_mul(&mem::size_of::<T>());
1485+
let data_size = data_size.expect("overflow in from_vec()");
1486+
let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
1487+
let size = size.expect("overflow in from_vec()");
1488+
1489+
// In a post-DST world, we can attempt to reuse the Vec allocation by calling
1490+
// shrink_to_fit() on it. That may involve a reallocation+memcpy, but that's no
1491+
// diffrent than what we're doing manually here.
1492+
1493+
let vp = v.as_mut_ptr();
1494+
1495+
unsafe {
1496+
let ret = malloc_raw(size) as *mut RawVec<()>;
1497+
1498+
(*ret).fill = len * mem::nonzero_size_of::<T>();
1499+
(*ret).alloc = len * mem::nonzero_size_of::<T>();
1500+
1501+
ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,
1502+
vp as *u8, data_size);
1503+
1504+
// we've transferred ownership of the contents from v, but we can't drop it
1505+
// as it still needs to free its own allocation.
1506+
v.set_len(0);
1507+
1508+
transmute(ret)
1509+
}
1510+
}
1511+
}
1512+
14681513
/// Unsafe operations
14691514
pub mod raw {
14701515
use super::Vec;
@@ -1488,7 +1533,8 @@ pub mod raw {
14881533
mod tests {
14891534
use prelude::*;
14901535
use mem::size_of;
1491-
use super::{unzip, raw};
1536+
use kinds::marker;
1537+
use super::{unzip, raw, FromVec};
14921538

14931539
#[test]
14941540
fn test_small_vec_struct() {
@@ -1765,4 +1811,30 @@ mod tests {
17651811
assert_eq!(d, vec![1, 2, 3, 4, 5]);
17661812
}
17671813
}
1814+
1815+
#[test]
1816+
fn test_from_vec() {
1817+
let a = vec![1u, 2, 3];
1818+
let b: ~[uint] = FromVec::from_vec(a);
1819+
assert_eq!(b.as_slice(), &[1u, 2, 3]);
1820+
1821+
let a = vec![];
1822+
let b: ~[u8] = FromVec::from_vec(a);
1823+
assert_eq!(b.as_slice(), &[]);
1824+
1825+
let a = vec!["one".to_owned(), "two".to_owned()];
1826+
let b: ~[~str] = FromVec::from_vec(a);
1827+
assert_eq!(b.as_slice(), &["one".to_owned(), "two".to_owned()]);
1828+
1829+
struct Foo {
1830+
x: uint,
1831+
nocopy: marker::NoCopy
1832+
}
1833+
1834+
let a = vec![Foo{x: 42, nocopy: marker::NoCopy}, Foo{x: 84, nocopy: marker::NoCopy}];
1835+
let b: ~[Foo] = FromVec::from_vec(a);
1836+
assert_eq!(b.len(), 2);
1837+
assert_eq!(b[0].x, 42);
1838+
assert_eq!(b[1].x, 84);
1839+
}
17681840
}

0 commit comments

Comments
 (0)