@@ -52,29 +52,41 @@ pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8]) {
52
52
}
53
53
}
54
54
55
- macro_rules! fill_via_chunks {
56
- ( $src: expr, $dst: expr, $ty: ty) => { {
57
- const SIZE : usize = core:: mem:: size_of:: <$ty>( ) ;
58
- let chunk_size_u8 = min( $src. len( ) * SIZE , $dst. len( ) ) ;
59
- let chunk_size = ( chunk_size_u8 + SIZE - 1 ) / SIZE ;
60
-
61
- // Byte-swap for portability of results:
62
- if cfg!( target_endian = "big" ) {
63
- for x in & mut $src[ ..chunk_size] {
64
- * x = x. to_le( ) ;
65
- }
66
- }
55
+ trait ToLe : Copy {
56
+ fn to_le ( self ) -> Self ;
57
+ }
58
+ impl ToLe for u32 {
59
+ fn to_le ( self ) -> Self {
60
+ self . to_le ( )
61
+ }
62
+ }
63
+ impl ToLe for u64 {
64
+ fn to_le ( self ) -> Self {
65
+ self . to_le ( )
66
+ }
67
+ }
68
+
69
+ fn fill_via_chunks < T : ToLe > ( src : & mut [ T ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
70
+ let size = core:: mem:: size_of :: < T > ( ) ;
71
+ let chunk_size_u8 = min ( src. len ( ) * size, dest. len ( ) ) ;
72
+ let chunk_size = ( chunk_size_u8 + size - 1 ) / size;
67
73
68
- // We do a simple copy, which is 25-50% faster:
69
- unsafe {
70
- core:: ptr:: copy_nonoverlapping(
71
- $src. as_ptr( ) as * const u8 ,
72
- $dst. as_mut_ptr( ) ,
73
- chunk_size_u8) ;
74
+ // Byte-swap for portability of results:
75
+ if cfg ! ( target_endian = "big" ) {
76
+ for x in & mut src[ ..chunk_size] {
77
+ * x = x. to_le ( ) ;
74
78
}
79
+ }
80
+
81
+ unsafe {
82
+ core:: ptr:: copy_nonoverlapping (
83
+ src. as_ptr ( ) as * const u8 ,
84
+ dest. as_mut_ptr ( ) ,
85
+ chunk_size_u8,
86
+ ) ;
87
+ }
75
88
76
- ( chunk_size, chunk_size_u8)
77
- } } ;
89
+ ( chunk_size, chunk_size_u8)
78
90
}
79
91
80
92
/// Implement `fill_bytes` by reading chunks from the output buffer of a block
@@ -111,7 +123,7 @@ macro_rules! fill_via_chunks {
111
123
/// }
112
124
/// ```
113
125
pub fn fill_via_u32_chunks ( src : & mut [ u32 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
114
- fill_via_chunks ! ( src, dest, u32 )
126
+ fill_via_chunks ( src, dest)
115
127
}
116
128
117
129
/// Implement `fill_bytes` by reading chunks from the output buffer of a block
@@ -129,7 +141,7 @@ pub fn fill_via_u32_chunks(src: &mut [u32], dest: &mut [u8]) -> (usize, usize) {
129
141
///
130
142
/// See `fill_via_u32_chunks` for an example.
131
143
pub fn fill_via_u64_chunks ( src : & mut [ u64 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
132
- fill_via_chunks ! ( src, dest, u64 )
144
+ fill_via_chunks ( src, dest)
133
145
}
134
146
135
147
/// Implement `next_u32` via `fill_bytes`, little-endian order.
0 commit comments