From e24423091f0690a83e63ee234bee5627a86b51f0 Mon Sep 17 00:00:00 2001 From: Jonathan Reem Date: Sun, 26 Jul 2015 22:12:00 -0700 Subject: Implement Clone for Box<[T]> where T: Clone Closes #25097 --- src/liballoc/boxed.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/liballoc/lib.rs | 1 + 2 files changed, 55 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index acf22094233..2b0aec5b727 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` @@ -511,3 +512,55 @@ impl<'a,A,R> FnOnce for Box+Send+'a> { } impl, U: ?Sized> CoerceUnsized> for Box {} + +#[stable(feature = "box_slice_clone", since = "1.3.0")] +impl 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 { + data: RawVec, + len: usize, + } + + impl BoxBuilder { + unsafe fn into_box(self) -> Box<[T]> { + let raw = ptr::read(&self.data); + mem::forget(self); + raw.into_box() + } + } + + impl Drop for BoxBuilder { + 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 f66495c4057..d49d209955e 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -78,6 +78,7 @@ #![feature(core)] #![feature(core_intrinsics)] #![feature(core_prelude)] +#![feature(core_slice_ext)] #![feature(custom_attribute)] #![feature(fundamental)] #![feature(lang_items)] -- cgit 1.4.1-3-g733a5