diff options
| author | bors <bors@rust-lang.org> | 2015-07-28 19:36:26 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-07-28 19:36:26 +0000 |
| commit | ba9224f35451e5d5ef7647bd2b40e5da80ce2735 (patch) | |
| tree | 3866a42e258bbf3a55cb9d683b64818a7b5a88e1 /src/liballoc | |
| parent | aa6efd959e450e1cea177a3f6cd6bab6d80d4154 (diff) | |
| parent | e24423091f0690a83e63ee234bee5627a86b51f0 (diff) | |
| download | rust-ba9224f35451e5d5ef7647bd2b40e5da80ce2735.tar.gz rust-ba9224f35451e5d5ef7647bd2b40e5da80ce2735.zip | |
Auto merge of #26934 - reem:boxed-slice-clone, r=Gankro
Closes #25097
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/boxed.rs | 55 | ||||
| -rw-r--r-- | src/liballoc/lib.rs | 1 |
2 files changed, 55 insertions, 1 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index d5a177d3ee5..db338eaaf00 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -56,6 +56,7 @@ use core::prelude::*; use heap; +use raw_vec::RawVec; use core::any::Any; use core::cmp::Ordering; @@ -65,7 +66,7 @@ use core::marker::{self, Unsize}; use core::mem; use core::ops::{CoerceUnsized, Deref, DerefMut}; use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace}; -use core::ptr::Unique; +use core::ptr::{self, Unique}; use core::raw::{TraitObject}; /// A value that represents the heap. This is the default place that the `box` @@ -514,3 +515,55 @@ impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> { } impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {} + +#[stable(feature = "box_slice_clone", since = "1.3.0")] +impl<T: Clone> Clone for Box<[T]> { + fn clone(&self) -> Self { + let mut new = BoxBuilder { + data: RawVec::with_capacity(self.len()), + len: 0 + }; + + let mut target = new.data.ptr(); + + for item in self.iter() { + unsafe { + ptr::write(target, item.clone()); + target = target.offset(1); + }; + + new.len += 1; + } + + return unsafe { new.into_box() }; + + // Helper type for responding to panics correctly. + struct BoxBuilder<T> { + data: RawVec<T>, + len: usize, + } + + impl<T> BoxBuilder<T> { + unsafe fn into_box(self) -> Box<[T]> { + let raw = ptr::read(&self.data); + mem::forget(self); + raw.into_box() + } + } + + impl<T> Drop for BoxBuilder<T> { + fn drop(&mut self) { + let mut data = self.data.ptr(); + let max = unsafe { data.offset(self.len as isize) }; + + while data != max { + unsafe { + ptr::read(data); + data = data.offset(1); + } + } + } + } + } +} + diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index fce327398e3..03cf4fc9fc1 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -76,6 +76,7 @@ #![feature(core)] #![feature(core_intrinsics)] #![feature(core_prelude)] +#![feature(core_slice_ext)] #![feature(custom_attribute)] #![feature(fundamental)] #![feature(lang_items)] |
