@@ -143,6 +143,7 @@ pub use hack::to_vec;
143143// `test_permutations` test
144144mod hack {
145145 use core:: alloc:: Allocator ;
146+ use core:: mem:: MaybeUninit ;
146147
147148 use crate :: boxed:: Box ;
148149 use crate :: vec:: Vec ;
@@ -163,10 +164,19 @@ mod hack {
163164 T :: to_vec ( s, alloc)
164165 }
165166
167+ #[ inline]
168+ pub fn to_boxed_slice < T : ConvertVec , A : Allocator > ( s : & [ T ] , alloc : A ) -> Box < [ T ] , A > {
169+ T :: to_boxed_slice ( s, alloc)
170+ }
171+
166172 pub trait ConvertVec {
167173 fn to_vec < A : Allocator > ( s : & [ Self ] , alloc : A ) -> Vec < Self , A >
168174 where
169175 Self : Sized ;
176+
177+ fn to_boxed_slice < A : Allocator > ( s : & [ Self ] , alloc : A ) -> Box < [ Self ] , A >
178+ where
179+ Self : Sized ;
170180 }
171181
172182 impl < T : Clone > ConvertVec for T {
@@ -203,6 +213,35 @@ mod hack {
203213 }
204214 vec
205215 }
216+
217+ #[ inline]
218+ default fn to_boxed_slice < A : Allocator > ( s : & [ Self ] , alloc : A ) -> Box < [ Self ] , A > {
219+ struct DropGuard < T > {
220+ dst : * mut T ,
221+ num_init : usize ,
222+ }
223+ impl < T > Drop for DropGuard < T > {
224+ #[ inline]
225+ fn drop ( & mut self ) {
226+ let init_slice = core:: ptr:: slice_from_raw_parts_mut ( self . dst , self . num_init ) ;
227+ // SAFETY: all elements in this slice have been initialized
228+ unsafe {
229+ core:: ptr:: drop_in_place ( init_slice) ;
230+ }
231+ }
232+ }
233+
234+ let mut boxed = Box :: new_uninit_slice_in ( s. len ( ) , alloc) ;
235+ let mut guard =
236+ DropGuard { dst : MaybeUninit :: slice_as_mut_ptr ( & mut boxed) , num_init : 0 } ;
237+ while guard. num_init < s. len ( ) {
238+ boxed[ guard. num_init ] . write ( s[ guard. num_init ] . clone ( ) ) ;
239+ guard. num_init += 1 ;
240+ }
241+ core:: mem:: forget ( guard) ;
242+ // SAFETY: each element is initialized by the loop above
243+ unsafe { boxed. assume_init ( ) }
244+ }
206245 }
207246
208247 impl < T : Copy > ConvertVec for T {
@@ -218,6 +257,17 @@ mod hack {
218257 }
219258 v
220259 }
260+
261+ #[ inline]
262+ fn to_boxed_slice < A : Allocator > ( s : & [ Self ] , alloc : A ) -> Box < [ Self ] , A > {
263+ let mut boxed = Box :: new_uninit_slice_in ( s. len ( ) , alloc) ;
264+ let boxed_ptr = MaybeUninit :: slice_as_mut_ptr ( & mut boxed) ;
265+ // SAFETY: `boxed` contains `s.len()` elements and all are initialized
266+ unsafe {
267+ s. as_ptr ( ) . copy_to_nonoverlapping ( boxed_ptr, s. len ( ) ) ;
268+ boxed. assume_init ( )
269+ }
270+ }
221271 }
222272}
223273
@@ -477,6 +527,49 @@ impl<T> [T] {
477527 hack:: to_vec ( self , alloc)
478528 }
479529
530+ /// Clones `self` into a new boxed slice.
531+ ///
532+ /// # Examples
533+ ///
534+ /// ```
535+ /// #![feature(slice_to_boxed)]
536+ ///
537+ /// let s = [1, 2, 3];
538+ /// let x: Box<[i32]> = s.to_boxed_slice();
539+ /// assert_eq!(&s, x.as_ref());
540+ /// ```
541+ #[ inline]
542+ #[ unstable( feature = "slice_to_boxed" , issue = "82725" ) ]
543+ pub fn to_boxed_slice ( & self ) -> Box < Self >
544+ where
545+ T : Clone ,
546+ {
547+ self . to_boxed_slice_in ( Global )
548+ }
549+
550+ /// Clones `self` into a new boxed slice with an allocator.
551+ ///
552+ /// # Examples
553+ ///
554+ /// ```
555+ /// #![feature(allocator_api)]
556+ ///
557+ /// use std::alloc::System;
558+ ///
559+ /// let s = [1, 2, 3];
560+ /// let x: Box<[i32], System> = s.to_boxed_slice_in(System);
561+ /// assert_eq!(&s, x.as_ref());
562+ /// ```
563+ #[ inline]
564+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
565+ // #[unstable(feature = "slice_to_boxed", issue = "82725")]
566+ pub fn to_boxed_slice_in < A : Allocator > ( & self , alloc : A ) -> Box < Self , A >
567+ where
568+ T : Clone ,
569+ {
570+ hack:: to_boxed_slice ( self , alloc)
571+ }
572+
480573 /// Converts `self` into a vector without clones or allocation.
481574 ///
482575 /// The resulting vector can be converted back into a box via
0 commit comments