56
56
use core:: prelude:: * ;
57
57
58
58
use heap;
59
+ use raw_vec:: RawVec ;
59
60
60
61
use core:: any:: Any ;
61
62
use core:: cmp:: Ordering ;
@@ -65,7 +66,7 @@ use core::marker::{self, Unsize};
65
66
use core:: mem;
66
67
use core:: ops:: { CoerceUnsized , Deref , DerefMut } ;
67
68
use core:: ops:: { Placer , Boxed , Place , InPlace , BoxPlace } ;
68
- use core:: ptr:: Unique ;
69
+ use core:: ptr:: { self , Unique } ;
69
70
use core:: raw:: { TraitObject } ;
70
71
71
72
/// A value that represents the heap. This is the default place that the `box`
@@ -514,3 +515,55 @@ impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> {
514
515
}
515
516
516
517
impl < T : ?Sized +Unsize < U > , U : ?Sized > CoerceUnsized < Box < U > > for Box < T > { }
518
+
519
+ #[ stable( feature = "box_slice_clone" , since = "1.3.0" ) ]
520
+ impl < T : Clone > Clone for Box < [ T ] > {
521
+ fn clone ( & self ) -> Self {
522
+ let mut new = BoxBuilder {
523
+ data : RawVec :: with_capacity ( self . len ( ) ) ,
524
+ len : 0
525
+ } ;
526
+
527
+ let mut target = new. data . ptr ( ) ;
528
+
529
+ for item in self . iter ( ) {
530
+ unsafe {
531
+ ptr:: write ( target, item. clone ( ) ) ;
532
+ target = target. offset ( 1 ) ;
533
+ } ;
534
+
535
+ new. len += 1 ;
536
+ }
537
+
538
+ return unsafe { new. into_box ( ) } ;
539
+
540
+ // Helper type for responding to panics correctly.
541
+ struct BoxBuilder < T > {
542
+ data : RawVec < T > ,
543
+ len : usize ,
544
+ }
545
+
546
+ impl < T > BoxBuilder < T > {
547
+ unsafe fn into_box ( self ) -> Box < [ T ] > {
548
+ let raw = ptr:: read ( & self . data ) ;
549
+ mem:: forget ( self ) ;
550
+ raw. into_box ( )
551
+ }
552
+ }
553
+
554
+ impl < T > Drop for BoxBuilder < T > {
555
+ fn drop ( & mut self ) {
556
+ let mut data = self . data . ptr ( ) ;
557
+ let max = unsafe { data. offset ( self . len as isize ) } ;
558
+
559
+ while data != max {
560
+ unsafe {
561
+ ptr:: read ( data) ;
562
+ data = data. offset ( 1 ) ;
563
+ }
564
+ }
565
+ }
566
+ }
567
+ }
568
+ }
569
+
0 commit comments