11use crate :: alloc:: Allocator ;
2- use core:: iter:: TrustedLen ;
2+ use core:: iter:: { TrustedLen , TrustedRandomAccess } ;
33use core:: ptr:: { self } ;
44use core:: slice:: { self } ;
55
@@ -11,6 +11,49 @@ pub(super) trait SpecExtend<T, I> {
1111}
1212
1313impl < T , I , A : Allocator > SpecExtend < T , I > for Vec < T , A >
14+ where
15+ I : Iterator < Item = T > ,
16+ {
17+ default fn spec_extend ( & mut self , iter : I ) {
18+ SpecExtendInner :: spec_extend ( self , iter) ;
19+ }
20+ }
21+
22+ impl < T , A : Allocator > SpecExtend < T , IntoIter < T > > for Vec < T , A > {
23+ fn spec_extend ( & mut self , mut iterator : IntoIter < T > ) {
24+ unsafe {
25+ self . append_elements ( iterator. as_slice ( ) as _ ) ;
26+ }
27+ iterator. ptr = iterator. end ;
28+ }
29+ }
30+
31+ impl < ' a , T : ' a , I , A : Allocator + ' a > SpecExtend < & ' a T , I > for Vec < T , A >
32+ where
33+ I : Iterator < Item = & ' a T > ,
34+ T : Clone ,
35+ {
36+ default fn spec_extend ( & mut self , iterator : I ) {
37+ SpecExtend :: spec_extend ( self , iterator. cloned ( ) )
38+ }
39+ }
40+
41+ impl < ' a , T : ' a , A : Allocator + ' a > SpecExtend < & ' a T , slice:: Iter < ' a , T > > for Vec < T , A >
42+ where
43+ T : Copy ,
44+ {
45+ fn spec_extend ( & mut self , iterator : slice:: Iter < ' a , T > ) {
46+ let slice = iterator. as_slice ( ) ;
47+ unsafe { self . append_elements ( slice) } ;
48+ }
49+ }
50+
51+ // Helper trait to disambiguate overlapping specializations
52+ trait SpecExtendInner < T , I > {
53+ fn spec_extend ( & mut self , iter : I ) ;
54+ }
55+
56+ impl < T , I , A : Allocator > SpecExtendInner < T , I > for Vec < T , A >
1457where
1558 I : Iterator < Item = T > ,
1659{
1962 }
2063}
2164
22- impl < T , I , A : Allocator > SpecExtend < T , I > for Vec < T , A >
65+ impl < T , I , A : Allocator > SpecExtendInner < T , I > for Vec < T , A >
2366where
2467 I : TrustedLen < Item = T > ,
2568{
@@ -57,31 +100,22 @@ where
57100 }
58101}
59102
60- impl < T , A : Allocator > SpecExtend < T , IntoIter < T > > for Vec < T , A > {
61- fn spec_extend ( & mut self , mut iterator : IntoIter < T > ) {
62- unsafe {
63- self . append_elements ( iterator. as_slice ( ) as _ ) ;
64- }
65- iterator. ptr = iterator. end ;
66- }
67- }
68-
69- impl < ' a , T : ' a , I , A : Allocator + ' a > SpecExtend < & ' a T , I > for Vec < T , A >
103+ impl < T , I , A : Allocator > SpecExtendInner < T , I > for Vec < T , A >
70104where
71- I : Iterator < Item = & ' a T > ,
72- T : Clone ,
105+ I : TrustedLen < Item = T > + TrustedRandomAccess ,
73106{
74- default fn spec_extend ( & mut self , iterator : I ) {
75- self . spec_extend ( iterator. cloned ( ) )
76- }
77- }
107+ default fn spec_extend ( & mut self , mut iterator : I ) {
108+ let size = iterator. size ( ) ;
109+ self . reserve ( size) ;
78110
79- impl < ' a , T : ' a , A : Allocator + ' a > SpecExtend < & ' a T , slice:: Iter < ' a , T > > for Vec < T , A >
80- where
81- T : Copy ,
82- {
83- fn spec_extend ( & mut self , iterator : slice:: Iter < ' a , T > ) {
84- let slice = iterator. as_slice ( ) ;
85- unsafe { self . append_elements ( slice) } ;
111+ // SAFETY: reserve ensured that there is sufficient capacity for the additional items.
112+ // The loop upholds the TRA requirements by accessing each element only once.
113+ unsafe {
114+ let sink = self . as_mut_ptr ( ) . add ( self . len ( ) ) ;
115+ for i in 0 ..size {
116+ ptr:: write ( sink. add ( i) , iterator. __iterator_get_unchecked ( i) ) ;
117+ self . set_len ( self . len ( ) + 1 ) ;
118+ }
119+ }
86120 }
87121}
0 commit comments