Skip to content

Commit

Permalink
Simplify unaligned Ref constructors (#329)
Browse files Browse the repository at this point in the history
These constructors don't currently make use of the `T: Unaligned` bound
internally - they just use it to document that an alignment check is
guaranteed to be elided. The alignment check in the non-`Unaligned`
constructors is trivially optimizable when it's unneeded since it's just
a check that `x % 1 == 0`. For that reason, in this commit, we remove
these methods' internals and simply have them be wrappers around the
equivalent non-`Unaligned` constructors.

While we're here, mark `Ref` functions which are just thin wrappers
around other functions as `#[inline(always)]`.
  • Loading branch information
joshlf authored Sep 6, 2023
1 parent fed18ba commit 80455a9
Showing 1 changed file with 24 additions and 57 deletions.
81 changes: 24 additions & 57 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,7 @@ where
/// If the checks succeed, then `bytes` will be initialized to zero. This
/// can be useful when re-using buffers to ensure that sensitive data
/// previously stored in the buffer is not leaked.
#[inline]
#[inline(always)]
pub fn new_zeroed(bytes: B) -> Option<Ref<B, T>> {
map_zeroed(Self::new(bytes))
}
Expand All @@ -1495,7 +1495,7 @@ where
/// If the checks succeed, then the prefix which is consumed will be
/// initialized to zero. This can be useful when re-using buffers to ensure
/// that sensitive data previously stored in the buffer is not leaked.
#[inline]
#[inline(always)]
pub fn new_from_prefix_zeroed(bytes: B) -> Option<(Ref<B, T>, B)> {
map_prefix_tuple_zeroed(Self::new_from_prefix(bytes))
}
Expand All @@ -1513,7 +1513,7 @@ where
/// If the checks succeed, then the suffix which is consumed will be
/// initialized to zero. This can be useful when re-using buffers to ensure
/// that sensitive data previously stored in the buffer is not leaked.
#[inline]
#[inline(always)]
pub fn new_from_suffix_zeroed(bytes: B) -> Option<(B, Ref<B, T>)> {
map_suffix_tuple_zeroed(Self::new_from_suffix(bytes))
}
Expand All @@ -1537,7 +1537,7 @@ where
/// # Panics
///
/// `new_slice` panics if `T` is a zero-sized type.
#[inline]
#[inline(always)]
pub fn new_slice_zeroed(bytes: B) -> Option<Ref<B, [T]>> {
map_zeroed(Self::new_slice(bytes))
}
Expand All @@ -1559,7 +1559,7 @@ where
/// # Panics
///
/// `new_slice_from_prefix_zeroed` panics if `T` is a zero-sized type.
#[inline]
#[inline(always)]
pub fn new_slice_from_prefix_zeroed(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
map_prefix_tuple_zeroed(Self::new_slice_from_prefix(bytes, count))
}
Expand All @@ -1581,7 +1581,7 @@ where
/// # Panics
///
/// `new_slice_from_suffix_zeroed` panics if `T` is a zero-sized type.
#[inline]
#[inline(always)]
pub fn new_slice_from_suffix_zeroed(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
map_suffix_tuple_zeroed(Self::new_slice_from_suffix(bytes, count))
}
Expand All @@ -1596,12 +1596,9 @@ where
///
/// `new_unaligned` verifies that `bytes.len() == size_of::<T>()` and
/// constructs a new `Ref`. If the check fails, it returns `None`.
#[inline]
#[inline(always)]
pub fn new_unaligned(bytes: B) -> Option<Ref<B, T>> {
if bytes.len() != mem::size_of::<T>() {
return None;
}
Some(Ref(bytes, PhantomData))
Ref::new(bytes)
}

/// Constructs a new `Ref` from the prefix of a byte slice for a type with
Expand All @@ -1611,13 +1608,9 @@ where
/// size_of::<T>()`. It consumes the first `size_of::<T>()` bytes from
/// `bytes` to construct a `Ref`, and returns the remaining bytes to the
/// caller. If the length check fails, it returns `None`.
#[inline]
#[inline(always)]
pub fn new_unaligned_from_prefix(bytes: B) -> Option<(Ref<B, T>, B)> {
if bytes.len() < mem::size_of::<T>() {
return None;
}
let (bytes, suffix) = bytes.split_at(mem::size_of::<T>());
Some((Ref(bytes, PhantomData), suffix))
Ref::new_from_prefix(bytes)
}

/// Constructs a new `Ref` from the suffix of a byte slice for a type with
Expand All @@ -1627,12 +1620,9 @@ where
/// size_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
/// `bytes` to construct a `Ref`, and returns the preceding bytes to the
/// caller. If the length check fails, it returns `None`.
#[inline]
#[inline(always)]
pub fn new_unaligned_from_suffix(bytes: B) -> Option<(B, Ref<B, T>)> {
let bytes_len = bytes.len();
let split_at = bytes_len.checked_sub(mem::size_of::<T>())?;
let (prefix, bytes) = bytes.split_at(split_at);
Some((prefix, Ref(bytes, PhantomData)))
Ref::new_from_suffix(bytes)
}
}

Expand All @@ -1650,16 +1640,9 @@ where
/// # Panics
///
/// `new_slice` panics if `T` is a zero-sized type.
#[inline]
#[inline(always)]
pub fn new_slice_unaligned(bytes: B) -> Option<Ref<B, [T]>> {
let remainder = bytes
.len()
.checked_rem(mem::size_of::<T>())
.expect("Ref::new_slice_unaligned called on a zero-sized type");
if remainder != 0 {
return None;
}
Some(Ref(bytes, PhantomData))
Ref::new_slice(bytes)
}

/// Constructs a new `Ref` of a slice type with no alignment requirement
Expand All @@ -1675,17 +1658,9 @@ where
/// # Panics
///
/// `new_slice_unaligned_from_prefix` panics if `T` is a zero-sized type.
#[inline]
#[inline(always)]
pub fn new_slice_unaligned_from_prefix(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
let expected_len = match mem::size_of::<T>().checked_mul(count) {
Some(len) => len,
None => return None,
};
if bytes.len() < expected_len {
return None;
}
let (prefix, bytes) = bytes.split_at(expected_len);
Self::new_slice_unaligned(prefix).map(move |l| (l, bytes))
Ref::new_slice_from_prefix(bytes, count)
}

/// Constructs a new `Ref` of a slice type with no alignment requirement
Expand All @@ -1700,17 +1675,9 @@ where
/// # Panics
///
/// `new_slice_unaligned_from_suffix` panics if `T` is a zero-sized type.
#[inline]
#[inline(always)]
pub fn new_slice_unaligned_from_suffix(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
let expected_len = match mem::size_of::<T>().checked_mul(count) {
Some(len) => len,
None => return None,
};
if bytes.len() < expected_len {
return None;
}
let (bytes, suffix) = bytes.split_at(expected_len);
Self::new_slice_unaligned(suffix).map(move |l| (bytes, l))
Ref::new_slice_from_suffix(bytes, count)
}
}

Expand All @@ -1728,7 +1695,7 @@ where
/// If the check succeeds, then `bytes` will be initialized to zero. This
/// can be useful when re-using buffers to ensure that sensitive data
/// previously stored in the buffer is not leaked.
#[inline]
#[inline(always)]
pub fn new_unaligned_zeroed(bytes: B) -> Option<Ref<B, T>> {
map_zeroed(Self::new_unaligned(bytes))
}
Expand All @@ -1744,7 +1711,7 @@ where
/// If the check succeeds, then the prefix which is consumed will be
/// initialized to zero. This can be useful when re-using buffers to ensure
/// that sensitive data previously stored in the buffer is not leaked.
#[inline]
#[inline(always)]
pub fn new_unaligned_from_prefix_zeroed(bytes: B) -> Option<(Ref<B, T>, B)> {
map_prefix_tuple_zeroed(Self::new_unaligned_from_prefix(bytes))
}
Expand All @@ -1760,7 +1727,7 @@ where
/// If the check succeeds, then the suffix which is consumed will be
/// initialized to zero. This can be useful when re-using buffers to ensure
/// that sensitive data previously stored in the buffer is not leaked.
#[inline]
#[inline(always)]
pub fn new_unaligned_from_suffix_zeroed(bytes: B) -> Option<(B, Ref<B, T>)> {
map_suffix_tuple_zeroed(Self::new_unaligned_from_suffix(bytes))
}
Expand All @@ -1785,7 +1752,7 @@ where
/// # Panics
///
/// `new_slice` panics if `T` is a zero-sized type.
#[inline]
#[inline(always)]
pub fn new_slice_unaligned_zeroed(bytes: B) -> Option<Ref<B, [T]>> {
map_zeroed(Self::new_slice_unaligned(bytes))
}
Expand All @@ -1808,7 +1775,7 @@ where
///
/// `new_slice_unaligned_from_prefix_zeroed` panics if `T` is a zero-sized
/// type.
#[inline]
#[inline(always)]
pub fn new_slice_unaligned_from_prefix_zeroed(
bytes: B,
count: usize,
Expand All @@ -1833,7 +1800,7 @@ where
///
/// `new_slice_unaligned_from_suffix_zeroed` panics if `T` is a zero-sized
/// type.
#[inline]
#[inline(always)]
pub fn new_slice_unaligned_from_suffix_zeroed(
bytes: B,
count: usize,
Expand Down

0 comments on commit 80455a9

Please sign in to comment.