Skip to content

Commit

Permalink
feat: more const functions
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes committed Oct 27, 2023
1 parent 19bf511 commit f8150df
Show file tree
Hide file tree
Showing 4 changed files with 284 additions and 51 deletions.
12 changes: 8 additions & 4 deletions src/arch/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ pub(crate) unsafe fn encode<const UPPER: bool>(input: &[u8], output: *mut u8) {

/// Default check function.
#[inline]
pub(crate) fn check(input: &[u8]) -> bool {
input
.iter()
.all(|byte| HEX_DECODE_LUT[*byte as usize] != NIL)
pub(crate) const fn check(mut input: &[u8]) -> bool {
while let [byte, rest @ ..] = input {
if HEX_DECODE_LUT[*byte as usize] == NIL {
return false;
}
input = rest;
}
true
}

/// Default unchecked decoding function.
Expand Down
37 changes: 37 additions & 0 deletions src/impl_core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//! Modified implementations of unstable libcore functions.

#![allow(dead_code)]

use core::mem::{self, MaybeUninit};

/// [`MaybeUninit::slice_assume_init_mut`]
#[inline(always)]
pub(crate) unsafe fn slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T] {
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
// mutable reference which is also guaranteed to be valid for writes.
unsafe { &mut *(slice as *mut [MaybeUninit<T>] as *mut [T]) }
}

/// [`MaybeUninit::uninit_array`]
#[inline]
pub(crate) const fn uninit_array<T, const N: usize>() -> [MaybeUninit<T>; N] {
// SAFETY: An uninitialized `[MaybeUninit<_>; N]` is valid.
unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() }
}

/// [`MaybeUninit::array_assume_init`]
#[inline]
pub(crate) unsafe fn array_assume_init<T, const N: usize>(array: [MaybeUninit<T>; N]) -> [T; N] {
// SAFETY:
// * The caller guarantees that all elements of the array are initialized
// * `MaybeUninit<T>` and T are guaranteed to have the same layout
// * `MaybeUninit` does not drop, so there are no double-frees
// And thus the conversion is safe
unsafe { transpose(array).assume_init() }
}

/// [`MaybeUninit::transpose`]
#[inline(always)]
unsafe fn transpose<T, const N: usize>(array: [MaybeUninit<T>; N]) -> MaybeUninit<[T; N]> {
mem::transmute_copy::<[MaybeUninit<T>; N], MaybeUninit<[T; N]>>(&mem::ManuallyDrop::new(&array))
}
Loading

0 comments on commit f8150df

Please sign in to comment.