@@ -1497,6 +1497,34 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
14971497 ptr
14981498 }
14991499
1500+ /// Consumes the `Arc`, returning the wrapped pointer and allocator.
1501+ ///
1502+ /// To avoid a memory leak the pointer must be converted back to an `Arc` using
1503+ /// [`Arc::from_raw_in`].
1504+ ///
1505+ /// # Examples
1506+ ///
1507+ /// ```
1508+ /// #![feature(allocator_api)]
1509+ /// use std::sync::Arc;
1510+ /// use std::alloc::System;
1511+ ///
1512+ /// let x = Arc::new_in("hello".to_owned(), System);
1513+ /// let (ptr, alloc) = Arc::into_raw_with_allocator(x);
1514+ /// assert_eq!(unsafe { &*ptr }, "hello");
1515+ /// let x = unsafe { Arc::from_raw_in(ptr, alloc) };
1516+ /// assert_eq!(&*x, "hello");
1517+ /// ```
1518+ #[ must_use = "losing the pointer will leak memory" ]
1519+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1520+ pub fn into_raw_with_allocator ( this : Self ) -> ( * const T , A ) {
1521+ let this = mem:: ManuallyDrop :: new ( this) ;
1522+ let ptr = Self :: as_ptr ( & this) ;
1523+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1524+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
1525+ ( ptr, alloc)
1526+ }
1527+
15001528 /// Provides a raw pointer to the data.
15011529 ///
15021530 /// The counts are not affected in any way and the `Arc` is not consumed. The pointer is valid for
@@ -2739,6 +2767,45 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
27392767 result
27402768 }
27412769
2770+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator.
2771+ ///
2772+ /// This converts the weak pointer into a raw pointer, while still preserving the ownership of
2773+ /// one weak reference (the weak count is not modified by this operation). It can be turned
2774+ /// back into the `Weak<T>` with [`from_raw_in`].
2775+ ///
2776+ /// The same restrictions of accessing the target of the pointer as with
2777+ /// [`as_ptr`] apply.
2778+ ///
2779+ /// # Examples
2780+ ///
2781+ /// ```
2782+ /// #![feature(allocator_api)]
2783+ /// use std::sync::{Arc, Weak};
2784+ /// use std::alloc::System;
2785+ ///
2786+ /// let strong = Arc::new_in("hello".to_owned(), System);
2787+ /// let weak = Arc::downgrade(&strong);
2788+ /// let (raw, alloc) = weak.into_raw_with_allocator();
2789+ ///
2790+ /// assert_eq!(1, Arc::weak_count(&strong));
2791+ /// assert_eq!("hello", unsafe { &*raw });
2792+ ///
2793+ /// drop(unsafe { Weak::from_raw_in(raw, alloc) });
2794+ /// assert_eq!(0, Arc::weak_count(&strong));
2795+ /// ```
2796+ ///
2797+ /// [`from_raw_in`]: Weak::from_raw_in
2798+ /// [`as_ptr`]: Weak::as_ptr
2799+ #[ must_use = "losing the pointer will leak memory" ]
2800+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
2801+ pub fn into_raw_with_allocator ( self ) -> ( * const T , A ) {
2802+ let this = mem:: ManuallyDrop :: new ( self ) ;
2803+ let result = this. as_ptr ( ) ;
2804+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
2805+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
2806+ ( result, alloc)
2807+ }
2808+
27422809 /// Converts a raw pointer previously created by [`into_raw`] back into `Weak<T>` in the provided
27432810 /// allocator.
27442811 ///
0 commit comments