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
{
@@ -55,31 +98,22 @@ where
55
98
}
56
99
}
57
100
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 >
68
102
where
69
- I : Iterator < Item = & ' a T > ,
70
- T : Clone ,
103
+ I : TrustedLen < Item = T > + TrustedRandomAccess ,
71
104
{
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) ;
76
108
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
+ }
84
118
}
85
119
}
0 commit comments