@@ -1442,6 +1442,104 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> {
14421442 }
14431443}
14441444
1445+ impl < T : ?Sized + CloneToUninit > Arc < T > {
1446+ /// Constructs a new `Arc<T>` with a clone of `value`.
1447+ ///
1448+ /// # Examples
1449+ ///
1450+ /// ```
1451+ /// #![feature(clone_from_ref)]
1452+ /// use std::sync::Arc;
1453+ ///
1454+ /// let hello: Arc<str> = Arc::clone_from_ref("hello");
1455+ /// ```
1456+ #[ cfg( not( no_global_oom_handling) ) ]
1457+ #[ unstable( feature = "clone_from_ref" , issue = "149075" ) ]
1458+ pub fn clone_from_ref ( value : & T ) -> Arc < T > {
1459+ Arc :: clone_from_ref_in ( value, Global )
1460+ }
1461+
1462+ /// Constructs a new `Arc<T>` with a clone of `value`, returning an error if allocation fails
1463+ ///
1464+ /// # Examples
1465+ ///
1466+ /// ```
1467+ /// #![feature(clone_from_ref)]
1468+ /// #![feature(allocator_api)]
1469+ /// use std::sync::Arc;
1470+ ///
1471+ /// let hello: Arc<str> = Arc::try_clone_from_ref("hello")?;
1472+ /// # Ok::<(), std::alloc::AllocError>(())
1473+ /// ```
1474+ #[ unstable( feature = "clone_from_ref" , issue = "149075" ) ]
1475+ //#[unstable(feature = "allocator_api", issue = "32838")]
1476+ pub fn try_clone_from_ref ( value : & T ) -> Result < Arc < T > , AllocError > {
1477+ Arc :: try_clone_from_ref_in ( value, Global )
1478+ }
1479+ }
1480+
1481+ impl < T : ?Sized + CloneToUninit , A : Allocator > Arc < T , A > {
1482+ /// Constructs a new `Arc<T>` with a clone of `value` in the provided allocator.
1483+ ///
1484+ /// # Examples
1485+ ///
1486+ /// ```
1487+ /// #![feature(clone_from_ref)]
1488+ /// #![feature(allocator_api)]
1489+ /// use std::sync::Arc;
1490+ /// use std::alloc::System;
1491+ ///
1492+ /// let hello: Arc<str, System> = Arc::clone_from_ref_in("hello", System);
1493+ /// ```
1494+ #[ cfg( not( no_global_oom_handling) ) ]
1495+ #[ unstable( feature = "clone_from_ref" , issue = "149075" ) ]
1496+ //#[unstable(feature = "allocator_api", issue = "32838")]
1497+ pub fn clone_from_ref_in ( value : & T , alloc : A ) -> Arc < T , A > {
1498+ // `in_progress` drops the allocation if we panic before finishing initializing it.
1499+ let mut in_progress: UniqueArcUninit < T , A > = UniqueArcUninit :: new ( value, alloc) ;
1500+
1501+ // Initialize with clone of value.
1502+ let initialized_clone = unsafe {
1503+ // Clone. If the clone panics, `in_progress` will be dropped and clean up.
1504+ value. clone_to_uninit ( in_progress. data_ptr ( ) . cast ( ) ) ;
1505+ // Cast type of pointer, now that it is initialized.
1506+ in_progress. into_arc ( )
1507+ } ;
1508+
1509+ initialized_clone
1510+ }
1511+
1512+ /// Constructs a new `Arc<T>` with a clone of `value` in the provided allocator, returning an error if allocation fails
1513+ ///
1514+ /// # Examples
1515+ ///
1516+ /// ```
1517+ /// #![feature(clone_from_ref)]
1518+ /// #![feature(allocator_api)]
1519+ /// use std::sync::Arc;
1520+ /// use std::alloc::System;
1521+ ///
1522+ /// let hello: Arc<str, System> = Arc::try_clone_from_ref_in("hello", System)?;
1523+ /// # Ok::<(), std::alloc::AllocError>(())
1524+ /// ```
1525+ #[ unstable( feature = "clone_from_ref" , issue = "149075" ) ]
1526+ //#[unstable(feature = "allocator_api", issue = "32838")]
1527+ pub fn try_clone_from_ref_in ( value : & T , alloc : A ) -> Result < Arc < T , A > , AllocError > {
1528+ // `in_progress` drops the allocation if we panic before finishing initializing it.
1529+ let mut in_progress: UniqueArcUninit < T , A > = UniqueArcUninit :: try_new ( value, alloc) ?;
1530+
1531+ // Initialize with clone of value.
1532+ let initialized_clone = unsafe {
1533+ // Clone. If the clone panics, `in_progress` will be dropped and clean up.
1534+ value. clone_to_uninit ( in_progress. data_ptr ( ) . cast ( ) ) ;
1535+ // Cast type of pointer, now that it is initialized.
1536+ in_progress. into_arc ( )
1537+ } ;
1538+
1539+ Ok ( initialized_clone)
1540+ }
1541+ }
1542+
14451543impl < T , A : Allocator > Arc < [ mem:: MaybeUninit < T > ] , A > {
14461544 /// Converts to `Arc<[T]>`.
14471545 ///
@@ -4159,6 +4257,20 @@ impl<T: ?Sized, A: Allocator> UniqueArcUninit<T, A> {
41594257 Self { ptr : NonNull :: new ( ptr) . unwrap ( ) , layout_for_value : layout, alloc : Some ( alloc) }
41604258 }
41614259
4260+ /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it,
4261+ /// returning an error if allocation fails.
4262+ fn try_new ( for_value : & T , alloc : A ) -> Result < UniqueArcUninit < T , A > , AllocError > {
4263+ let layout = Layout :: for_value ( for_value) ;
4264+ let ptr = unsafe {
4265+ Arc :: try_allocate_for_layout (
4266+ layout,
4267+ |layout_for_arcinner| alloc. allocate ( layout_for_arcinner) ,
4268+ |mem| mem. with_metadata_of ( ptr:: from_ref ( for_value) as * const ArcInner < T > ) ,
4269+ ) ?
4270+ } ;
4271+ Ok ( Self { ptr : NonNull :: new ( ptr) . unwrap ( ) , layout_for_value : layout, alloc : Some ( alloc) } )
4272+ }
4273+
41624274 /// Returns the pointer to be written into to initialize the [`Arc`].
41634275 fn data_ptr ( & mut self ) -> * mut T {
41644276 let offset = data_offset_align ( self . layout_for_value . align ( ) ) ;
0 commit comments