@@ -143,6 +143,7 @@ pub use hack::to_vec;
143
143
// `test_permutations` test
144
144
mod hack {
145
145
use core:: alloc:: Allocator ;
146
+ use core:: mem:: MaybeUninit ;
146
147
147
148
use crate :: boxed:: Box ;
148
149
use crate :: vec:: Vec ;
@@ -163,10 +164,19 @@ mod hack {
163
164
T :: to_vec ( s, alloc)
164
165
}
165
166
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
+
166
172
pub trait ConvertVec {
167
173
fn to_vec < A : Allocator > ( s : & [ Self ] , alloc : A ) -> Vec < Self , A >
168
174
where
169
175
Self : Sized ;
176
+
177
+ fn to_boxed_slice < A : Allocator > ( s : & [ Self ] , alloc : A ) -> Box < [ Self ] , A >
178
+ where
179
+ Self : Sized ;
170
180
}
171
181
172
182
impl < T : Clone > ConvertVec for T {
@@ -203,6 +213,35 @@ mod hack {
203
213
}
204
214
vec
205
215
}
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
+ }
206
245
}
207
246
208
247
impl < T : Copy > ConvertVec for T {
@@ -218,6 +257,17 @@ mod hack {
218
257
}
219
258
v
220
259
}
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
+ }
221
271
}
222
272
}
223
273
@@ -477,6 +527,49 @@ impl<T> [T] {
477
527
hack:: to_vec ( self , alloc)
478
528
}
479
529
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
+
480
573
/// Converts `self` into a vector without clones or allocation.
481
574
///
482
575
/// The resulting vector can be converted back into a box via
0 commit comments