@@ -25,12 +25,7 @@ impl<'a, T, const N: usize> Cursor<'a, T, N> {
25
25
}
26
26
27
27
fn write_impl ( & mut self , value : [ T ; N ] ) {
28
- * self . slice = unsafe {
29
- let ptr = & value as * const [ T ; N ] as * const [ MaybeUninit < T > ; N ] ;
30
- let read_value = core:: ptr:: read ( ptr) ;
31
- core:: mem:: drop ( value) ;
32
- read_value
33
- } ;
28
+ * self . slice = value. map ( |v| MaybeUninit :: new ( v) ) ;
34
29
}
35
30
36
31
/// Finishes the buffer by writing the remaining values.
@@ -53,8 +48,8 @@ impl<'a, T, const N: usize> Cursor<'a, T, N> {
53
48
r
54
49
}
55
50
56
- unsafe fn into_buf ( self ) -> & ' a mut [ MaybeUninit < T > ; N ] {
57
- core:: mem:: transmute ( self )
51
+ fn into_buf ( self ) -> & ' a mut [ MaybeUninit < T > ; N ] {
52
+ unsafe { core:: mem:: transmute ( self ) }
58
53
}
59
54
60
55
/// Splits the cursor in two.
@@ -63,7 +58,7 @@ impl<'a, T, const N: usize> Cursor<'a, T, N> {
63
58
/// `cargo check`, since the error is not discovered by `rustc` until it tries to instantiate
64
59
/// the code.
65
60
pub fn split < const L : usize , const R : usize > ( self ) -> ( Cursor < ' a , T , L > , Cursor < ' a , T , R > ) {
66
- let buf = unsafe { self . into_buf ( ) } ;
61
+ let buf = self . into_buf ( ) ;
67
62
let ( l, r) = crate :: util:: split_mut :: < _ , N , L , R > ( buf) ;
68
63
( Cursor { slice : l } , Cursor { slice : r } )
69
64
}
@@ -94,3 +89,62 @@ impl<T, const N: usize> Drop for Cursor<'_, T, N> {
94
89
}
95
90
}
96
91
}
92
+
93
+ #[ cfg( test) ]
94
+ mod tests {
95
+ use core:: sync:: atomic:: AtomicU8 ;
96
+
97
+ use super :: * ;
98
+
99
+ #[ test]
100
+ fn test_drop ( ) {
101
+ struct DropCounter < ' a > ( & ' a AtomicU8 ) ;
102
+ impl core:: ops:: Drop for DropCounter < ' _ > {
103
+ fn drop ( & mut self ) {
104
+ self . 0 . fetch_add ( 1 , core:: sync:: atomic:: Ordering :: SeqCst ) ;
105
+ }
106
+ }
107
+
108
+ let value = AtomicU8 :: new ( 0 ) ;
109
+ {
110
+ let mut data: [ MaybeUninit < DropCounter < ' _ > > ; 1 ] = [ MaybeUninit :: uninit ( ) ] ;
111
+ Cursor :: new ( & mut data) . finish ( [ DropCounter ( & value) ] ) ;
112
+ }
113
+ assert_eq ! ( value. load( core:: sync:: atomic:: Ordering :: SeqCst ) , 0 ) ;
114
+
115
+ let value = AtomicU8 :: new ( 0 ) ;
116
+ {
117
+ let mut data: [ MaybeUninit < DropCounter < ' _ > > ; 2 ] =
118
+ [ MaybeUninit :: uninit ( ) , MaybeUninit :: uninit ( ) ] ;
119
+ Cursor :: new ( & mut data) . finish ( [ DropCounter ( & value) , DropCounter ( & value) ] ) ;
120
+ }
121
+ assert_eq ! ( value. load( core:: sync:: atomic:: Ordering :: SeqCst ) , 0 ) ;
122
+
123
+ let value = AtomicU8 :: new ( 0 ) ;
124
+ {
125
+ let mut data: [ MaybeUninit < DropCounter < ' _ > > ; 1 ] = [ MaybeUninit :: uninit ( ) ] ;
126
+ Cursor :: new ( & mut data) . finish ( [ DropCounter ( & value) ] ) ;
127
+ let [ value] = data;
128
+ unsafe { value. assume_init ( ) } ;
129
+ }
130
+ assert_eq ! ( value. load( core:: sync:: atomic:: Ordering :: SeqCst ) , 1 ) ;
131
+
132
+ let value = AtomicU8 :: new ( 0 ) ;
133
+ {
134
+ let mut data: [ MaybeUninit < DropCounter < ' _ > > ; 2 ] =
135
+ [ MaybeUninit :: uninit ( ) , MaybeUninit :: uninit ( ) ] ;
136
+ Cursor :: new ( & mut data) . finish ( [ DropCounter ( & value) , DropCounter ( & value) ] ) ;
137
+ let [ value0, value1] = data;
138
+ unsafe { value0. assume_init ( ) } ;
139
+ unsafe { value1. assume_init ( ) } ;
140
+ }
141
+ assert_eq ! ( value. load( core:: sync:: atomic:: Ordering :: SeqCst ) , 2 ) ;
142
+ }
143
+
144
+ #[ test]
145
+ fn test_initalized ( ) {
146
+ let mut data: [ MaybeUninit < u8 > ; 4 ] = [ MaybeUninit :: new ( 0 ) ; 4 ] ;
147
+ Cursor :: new ( & mut data) . write ( [ 1 , 2 ] ) . finish ( [ 3 , 4 ] ) ;
148
+ assert_eq ! ( data. map( |d| unsafe { d. assume_init( ) } ) , [ 1 , 2 , 3 , 4 ] ) ;
149
+ }
150
+ }
0 commit comments