1
+
1
2
use { alloc:: vec:: Vec , core:: ptr} ;
2
3
3
4
/// A typesafe helper that separates new value construction from
@@ -22,6 +23,26 @@ impl<'a, T> VecAllocation<'a, T> {
22
23
}
23
24
}
24
25
26
+ pub struct VecArrayAllocation < ' a , T : ' a , const N : usize > {
27
+ vec : & ' a mut Vec < T > ,
28
+ index : usize ,
29
+ }
30
+
31
+ impl < ' a , T , const N : usize > VecArrayAllocation < ' a , T , N > {
32
+ /// Consumes self and writes the given value into the allocation.
33
+ // writing is safe because alloc() ensured enough capacity
34
+ // and `Allocation` holds a mutable borrow to prevent anyone else
35
+ // from breaking this invariant.
36
+ #[ inline( always) ]
37
+ pub fn init ( self , value : [ T ; N ] ) -> usize {
38
+ unsafe {
39
+ ptr:: write ( self . vec . as_mut_ptr ( ) . add ( self . index ) as * mut [ T ; N ] , value) ;
40
+ self . vec . set_len ( self . index + N ) ;
41
+ }
42
+ self . index
43
+ }
44
+ }
45
+
25
46
/// An entry into a vector, similar to `std::collections::hash_map::Entry`.
26
47
pub enum VecEntry < ' a , T : ' a > {
27
48
/// Entry has just been freshly allocated.
@@ -52,6 +73,8 @@ pub trait VecHelper<T> {
52
73
/// Either returns an existing element, or grows the vector by one.
53
74
/// Doesn't expect indices to be higher than the current length.
54
75
fn entry ( & mut self , index : usize ) -> VecEntry < T > ;
76
+
77
+ fn alloc_multiple < const N : usize > ( & mut self ) -> VecArrayAllocation < T , N > ;
55
78
}
56
79
57
80
impl < T > VecHelper < T > for Vec < T > {
@@ -63,6 +86,12 @@ impl<T> VecHelper<T> for Vec<T> {
63
86
VecAllocation { vec : self , index }
64
87
}
65
88
89
+ fn alloc_multiple < const N : usize > ( & mut self ) -> VecArrayAllocation < T , N > {
90
+ self . reserve ( N ) ;
91
+ let index = self . len ( ) ;
92
+ VecArrayAllocation { vec : self , index }
93
+ }
94
+
66
95
fn entry ( & mut self , index : usize ) -> VecEntry < T > {
67
96
if index < self . len ( ) {
68
97
VecEntry :: Occupied ( unsafe { self . get_unchecked_mut ( index) } )
@@ -94,3 +123,15 @@ fn test_zero_copy() {
94
123
//TODO: make the expected value to be concrete
95
124
assert_ne ! ( unsafe { vec[ 0 ] . big[ 1 ] } , 1.0 ) ;
96
125
}
126
+
127
+ #[ test]
128
+ fn test_add_multiple ( ) {
129
+ use alloc:: vec;
130
+ let mut vec = vec ! [ 1 , 2 , 3 ] ;
131
+
132
+ // check that the new helper is not overwriting
133
+ vec. remove ( 0 ) ;
134
+ vec. alloc_multiple ( ) . init ( [ 4 , 5 ] ) ;
135
+ assert_eq ! ( vec, [ 2 , 3 , 4 , 5 ] )
136
+
137
+ }
0 commit comments