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`
@@ -511,3 +512,55 @@ impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> {
511
512
}
512
513
513
514
impl < T : ?Sized +Unsize < U > , U : ?Sized > CoerceUnsized < Box < U > > for Box < T > { }
515
+
516
+ #[ stable( feature = "box_slice_clone" , since = "1.3.0" ) ]
517
+ impl < T : Clone > Clone for Box < [ T ] > {
518
+ fn clone ( & self ) -> Self {
519
+ let mut new = BoxBuilder {
520
+ data : RawVec :: with_capacity ( self . len ( ) ) ,
521
+ len : 0
522
+ } ;
523
+
524
+ let mut target = new. data . ptr ( ) ;
525
+
526
+ for item in self . iter ( ) {
527
+ unsafe {
528
+ ptr:: write ( target, item. clone ( ) ) ;
529
+ target = target. offset ( 1 ) ;
530
+ } ;
531
+
532
+ new. len += 1 ;
533
+ }
534
+
535
+ return unsafe { new. into_box ( ) } ;
536
+
537
+ // Helper type for responding to panics correctly.
538
+ struct BoxBuilder < T > {
539
+ data : RawVec < T > ,
540
+ len : usize ,
541
+ }
542
+
543
+ impl < T > BoxBuilder < T > {
544
+ unsafe fn into_box ( self ) -> Box < [ T ] > {
545
+ let raw = ptr:: read ( & self . data ) ;
546
+ mem:: forget ( self ) ;
547
+ raw. into_box ( )
548
+ }
549
+ }
550
+
551
+ impl < T > Drop for BoxBuilder < T > {
552
+ fn drop ( & mut self ) {
553
+ let mut data = self . data . ptr ( ) ;
554
+ let max = unsafe { data. offset ( self . len as isize ) } ;
555
+
556
+ while data != max {
557
+ unsafe {
558
+ ptr:: read ( data) ;
559
+ data = data. offset ( 1 ) ;
560
+ }
561
+ }
562
+ }
563
+ }
564
+ }
565
+ }
566
+
0 commit comments