1
1
use crate :: alloc:: Allocator ;
2
- use core:: iter:: TrustedLen ;
2
+ use core:: iter:: { TrustedLen , TrustedRandomAccess } ;
3
3
use core:: ptr:: { self } ;
4
4
use core:: slice:: { self } ;
5
5
@@ -11,6 +11,49 @@ pub(super) trait SpecExtend<T, I> {
11
11
}
12
12
13
13
impl < 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 >
14
57
where
15
58
I : Iterator < Item = T > ,
16
59
{
19
62
}
20
63
}
21
64
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 >
23
66
where
24
67
I : TrustedLen < Item = T > ,
25
68
{
@@ -57,31 +100,22 @@ where
57
100
}
58
101
}
59
102
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 >
70
104
where
71
- I : Iterator < Item = & ' a T > ,
72
- T : Clone ,
105
+ I : TrustedLen < Item = T > + TrustedRandomAccess ,
73
106
{
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) ;
78
110
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
+ }
86
120
}
87
121
}
0 commit comments