| // Copyright 2015-2016 Brian Smith. |
| // |
| // Permission to use, copy, modify, and/or distribute this software for any |
| // purpose with or without fee is hereby granted, provided that the above |
| // copyright notice and this permission notice appear in all copies. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES |
| // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY |
| // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
| // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
| // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| |
| //! Polyfills for functionality that will (hopefully) be added to Rust's |
| //! standard library soon. |
| |
| use core; |
| |
| // A better name for the `&*` idiom for removing the mutability from a |
| // reference. |
| #[cfg(feature = "use_heap")] |
| #[inline(always)] |
| pub fn ref_from_mut_ref<'a, T: ?Sized>(x: &'a mut T) -> &'a T { x } |
| |
| #[inline(always)] |
| pub fn u64_from_usize(x: usize) -> u64 { x as u64 } |
| |
| /// `core::num::Wrapping` doesn't support `rotate_left`. |
| /// There is no usable trait for `rotate_left`, so this polyfill just |
| /// hard-codes u32. https://github.com/rust-lang/rust/issues/32463 |
| #[inline(always)] |
| pub fn wrapping_rotate_left_u32(x: core::num::Wrapping<u32>, n: u32) |
| -> core::num::Wrapping<u32> { |
| core::num::Wrapping(x.0.rotate_left(n)) |
| } |
| |
| |
| pub mod slice { |
| use core; |
| |
| #[inline(always)] |
| pub fn u32_from_be_u8(buffer: &[u8; 4]) -> u32 { |
| u32::from(buffer[0]) << 24 | |
| u32::from(buffer[1]) << 16 | |
| u32::from(buffer[2]) << 8 | |
| u32::from(buffer[3]) |
| } |
| |
| #[inline(always)] |
| pub fn u32_from_le_u8(buffer: &[u8; 4]) -> u32 { |
| u32::from(buffer[0]) | |
| u32::from(buffer[1]) << 8 | |
| u32::from(buffer[2]) << 16 | |
| u32::from(buffer[3]) << 24 |
| } |
| |
| #[inline(always)] |
| pub fn be_u8_from_u32(value: u32) -> [u8; 4] { |
| [((value >> 24) & 0xff) as u8, |
| ((value >> 16) & 0xff) as u8, |
| ((value >> 8) & 0xff) as u8, |
| (value & 0xff) as u8] |
| } |
| |
| // https://github.com/rust-lang/rust/issues/27750 |
| // https://internals.rust-lang.org/t/stabilizing-basic-functions-on-arrays-and-slices/2868 |
| #[inline(always)] |
| pub fn fill(dest: &mut [u8], value: u8) { |
| for d in dest { |
| *d = value; |
| } |
| } |
| |
| // https://internals.rust-lang.org/t/safe-trasnsmute-for-slices-e-g-u64-u32-particularly-simd-types/2871 |
| #[inline(always)] |
| pub fn u64_as_u8(src: &[u64]) -> &[u8] { |
| unsafe { |
| core::slice::from_raw_parts(src.as_ptr() as *const u8, |
| src.len() * 8) |
| } |
| } |
| |
| // https://internals.rust-lang.org/t/safe-trasnsmute-for-slices-e-g-u64-u32-particularly-simd-types/2871 |
| #[inline(always)] |
| pub fn u64_as_u8_mut(src: &mut [u64]) -> &mut [u8] { |
| unsafe { |
| core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u8, |
| src.len() * 8) |
| } |
| } |
| |
| // https://internals.rust-lang.org/t/safe-trasnsmute-for-slices-e-g-u64-u32-particularly-simd-types/2871 |
| #[inline(always)] |
| #[allow(dead_code)] // Only used on 32-bit builds currently |
| pub fn u32_as_u8<'a>(src: &'a [u32]) -> &'a [u8] { |
| unsafe { |
| core::slice::from_raw_parts(src.as_ptr() as *mut u8, src.len() * 4) |
| } |
| } |
| |
| // https://internals.rust-lang.org/t/safe-trasnsmute-for-slices-e-g-u64-u32-particularly-simd-types/2871 |
| #[inline(always)] |
| #[allow(dead_code)] // Only used on 32-bit builds currently |
| pub fn u32_as_u8_mut<'a>(src: &'a mut [u32]) -> &'a mut [u8] { |
| unsafe { |
| core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u8, |
| src.len() * 4) |
| } |
| } |
| |
| // https://internals.rust-lang.org/t/safe-trasnsmute-for-slices-e-g-u64-u32-particularly-simd-types/2871 |
| #[inline(always)] |
| pub fn u64_as_u32(src: &[u64]) -> &[u32] { |
| unsafe { |
| core::slice::from_raw_parts(src.as_ptr() as *const u32, |
| src.len() * 2) |
| } |
| } |
| |
| // https://internals.rust-lang.org/t/safe-trasnsmute-for-slices-e-g-u64-u32-particularly-simd-types/2871 |
| #[inline(always)] |
| pub fn u64_as_u32_mut(src: &mut [u64]) -> &mut [u32] { |
| unsafe { |
| core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u32, |
| src.len() * 2) |
| } |
| } |
| |
| #[inline(always)] |
| pub fn as_wrapping_mut<T>(src: &mut [T]) -> &mut [core::num::Wrapping<T>] { |
| unsafe { |
| core::slice::from_raw_parts_mut( |
| src.as_mut_ptr() as *mut core::num::Wrapping<T>, src.len()) |
| } |
| } |
| } |
| |
| /// Returns a reference to the elements of `$slice` as an array, verifying that |
| /// the slice is of length `$len`. |
| macro_rules! slice_as_array_ref { |
| ($slice:expr, $len:expr) => { |
| { |
| use error; |
| |
| fn slice_as_array_ref<T>(slice: &[T]) |
| -> Result<&[T; $len], error::Unspecified> { |
| if slice.len() != $len { |
| return Err(error::Unspecified); |
| } |
| Ok(unsafe { |
| &*(slice.as_ptr() as *const [T; $len]) |
| }) |
| } |
| slice_as_array_ref($slice) |
| } |
| } |
| } |
| |
| /// Returns a reference to elements of `$slice` as a mutable array, verifying |
| /// that the slice is of length `$len`. |
| macro_rules! slice_as_array_ref_mut { |
| ($slice:expr, $len:expr) => { |
| { |
| use error; |
| |
| fn slice_as_array_ref<T>(slice: &mut [T]) |
| -> Result<&mut [T; $len], |
| error::Unspecified> { |
| if slice.len() != $len { |
| return Err(error::Unspecified); |
| } |
| Ok(unsafe { |
| &mut *(slice.as_mut_ptr() as *mut [T; $len]) |
| }) |
| } |
| slice_as_array_ref($slice) |
| } |
| } |
| } |