23
23
#![ allow( unused) ]
24
24
25
25
use core:: intrinsics:: transmute;
26
+ use core:: ptr:: copy_nonoverlapping;
26
27
use core:: slice;
27
28
use core:: cmp:: min;
28
29
use core:: mem:: size_of;
@@ -82,21 +83,28 @@ macro_rules! impl_uint_from_fill {
82
83
}
83
84
84
85
macro_rules! fill_via_chunks {
85
- ( $src: expr, $dest: expr, $N: expr) => ( {
86
- let chunk_size_u8 = min( $src. len( ) * $N, $dest. len( ) ) ;
87
- let chunk_size = ( chunk_size_u8 + $N - 1 ) / $N;
88
-
89
- // Convert to little-endian:
90
- for ref mut x in $src[ 0 ..chunk_size] . iter_mut( ) {
91
- * * x = ( * x) . to_le( ) ;
86
+ ( $src: expr, $dst: expr, $ty: ty, $size: expr) => ( {
87
+ let chunk_size_u8 = min( $src. len( ) * $size, $dst. len( ) ) ;
88
+ let chunk_size = ( chunk_size_u8 + $size - 1 ) / $size;
89
+ if cfg!( target_endian="little" ) {
90
+ unsafe {
91
+ copy_nonoverlapping(
92
+ $src. as_ptr( ) as * const u8 ,
93
+ $dst. as_mut_ptr( ) ,
94
+ chunk_size_u8) ;
95
+ }
96
+ } else {
97
+ for ( & n, chunk) in $src. iter( ) . zip( $dst. chunks_mut( $size) ) {
98
+ let tmp = n. to_le( ) ;
99
+ let src_ptr = & tmp as * const $ty as * const u8 ;
100
+ unsafe {
101
+ copy_nonoverlapping( src_ptr,
102
+ chunk. as_mut_ptr( ) ,
103
+ chunk. len( ) ) ;
104
+ }
105
+ }
92
106
}
93
107
94
- let bytes = unsafe { slice:: from_raw_parts( $src. as_ptr( ) as * const u8 ,
95
- $src. len( ) * $N) } ;
96
-
97
- let dest_chunk = & mut $dest[ 0 ..chunk_size_u8] ;
98
- dest_chunk. copy_from_slice( & bytes[ 0 ..chunk_size_u8] ) ;
99
-
100
108
( chunk_size, chunk_size_u8)
101
109
} ) ;
102
110
}
@@ -111,10 +119,6 @@ macro_rules! fill_via_chunks {
111
119
/// `consumed_u32` is the number of words consumed from `src`, which is the same
112
120
/// as `filled_u8 / 4` rounded up.
113
121
///
114
- /// Note that on big-endian systems values in the output buffer `src` are
115
- /// mutated. `src[0..consumed_u32]` get converted to little-endian before
116
- /// copying.
117
- ///
118
122
/// # Example
119
123
/// (from `IsaacRng`)
120
124
///
@@ -135,8 +139,8 @@ macro_rules! fill_via_chunks {
135
139
/// }
136
140
/// }
137
141
/// ```
138
- pub fn fill_via_u32_chunks ( src : & mut [ u32 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
139
- fill_via_chunks ! ( src, dest, 4 )
142
+ pub fn fill_via_u32_chunks ( src : & [ u32 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
143
+ fill_via_chunks ! ( src, dest, u32 , 4 )
140
144
}
141
145
142
146
/// Implement `fill_bytes` by reading chunks from the output buffer of a block
@@ -148,13 +152,9 @@ pub fn fill_via_u32_chunks(src: &mut [u32], dest: &mut [u8]) -> (usize, usize) {
148
152
/// `consumed_u64` is the number of words consumed from `src`, which is the same
149
153
/// as `filled_u8 / 8` rounded up.
150
154
///
151
- /// Note that on big-endian systems values in the output buffer `src` are
152
- /// mutated. `src[0..consumed_u64]` get converted to little-endian before
153
- /// copying.
154
- ///
155
155
/// See `fill_via_u32_chunks` for an example.
156
- pub fn fill_via_u64_chunks ( src : & mut [ u64 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
157
- fill_via_chunks ! ( src, dest, 8 )
156
+ pub fn fill_via_u64_chunks ( src : & [ u64 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
157
+ fill_via_chunks ! ( src, dest, u64 , 8 )
158
158
}
159
159
160
160
/// Implement `next_u32` via `fill_bytes`, little-endian order.
0 commit comments