11//! Defines the `IntoIter` owned iterator for arrays.
22
3+ use crate :: clone:: TrivialClone ;
34use crate :: mem:: MaybeUninit ;
45use crate :: num:: NonZero ;
56use crate :: ops:: { IndexRange , NeverShortCircuit , Try } ;
6- use crate :: { fmt, iter} ;
7+ use crate :: { fmt, iter, ptr } ;
78
89#[ allow( private_bounds) ]
910trait PartialDrop {
@@ -99,9 +100,26 @@ impl<T, const N: usize> PolymorphicIter<[MaybeUninit<T>; N]> {
99100impl < T : Clone , const N : usize > Clone for PolymorphicIter < [ MaybeUninit < T > ; N ] > {
100101 #[ inline]
101102 fn clone ( & self ) -> Self {
103+ SpecPolymorphicIterClone :: < N > :: spec_clone ( self )
104+ }
105+ }
106+
107+ trait SpecPolymorphicIterClone < const N : usize > {
108+ fn spec_clone (
109+ this : & PolymorphicIter < [ MaybeUninit < Self > ; N ] > ,
110+ ) -> PolymorphicIter < [ MaybeUninit < Self > ; N ] >
111+ where
112+ Self : Sized ;
113+ }
114+
115+ impl < T : Clone , const N : usize > SpecPolymorphicIterClone < N > for T {
116+ #[ inline]
117+ default fn spec_clone (
118+ this : & PolymorphicIter < [ MaybeUninit < Self > ; N ] > ,
119+ ) -> PolymorphicIter < [ MaybeUninit < Self > ; N ] > {
102120 // Note, we don't really need to match the exact same alive range, so
103121 // we can just clone into offset 0 regardless of where `self` is.
104- let mut new = Self :: empty ( ) ;
122+ let mut new = PolymorphicIter :: < [ MaybeUninit < T > ; N ] > :: empty ( ) ;
105123
106124 fn clone_into_new < U : Clone > (
107125 source : & PolymorphicIter < [ MaybeUninit < U > ] > ,
@@ -118,7 +136,33 @@ impl<T: Clone, const N: usize> Clone for PolymorphicIter<[MaybeUninit<T>; N]> {
118136 }
119137 }
120138
121- clone_into_new ( self , & mut new) ;
139+ clone_into_new ( this, & mut new) ;
140+ new
141+ }
142+ }
143+
144+ impl < T : TrivialClone , const N : usize > SpecPolymorphicIterClone < N > for T {
145+ #[ inline]
146+ fn spec_clone (
147+ this : & PolymorphicIter < [ MaybeUninit < Self > ; N ] > ,
148+ ) -> PolymorphicIter < [ MaybeUninit < Self > ; N ] > {
149+ // Note, we don't really need to match the exact same alive range, so
150+ // we can just clone into offset 0 regardless of where `self` is.
151+ let mut new = PolymorphicIter :: < [ MaybeUninit < T > ; N ] > :: empty ( ) ;
152+
153+ let len = this. alive . len ( ) ;
154+
155+ // SAFETY: These two allocations can not overlap since `new` is allocated
156+ // on the stack of this function.
157+ unsafe {
158+ ptr:: copy_nonoverlapping (
159+ this. data . as_ptr ( ) . add ( this. alive . start ( ) ) ,
160+ new. data . as_mut_ptr ( ) ,
161+ len,
162+ ) ;
163+ new. alive = IndexRange :: zero_to ( len) ;
164+ }
165+
122166 new
123167 }
124168}
0 commit comments