Implement From<&[T]>
and others for Arc
/Rc
· rust-lang/rust@8e0d01b (original) (raw)
`@@ -16,16 +16,13 @@
`
16
16
`//!
`
17
17
`//! [arc]: struct.Arc.html
`
18
18
``
19
``
`-
use boxed::Box;
`
20
``
-
21
19
`use core::sync::atomic;
`
22
20
`use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
`
23
21
`use core::borrow;
`
24
22
`use core::fmt;
`
25
23
`use core::cmp::Ordering;
`
26
24
`use core::intrinsics::abort;
`
27
``
`-
use core::mem;
`
28
``
`-
use core::mem::uninitialized;
`
``
25
`+
use core::mem::{self, size_of_val, uninitialized};
`
29
26
`use core::ops::Deref;
`
30
27
`use core::ops::CoerceUnsized;
`
31
28
`use core::ptr::{self, Shared};
`
`@@ -34,7 +31,10 @@ use core::hash::{Hash, Hasher};
`
34
31
`use core::{isize, usize};
`
35
32
`use core::convert::From;
`
36
33
``
37
``
`-
use heap::{Heap, Alloc, Layout};
`
``
34
`+
use heap::{Heap, Alloc, Layout, box_free};
`
``
35
`+
use boxed::Box;
`
``
36
`+
use string::String;
`
``
37
`+
use vec::Vec;
`
38
38
``
39
39
`` /// A soft limit on the amount of references that may be made to an Arc
.
``
40
40
`///
`
`@@ -532,6 +532,141 @@ impl<T: ?Sized> Arc {
`
532
532
`}
`
533
533
`}
`
534
534
``
``
535
`+
impl<T: ?Sized> Arc {
`
``
536
`` +
// Allocates an ArcInner<T>
with sufficient space for an unsized value
``
``
537
`+
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner {
`
``
538
`+
// Create a fake ArcInner to find allocation size and alignment
`
``
539
`+
let fake_ptr = ptr as *mut ArcInner;
`
``
540
+
``
541
`+
let layout = Layout::for_value(&*fake_ptr);
`
``
542
+
``
543
`+
let mem = Heap.alloc(layout)
`
``
544
`+
.unwrap_or_else(|e| Heap.oom(e));
`
``
545
+
``
546
`+
// Initialize the real ArcInner
`
``
547
`+
let inner = set_data_ptr(ptr as *mut T, mem) as *mut ArcInner;
`
``
548
+
``
549
`+
ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
`
``
550
`+
ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));
`
``
551
+
``
552
`+
inner
`
``
553
`+
}
`
``
554
+
``
555
`+
fn from_box(v: Box) -> Arc {
`
``
556
`+
unsafe {
`
``
557
`+
let bptr = Box::into_raw(v);
`
``
558
+
``
559
`+
let value_size = size_of_val(&*bptr);
`
``
560
`+
let ptr = Self::allocate_for_ptr(bptr);
`
``
561
+
``
562
`+
// Copy value as bytes
`
``
563
`+
ptr::copy_nonoverlapping(
`
``
564
`+
bptr as *const T as *const u8,
`
``
565
`+
&mut (*ptr).data as *mut _ as *mut u8,
`
``
566
`+
value_size);
`
``
567
+
``
568
`+
// Free the allocation without dropping its contents
`
``
569
`+
box_free(bptr);
`
``
570
+
``
571
`+
Arc { ptr: Shared::new_unchecked(ptr) }
`
``
572
`+
}
`
``
573
`+
}
`
``
574
`+
}
`
``
575
+
``
576
`` +
// Sets the data pointer of a ?Sized
raw pointer.
``
``
577
`+
//
`
``
578
`` +
// For a slice/trait object, this sets the data
field and leaves the rest
``
``
579
`+
// unchanged. For a sized raw pointer, this simply sets the pointer.
`
``
580
`+
unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T {
`
``
581
`+
ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8);
`
``
582
`+
ptr
`
``
583
`+
}
`
``
584
+
``
585
`+
impl Arc<[T]> {
`
``
586
`+
// Copy elements from slice into newly allocated Arc<[T]>
`
``
587
`+
//
`
``
588
`` +
// Unsafe because the caller must either take ownership or bind T: Copy
``
``
589
`+
unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> {
`
``
590
`+
let v_ptr = v as *const [T];
`
``
591
`+
let ptr = Self::allocate_for_ptr(v_ptr);
`
``
592
+
``
593
`+
ptr::copy_nonoverlapping(
`
``
594
`+
v.as_ptr(),
`
``
595
`+
&mut (*ptr).data as *mut [T] as *mut T,
`
``
596
`+
v.len());
`
``
597
+
``
598
`+
Arc { ptr: Shared::new_unchecked(ptr) }
`
``
599
`+
}
`
``
600
`+
}
`
``
601
+
``
602
`+
// Specialization trait used for From<&[T]>
`
``
603
`+
trait ArcFromSlice {
`
``
604
`+
fn from_slice(slice: &[T]) -> Self;
`
``
605
`+
}
`
``
606
+
``
607
`+
impl<T: Clone> ArcFromSlice for Arc<[T]> {
`
``
608
`+
#[inline]
`
``
609
`+
default fn from_slice(v: &[T]) -> Self {
`
``
610
`+
// Panic guard while cloning T elements.
`
``
611
`+
// In the event of a panic, elements that have been written
`
``
612
`+
// into the new ArcInner will be dropped, then the memory freed.
`
``
613
`+
struct Guard {
`
``
614
`+
mem: *mut u8,
`
``
615
`+
elems: *mut T,
`
``
616
`+
layout: Layout,
`
``
617
`+
n_elems: usize,
`
``
618
`+
}
`
``
619
+
``
620
`+
impl Drop for Guard {
`
``
621
`+
fn drop(&mut self) {
`
``
622
`+
use core::slice::from_raw_parts_mut;
`
``
623
+
``
624
`+
unsafe {
`
``
625
`+
let slice = from_raw_parts_mut(self.elems, self.n_elems);
`
``
626
`+
ptr::drop_in_place(slice);
`
``
627
+
``
628
`+
Heap.dealloc(self.mem, self.layout.clone());
`
``
629
`+
}
`
``
630
`+
}
`
``
631
`+
}
`
``
632
+
``
633
`+
unsafe {
`
``
634
`+
let v_ptr = v as *const [T];
`
``
635
`+
let ptr = Self::allocate_for_ptr(v_ptr);
`
``
636
+
``
637
`+
let mem = ptr as *mut _ as *mut u8;
`
``
638
`+
let layout = Layout::for_value(&*ptr);
`
``
639
+
``
640
`+
// Pointer to first element
`
``
641
`+
let elems = &mut (*ptr).data as *mut [T] as *mut T;
`
``
642
+
``
643
`+
let mut guard = Guard{
`
``
644
`+
mem: mem,
`
``
645
`+
elems: elems,
`
``
646
`+
layout: layout,
`
``
647
`+
n_elems: 0,
`
``
648
`+
};
`
``
649
+
``
650
`+
for (i, item) in v.iter().enumerate() {
`
``
651
`+
ptr::write(elems.offset(i as isize), item.clone());
`
``
652
`+
guard.n_elems += 1;
`
``
653
`+
}
`
``
654
+
``
655
`+
// All clear. Forget the guard so it doesn't free the new ArcInner.
`
``
656
`+
mem::forget(guard);
`
``
657
+
``
658
`+
Arc { ptr: Shared::new_unchecked(ptr) }
`
``
659
`+
}
`
``
660
`+
}
`
``
661
`+
}
`
``
662
+
``
663
`+
impl<T: Copy> ArcFromSlice for Arc<[T]> {
`
``
664
`+
#[inline]
`
``
665
`+
fn from_slice(v: &[T]) -> Self {
`
``
666
`+
unsafe { Arc::copy_from_slice(v) }
`
``
667
`+
}
`
``
668
`+
}
`
``
669
+
535
670
`#[stable(feature = "rust1", since = "1.0.0")]
`
536
671
`impl<T: ?Sized> Clone for Arc {
`
537
672
`` /// Makes a clone of the Arc
pointer.
``
`@@ -1216,8 +1351,56 @@ impl From for Arc {
`
1216
1351
`}
`
1217
1352
`}
`
1218
1353
``
``
1354
`+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
`
``
1355
`+
impl<'a, T: Clone> From<&'a [T]> for Arc<[T]> {
`
``
1356
`+
#[inline]
`
``
1357
`+
fn from(v: &[T]) -> Arc<[T]> {
`
``
1358
`+
<Self as ArcFromSlice>::from_slice(v)
`
``
1359
`+
}
`
``
1360
`+
}
`
``
1361
+
``
1362
`+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
`
``
1363
`+
impl<'a> From<&'a str> for Arc {
`
``
1364
`+
#[inline]
`
``
1365
`+
fn from(v: &str) -> Arc {
`
``
1366
`+
unsafe { mem::transmute(<Arc<[u8]>>::from(v.as_bytes())) }
`
``
1367
`+
}
`
``
1368
`+
}
`
``
1369
+
``
1370
`+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
`
``
1371
`+
impl From for Arc {
`
``
1372
`+
#[inline]
`
``
1373
`+
fn from(v: String) -> Arc {
`
``
1374
`+
Arc::from(&v[..])
`
``
1375
`+
}
`
``
1376
`+
}
`
``
1377
+
``
1378
`+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
`
``
1379
`+
impl<T: ?Sized> From<Box> for Arc {
`
``
1380
`+
#[inline]
`
``
1381
`+
fn from(v: Box) -> Arc {
`
``
1382
`+
Arc::from_box(v)
`
``
1383
`+
}
`
``
1384
`+
}
`
``
1385
+
``
1386
`+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
`
``
1387
`+
impl From<Vec> for Arc<[T]> {
`
``
1388
`+
#[inline]
`
``
1389
`+
fn from(mut v: Vec) -> Arc<[T]> {
`
``
1390
`+
unsafe {
`
``
1391
`+
let arc = Arc::copy_from_slice(&v);
`
``
1392
+
``
1393
`+
// Allow the Vec to free its memory, but not destroy its contents
`
``
1394
`+
v.set_len(0);
`
``
1395
+
``
1396
`+
arc
`
``
1397
`+
}
`
``
1398
`+
}
`
``
1399
`+
}
`
``
1400
+
1219
1401
`#[cfg(test)]
`
1220
1402
`mod tests {
`
``
1403
`+
use std::boxed::Box;
`
1221
1404
`use std::clone::Clone;
`
1222
1405
`use std::sync::mpsc::channel;
`
1223
1406
`use std::mem::drop;
`
`@@ -1520,6 +1703,113 @@ mod tests {
`
1520
1703
`}
`
1521
1704
` t.join().unwrap();
`
1522
1705
`}
`
``
1706
+
``
1707
`+
#[test]
`
``
1708
`+
fn test_from_str() {
`
``
1709
`+
let r: Arc = Arc::from("foo");
`
``
1710
+
``
1711
`+
assert_eq!(&r[..], "foo");
`
``
1712
`+
}
`
``
1713
+
``
1714
`+
#[test]
`
``
1715
`+
fn test_copy_from_slice() {
`
``
1716
`+
let s: &[u32] = &[1, 2, 3];
`
``
1717
`+
let r: Arc<[u32]> = Arc::from(s);
`
``
1718
+
``
1719
`+
assert_eq!(&r[..], [1, 2, 3]);
`
``
1720
`+
}
`
``
1721
+
``
1722
`+
#[test]
`
``
1723
`+
fn test_clone_from_slice() {
`
``
1724
`+
#[derive(Clone, Debug, Eq, PartialEq)]
`
``
1725
`+
struct X(u32);
`
``
1726
+
``
1727
`+
let s: &[X] = &[X(1), X(2), X(3)];
`
``
1728
`+
let r: Arc<[X]> = Arc::from(s);
`
``
1729
+
``
1730
`+
assert_eq!(&r[..], s);
`
``
1731
`+
}
`
``
1732
+
``
1733
`+
#[test]
`
``
1734
`+
#[should_panic]
`
``
1735
`+
fn test_clone_from_slice_panic() {
`
``
1736
`+
use std:🧵:{String, ToString};
`
``
1737
+
``
1738
`+
struct Fail(u32, String);
`
``
1739
+
``
1740
`+
impl Clone for Fail {
`
``
1741
`+
fn clone(&self) -> Fail {
`
``
1742
`+
if self.0 == 2 {
`
``
1743
`+
panic!();
`
``
1744
`+
}
`
``
1745
`+
Fail(self.0, self.1.clone())
`
``
1746
`+
}
`
``
1747
`+
}
`
``
1748
+
``
1749
`+
let s: &[Fail] = &[
`
``
1750
`+
Fail(0, "foo".to_string()),
`
``
1751
`+
Fail(1, "bar".to_string()),
`
``
1752
`+
Fail(2, "baz".to_string()),
`
``
1753
`+
];
`
``
1754
+
``
1755
`+
// Should panic, but not cause memory corruption
`
``
1756
`+
let _r: Arc<[Fail]> = Arc::from(s);
`
``
1757
`+
}
`
``
1758
+
``
1759
`+
#[test]
`
``
1760
`+
fn test_from_box() {
`
``
1761
`+
let b: Box = box 123;
`
``
1762
`+
let r: Arc = Arc::from(b);
`
``
1763
+
``
1764
`+
assert_eq!(*r, 123);
`
``
1765
`+
}
`
``
1766
+
``
1767
`+
#[test]
`
``
1768
`+
fn test_from_box_str() {
`
``
1769
`+
use std:🧵:String;
`
``
1770
+
``
1771
`+
let s = String::from("foo").into_boxed_str();
`
``
1772
`+
let r: Arc = Arc::from(s);
`
``
1773
+
``
1774
`+
assert_eq!(&r[..], "foo");
`
``
1775
`+
}
`
``
1776
+
``
1777
`+
#[test]
`
``
1778
`+
fn test_from_box_slice() {
`
``
1779
`+
let s = vec![1, 2, 3].into_boxed_slice();
`
``
1780
`+
let r: Arc<[u32]> = Arc::from(s);
`
``
1781
+
``
1782
`+
assert_eq!(&r[..], [1, 2, 3]);
`
``
1783
`+
}
`
``
1784
+
``
1785
`+
#[test]
`
``
1786
`+
fn test_from_box_trait() {
`
``
1787
`+
use std::fmt::Display;
`
``
1788
`+
use std:🧵:ToString;
`
``
1789
+
``
1790
`+
let b: Box = box 123;
`
``
1791
`+
let r: Arc = Arc::from(b);
`
``
1792
+
``
1793
`+
assert_eq!(r.to_string(), "123");
`
``
1794
`+
}
`
``
1795
+
``
1796
`+
#[test]
`
``
1797
`+
fn test_from_box_trait_zero_sized() {
`
``
1798
`+
use std::fmt::Debug;
`
``
1799
+
``
1800
`+
let b: Box = box ();
`
``
1801
`+
let r: Arc = Arc::from(b);
`
``
1802
+
``
1803
`+
assert_eq!(format!("{:?}", r), "()");
`
``
1804
`+
}
`
``
1805
+
``
1806
`+
#[test]
`
``
1807
`+
fn test_from_vec() {
`
``
1808
`+
let v = vec![1, 2, 3];
`
``
1809
`+
let r: Arc<[u32]> = Arc::from(v);
`
``
1810
+
``
1811
`+
assert_eq!(&r[..], [1, 2, 3]);
`
``
1812
`+
}
`
1523
1813
`}
`
1524
1814
``
1525
1815
`#[stable(feature = "rust1", since = "1.0.0")]
`