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{
@@ -55,31 +98,22 @@ where
5598 }
5699}
57100
58- impl < T , A : Allocator > SpecExtend < T , IntoIter < T > > for Vec < T , A > {
59- fn spec_extend ( & mut self , mut iterator : IntoIter < T > ) {
60- unsafe {
61- self . append_elements ( iterator. as_slice ( ) as _ ) ;
62- }
63- iterator. ptr = iterator. end ;
64- }
65- }
66-
67- impl < ' a , T : ' a , I , A : Allocator + ' a > SpecExtend < & ' a T , I > for Vec < T , A >
101+ impl < T , I , A : Allocator > SpecExtendInner < T , I > for Vec < T , A >
68102where
69- I : Iterator < Item = & ' a T > ,
70- T : Clone ,
103+ I : TrustedLen < Item = T > + TrustedRandomAccess ,
71104{
72- default fn spec_extend ( & mut self , iterator : I ) {
73- self . spec_extend ( iterator. cloned ( ) )
74- }
75- }
105+ default fn spec_extend ( & mut self , mut iterator : I ) {
106+ let size = iterator. size ( ) ;
107+ self . reserve ( size) ;
76108
77- impl < ' a , T : ' a , A : Allocator + ' a > SpecExtend < & ' a T , slice:: Iter < ' a , T > > for Vec < T , A >
78- where
79- T : Copy ,
80- {
81- fn spec_extend ( & mut self , iterator : slice:: Iter < ' a , T > ) {
82- let slice = iterator. as_slice ( ) ;
83- unsafe { self . append_elements ( slice) } ;
109+ // SAFETY: reserve ensured that there is sufficient capacity for the additional items.
110+ // The loop upholds the TRA requirements by accessing each element only once.
111+ unsafe {
112+ let sink = self . as_mut_ptr ( ) . add ( self . len ( ) ) ;
113+ for i in 0 ..size {
114+ ptr:: write ( sink. add ( i) , iterator. __iterator_get_unchecked ( i) ) ;
115+ self . set_len ( self . len ( ) + 1 ) ;
116+ }
117+ }
84118 }
85119}
0 commit comments