@@ -5,38 +5,40 @@ use std::mem;
5
5
use std:: ops:: { Deref , DerefMut } ;
6
6
use std:: slice;
7
7
8
+ // `T` is always `u8` in practice. Attempts to remove `T` caused mild
9
+ // performance regressions, surprisingly enough.
8
10
#[ repr( C ) ]
9
- pub struct Buffer {
10
- data : * mut u8 ,
11
+ pub struct Buffer < T : Copy > {
12
+ data : * mut T ,
11
13
len : usize ,
12
14
capacity : usize ,
13
- reserve : extern "C" fn ( Buffer , usize ) -> Buffer ,
14
- drop : extern "C" fn ( Buffer ) ,
15
+ reserve : extern "C" fn ( Buffer < T > , usize ) -> Buffer < T > ,
16
+ drop : extern "C" fn ( Buffer < T > ) ,
15
17
}
16
18
17
- unsafe impl Sync for Buffer { }
18
- unsafe impl Send for Buffer { }
19
+ unsafe impl < T : Copy + Sync > Sync for Buffer < T > { }
20
+ unsafe impl < T : Copy + Send > Send for Buffer < T > { }
19
21
20
- impl Default for Buffer {
22
+ impl < T : Copy > Default for Buffer < T > {
21
23
fn default ( ) -> Self {
22
24
Self :: from ( vec ! [ ] )
23
25
}
24
26
}
25
27
26
- impl Deref for Buffer {
27
- type Target = [ u8 ] ;
28
- fn deref ( & self ) -> & [ u8 ] {
29
- unsafe { slice:: from_raw_parts ( self . data as * const u8 , self . len ) }
28
+ impl < T : Copy > Deref for Buffer < T > {
29
+ type Target = [ T ] ;
30
+ fn deref ( & self ) -> & [ T ] {
31
+ unsafe { slice:: from_raw_parts ( self . data as * const T , self . len ) }
30
32
}
31
33
}
32
34
33
- impl DerefMut for Buffer {
34
- fn deref_mut ( & mut self ) -> & mut [ u8 ] {
35
+ impl < T : Copy > DerefMut for Buffer < T > {
36
+ fn deref_mut ( & mut self ) -> & mut [ T ] {
35
37
unsafe { slice:: from_raw_parts_mut ( self . data , self . len ) }
36
38
}
37
39
}
38
40
39
- impl Buffer {
41
+ impl < T : Copy > Buffer < T > {
40
42
pub ( super ) fn new ( ) -> Self {
41
43
Self :: default ( )
42
44
}
@@ -53,7 +55,7 @@ impl Buffer {
53
55
// because in the case of small arrays, codegen can be more efficient
54
56
// (avoiding a memmove call). With extend_from_slice, LLVM at least
55
57
// currently is not able to make that optimization.
56
- pub ( super ) fn extend_from_array < const N : usize > ( & mut self , xs : & [ u8 ; N ] ) {
58
+ pub ( super ) fn extend_from_array < const N : usize > ( & mut self , xs : & [ T ; N ] ) {
57
59
if xs. len ( ) > ( self . capacity - self . len ) {
58
60
let b = self . take ( ) ;
59
61
* self = ( b. reserve ) ( b, xs. len ( ) ) ;
@@ -64,7 +66,7 @@ impl Buffer {
64
66
}
65
67
}
66
68
67
- pub ( super ) fn extend_from_slice ( & mut self , xs : & [ u8 ] ) {
69
+ pub ( super ) fn extend_from_slice ( & mut self , xs : & [ T ] ) {
68
70
if xs. len ( ) > ( self . capacity - self . len ) {
69
71
let b = self . take ( ) ;
70
72
* self = ( b. reserve ) ( b, xs. len ( ) ) ;
@@ -75,7 +77,7 @@ impl Buffer {
75
77
}
76
78
}
77
79
78
- pub ( super ) fn push ( & mut self , v : u8 ) {
80
+ pub ( super ) fn push ( & mut self , v : T ) {
79
81
// The code here is taken from Vec::push, and we know that reserve()
80
82
// will panic if we're exceeding isize::MAX bytes and so there's no need
81
83
// to check for overflow.
@@ -90,7 +92,7 @@ impl Buffer {
90
92
}
91
93
}
92
94
93
- impl Write for Buffer {
95
+ impl Write for Buffer < u8 > {
94
96
fn write ( & mut self , xs : & [ u8 ] ) -> io:: Result < usize > {
95
97
self . extend_from_slice ( xs) ;
96
98
Ok ( xs. len ( ) )
@@ -106,35 +108,35 @@ impl Write for Buffer {
106
108
}
107
109
}
108
110
109
- impl Drop for Buffer {
111
+ impl < T : Copy > Drop for Buffer < T > {
110
112
fn drop ( & mut self ) {
111
113
let b = self . take ( ) ;
112
114
( b. drop ) ( b) ;
113
115
}
114
116
}
115
117
116
- impl From < Vec < u8 > > for Buffer {
117
- fn from ( mut v : Vec < u8 > ) -> Self {
118
+ impl < T : Copy > From < Vec < T > > for Buffer < T > {
119
+ fn from ( mut v : Vec < T > ) -> Self {
118
120
let ( data, len, capacity) = ( v. as_mut_ptr ( ) , v. len ( ) , v. capacity ( ) ) ;
119
121
mem:: forget ( v) ;
120
122
121
123
// This utility function is nested in here because it can *only*
122
124
// be safely called on `Buffer`s created by *this* `proc_macro`.
123
- fn to_vec ( b : Buffer ) -> Vec < u8 > {
125
+ fn to_vec < T : Copy > ( b : Buffer < T > ) -> Vec < T > {
124
126
unsafe {
125
127
let Buffer { data, len, capacity, .. } = b;
126
128
mem:: forget ( b) ;
127
129
Vec :: from_raw_parts ( data, len, capacity)
128
130
}
129
131
}
130
132
131
- extern "C" fn reserve ( b : Buffer , additional : usize ) -> Buffer {
133
+ extern "C" fn reserve < T : Copy > ( b : Buffer < T > , additional : usize ) -> Buffer < T > {
132
134
let mut v = to_vec ( b) ;
133
135
v. reserve ( additional) ;
134
136
Buffer :: from ( v)
135
137
}
136
138
137
- extern "C" fn drop ( b : Buffer ) {
139
+ extern "C" fn drop < T : Copy > ( b : Buffer < T > ) {
138
140
mem:: drop ( to_vec ( b) ) ;
139
141
}
140
142
0 commit comments