@@ -5,38 +5,40 @@ use std::mem;
55use std:: ops:: { Deref , DerefMut } ;
66use std:: slice;
77
8+ // `T` is always `u8` in practice. Attempts to remove `T` caused mild
9+ // performance regressions, surprisingly enough.
810#[ repr( C ) ]
9- pub struct Buffer {
10- data : * mut u8 ,
11+ pub struct Buffer < T : Copy > {
12+ data : * mut T ,
1113 len : usize ,
1214 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 > ) ,
1517}
1618
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 > { }
1921
20- impl Default for Buffer {
22+ impl < T : Copy > Default for Buffer < T > {
2123 fn default ( ) -> Self {
2224 Self :: from ( vec ! [ ] )
2325 }
2426}
2527
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 ) }
3032 }
3133}
3234
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 ] {
3537 unsafe { slice:: from_raw_parts_mut ( self . data , self . len ) }
3638 }
3739}
3840
39- impl Buffer {
41+ impl < T : Copy > Buffer < T > {
4042 pub ( super ) fn new ( ) -> Self {
4143 Self :: default ( )
4244 }
@@ -53,7 +55,7 @@ impl Buffer {
5355 // because in the case of small arrays, codegen can be more efficient
5456 // (avoiding a memmove call). With extend_from_slice, LLVM at least
5557 // 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 ] ) {
5759 if xs. len ( ) > ( self . capacity - self . len ) {
5860 let b = self . take ( ) ;
5961 * self = ( b. reserve ) ( b, xs. len ( ) ) ;
@@ -64,7 +66,7 @@ impl Buffer {
6466 }
6567 }
6668
67- pub ( super ) fn extend_from_slice ( & mut self , xs : & [ u8 ] ) {
69+ pub ( super ) fn extend_from_slice ( & mut self , xs : & [ T ] ) {
6870 if xs. len ( ) > ( self . capacity - self . len ) {
6971 let b = self . take ( ) ;
7072 * self = ( b. reserve ) ( b, xs. len ( ) ) ;
@@ -75,7 +77,7 @@ impl Buffer {
7577 }
7678 }
7779
78- pub ( super ) fn push ( & mut self , v : u8 ) {
80+ pub ( super ) fn push ( & mut self , v : T ) {
7981 // The code here is taken from Vec::push, and we know that reserve()
8082 // will panic if we're exceeding isize::MAX bytes and so there's no need
8183 // to check for overflow.
@@ -90,7 +92,7 @@ impl Buffer {
9092 }
9193}
9294
93- impl Write for Buffer {
95+ impl Write for Buffer < u8 > {
9496 fn write ( & mut self , xs : & [ u8 ] ) -> io:: Result < usize > {
9597 self . extend_from_slice ( xs) ;
9698 Ok ( xs. len ( ) )
@@ -106,35 +108,35 @@ impl Write for Buffer {
106108 }
107109}
108110
109- impl Drop for Buffer {
111+ impl < T : Copy > Drop for Buffer < T > {
110112 fn drop ( & mut self ) {
111113 let b = self . take ( ) ;
112114 ( b. drop ) ( b) ;
113115 }
114116}
115117
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 {
118120 let ( data, len, capacity) = ( v. as_mut_ptr ( ) , v. len ( ) , v. capacity ( ) ) ;
119121 mem:: forget ( v) ;
120122
121123 // This utility function is nested in here because it can *only*
122124 // 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 > {
124126 unsafe {
125127 let Buffer { data, len, capacity, .. } = b;
126128 mem:: forget ( b) ;
127129 Vec :: from_raw_parts ( data, len, capacity)
128130 }
129131 }
130132
131- extern "C" fn reserve ( b : Buffer , additional : usize ) -> Buffer {
133+ extern "C" fn reserve < T : Copy > ( b : Buffer < T > , additional : usize ) -> Buffer < T > {
132134 let mut v = to_vec ( b) ;
133135 v. reserve ( additional) ;
134136 Buffer :: from ( v)
135137 }
136138
137- extern "C" fn drop ( b : Buffer ) {
139+ extern "C" fn drop < T : Copy > ( b : Buffer < T > ) {
138140 mem:: drop ( to_vec ( b) ) ;
139141 }
140142
0 commit comments