mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
parent
184267cac6
commit
e24423091f
@ -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<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,7 @@
|
||||
#![feature(core)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_prelude)]
|
||||
#![feature(core_slice_ext)]
|
||||
#![feature(custom_attribute)]
|
||||
#![feature(fundamental)]
|
||||
#![feature(lang_items)]
|
||||
|
@ -1270,6 +1270,59 @@ fn test_to_vec() {
|
||||
assert_eq!(ys, [1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_box_slice_clone() {
|
||||
let data = vec![vec![0, 1], vec![0], vec![1]];
|
||||
let data2 = data.clone().into_boxed_slice().clone().to_vec();
|
||||
|
||||
assert_eq!(data, data2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_box_slice_clone_panics() {
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::thread::spawn;
|
||||
|
||||
struct Canary {
|
||||
count: Arc<AtomicUsize>,
|
||||
panics: bool
|
||||
}
|
||||
|
||||
impl Drop for Canary {
|
||||
fn drop(&mut self) {
|
||||
self.count.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Canary {
|
||||
fn clone(&self) -> Self {
|
||||
if self.panics { panic!() }
|
||||
|
||||
Canary {
|
||||
count: self.count.clone(),
|
||||
panics: self.panics
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let drop_count = Arc::new(AtomicUsize::new(0));
|
||||
let canary = Canary { count: drop_count.clone(), panics: false };
|
||||
let panic = Canary { count: drop_count.clone(), panics: true };
|
||||
|
||||
spawn(move || {
|
||||
// When xs is dropped, +5.
|
||||
let xs = vec![canary.clone(), canary.clone(), canary.clone(),
|
||||
panic, canary].into_boxed_slice();
|
||||
|
||||
// When panic is cloned, +3.
|
||||
xs.clone();
|
||||
}).join().unwrap_err();
|
||||
|
||||
// Total = 8
|
||||
assert_eq!(drop_count.load(Ordering::SeqCst), 8);
|
||||
}
|
||||
|
||||
mod bench {
|
||||
use std::iter::repeat;
|
||||
use std::{mem, ptr};
|
||||
|
@ -11,7 +11,6 @@
|
||||
use ascii;
|
||||
use borrow::{Cow, ToOwned, Borrow};
|
||||
use boxed::Box;
|
||||
use clone::Clone;
|
||||
use convert::{Into, From};
|
||||
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
|
||||
use error::Error;
|
||||
@ -62,7 +61,7 @@ use vec::Vec;
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct CString {
|
||||
inner: Box<[u8]>,
|
||||
@ -250,13 +249,6 @@ impl CString {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Clone for CString {
|
||||
fn clone(&self) -> Self {
|
||||
CString { inner: self.inner.to_owned().into_boxed_slice() }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Deref for CString {
|
||||
type Target = CStr;
|
||||
|
Loading…
Reference in New Issue
Block a user