1616//!
1717//! [arc]: struct.Arc.html
1818
19- use boxed:: Box ;
20-
2119use core:: sync:: atomic;
2220use core:: sync:: atomic:: Ordering :: { Acquire , Relaxed , Release , SeqCst } ;
2321use core:: borrow;
2422use core:: fmt;
2523use core:: cmp:: Ordering ;
2624use core:: intrinsics:: abort;
27- use core:: mem;
28- use core:: mem:: uninitialized;
25+ use core:: mem:: { self , size_of_val, uninitialized} ;
2926use core:: ops:: Deref ;
3027use core:: ops:: CoerceUnsized ;
3128use core:: ptr:: { self , Shared } ;
@@ -34,7 +31,10 @@ use core::hash::{Hash, Hasher};
3431use core:: { isize, usize} ;
3532use core:: convert:: From ;
3633
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 ;
3838
3939/// A soft limit on the amount of references that may be made to an `Arc`.
4040///
@@ -532,6 +532,141 @@ impl<T: ?Sized> Arc<T> {
532532 }
533533}
534534
535+ impl < T : ?Sized > Arc < T > {
536+ // Allocates an `ArcInner<T>` with sufficient space for an unsized value
537+ unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut ArcInner < T > {
538+ // Create a fake ArcInner to find allocation size and alignment
539+ let fake_ptr = ptr as * mut ArcInner < T > ;
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 < T > ;
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 < T > ) -> Arc < T > {
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 < T > 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 < T > {
604+ fn from_slice ( slice : & [ T ] ) -> Self ;
605+ }
606+
607+ impl < T : Clone > ArcFromSlice < T > 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 < T > {
614+ mem : * mut u8 ,
615+ elems : * mut T ,
616+ layout : Layout ,
617+ n_elems : usize ,
618+ }
619+
620+ impl < T > Drop for Guard < T > {
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 < T > for Arc < [ T ] > {
664+ #[ inline]
665+ fn from_slice ( v : & [ T ] ) -> Self {
666+ unsafe { Arc :: copy_from_slice ( v) }
667+ }
668+ }
669+
535670#[ stable( feature = "rust1" , since = "1.0.0" ) ]
536671impl < T : ?Sized > Clone for Arc < T > {
537672 /// Makes a clone of the `Arc` pointer.
@@ -1216,8 +1351,56 @@ impl<T> From<T> for Arc<T> {
12161351 }
12171352}
12181353
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 < T > >:: from_slice ( v)
1359+ }
1360+ }
1361+
1362+ #[ stable( feature = "shared_from_slice" , since = "1.21.0" ) ]
1363+ impl < ' a > From < & ' a str > for Arc < str > {
1364+ #[ inline]
1365+ fn from ( v : & str ) -> Arc < str > {
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 < String > for Arc < str > {
1372+ #[ inline]
1373+ fn from ( v : String ) -> Arc < str > {
1374+ Arc :: from ( & v[ ..] )
1375+ }
1376+ }
1377+
1378+ #[ stable( feature = "shared_from_slice" , since = "1.21.0" ) ]
1379+ impl < T : ?Sized > From < Box < T > > for Arc < T > {
1380+ #[ inline]
1381+ fn from ( v : Box < T > ) -> Arc < T > {
1382+ Arc :: from_box ( v)
1383+ }
1384+ }
1385+
1386+ #[ stable( feature = "shared_from_slice" , since = "1.21.0" ) ]
1387+ impl < T > From < Vec < T > > for Arc < [ T ] > {
1388+ #[ inline]
1389+ fn from ( mut v : Vec < T > ) -> 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+
12191401#[ cfg( test) ]
12201402mod tests {
1403+ use std:: boxed:: Box ;
12211404 use std:: clone:: Clone ;
12221405 use std:: sync:: mpsc:: channel;
12231406 use std:: mem:: drop;
@@ -1520,6 +1703,113 @@ mod tests {
15201703 }
15211704 t. join ( ) . unwrap ( ) ;
15221705 }
1706+
1707+ #[ test]
1708+ fn test_from_str ( ) {
1709+ let r: Arc < str > = 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:: { 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 < u32 > = box 123 ;
1762+ let r: Arc < u32 > = Arc :: from ( b) ;
1763+
1764+ assert_eq ! ( * r, 123 ) ;
1765+ }
1766+
1767+ #[ test]
1768+ fn test_from_box_str ( ) {
1769+ use std:: string:: String ;
1770+
1771+ let s = String :: from ( "foo" ) . into_boxed_str ( ) ;
1772+ let r: Arc < str > = 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:: string:: ToString ;
1789+
1790+ let b: Box < Display > = box 123 ;
1791+ let r: Arc < Display > = 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 < Debug > = box ( ) ;
1801+ let r: Arc < Debug > = 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+ }
15231813}
15241814
15251815#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments