oct 0.37.0

Octonary utilities.
Documentation
// Copyright 2024-2026 Gabriel Bjørnager Jensen.
//
// SPDX: MIT OR Apache-2.0

//! The [`Unaligned`] trait.

use core::cell::{Cell, UnsafeCell};
use core::cmp::{self, Reverse};
use core::marker::PhantomData;
use core::mem::{ManuallyDrop, MaybeUninit};
use core::num::{NonZero, Saturating, Wrapping};

#[cfg(feature = "ascii")]
use core::ascii;

#[cfg(feature = "bstr")]
use core::bstr::ByteStr;

#[cfg(target_has_atomic = "8")]
use core::sync::atomic::{AtomicBool, AtomicI8, AtomicU8};

/// Denotes an unaligned type.
///
/// # Safety
///
/// Only types that always have an alignment
/// requirement of exactly one byte may implement
/// this trait.
pub unsafe trait Unaligned {}

// SAFETY: `[T; N]` has the same alignment as `T`:
// [0]
//
// > An array of `[T; N]` has... and the same
// > alignment of `T`.
//
// [0]: The Rust Standard Library, array
unsafe impl<T: Unaligned, const N: usize> Unaligned for [T; N] {}

// SAFETY: `AtomicBool` has the same layout as
// `bool`: [0]
//
// > This type has the same size, alignment, and
// > bit validity as a `bool`.
//
// [0]: The Rust Standard Library, core::sync::atomic::AtomicBool
#[cfg(target_has_atomic = "8")]
unsafe impl Unaligned for AtomicBool {}

// SAFETY: `AtomicI8` has the same layout as `i8`:
// [0]
//
// > This type has the same size, alignment, and
// > bit validity as the underlying integer type,
// `i8`.
//
// [0]: The Rust Standard Library, core::sync::atomic::AtomicI8
#[cfg(target_has_atomic = "8")]
unsafe impl Unaligned for AtomicI8 {}

// SAFETY: `AtomicU8` has the same layout as `u8`:
// [0]
//
// > This type has the same size, alignment, and
// > bit validity as the underlying integer type,
// `i8`.
//
// [0]: The Rust Standard Library, core::sync::atomic::AtomicU8
#[cfg(target_has_atomic = "8")]
unsafe impl Unaligned for AtomicU8 {}

// SAFETY: `Cell<T>` has the same layout as
// `UnsafeCell<T>`: [0]
//
// > `Cell<T>` has the same memory layout and cave-
// > ats as `UnsafeCell<T>`.
//
// [0]: The Rust Standard Library, core::cell::Cell
unsafe impl<T: Unaligned> Unaligned for Cell<T> {}

// SAFETY: The size of `Char` is guaranteed to be
// `1`: [0]
//
// > This type is guaranteed to have a size and
// > alignment of 1 byte.
//
// [0]: The Rust Standard Library, core::ascii::Char
#[cfg(feature = "ascii")]
unsafe impl Unaligned for ascii::Char {}

// SAFETY: `ByteStr` is a transparent, structural
// wrapper for `[u8]`. It is generally *inferred*
// that this is a stable guarantee (although, for-
// mally, only the constant reference representa-
// tion is guaranteed:) [0]
//
// > A `&ByteStr` has the same representation as a
// > `&str`.
//
// [0]: The Rust Standard Library, core::bstr::ByteStr
#[cfg(feature = "bstr")]
unsafe impl Unaligned for ByteStr {}

// SAFETY: The size of a boolean is `1`. [0] The
// alignment of a type cannot be greater than its
// size: [1]
//
// > The alignment of primitives is platform-spe-
// > cific. In most cases, their alignment is equal
// to their size, but it may be less.
//
// [0]: The Rust Reference, layout.primitive.size
// [1]: The Rust Reference, layout.primitive.platform-specific-alignement
unsafe impl Unaligned for bool {}

// SAFETY: The size of `i8` is `1`. [0] The align-
// ment of a type cannot be greater than its size:
// [1]
//
// > The alignment of primitives is platform-spe-
// > cific. In most cases, their alignment is equal
// to their size, but it may be less.
//
// [0]: The Rust Reference, layout.primitive.size
// [1]: The Rust Reference, layout.primitive.platform-specific-alignement
unsafe impl Unaligned for i8 {}

// SAFETY: `ManuallyDrop<T>` has the same layout as
// `T`: [0]
//
// > `ManuallyDrop<T>` is guaranteed to have the
// > same layout and bit validity as `T`...
//
// [0]: The Rust Standard Library, core::mem::ManuallyDrop
unsafe impl<T: Unaligned> Unaligned for ManuallyDrop<T> {}

// SAFETY: `MaybeUninit<T>` has the same layout as
// `T`: [0]
//
// > `MaybeUninit<T>` is guaranteed to have the
// > same size, alignment, and ABI as `T`...
//
// [0]: The Rust Standard Library, core::mem::MaybeUninit
unsafe impl<T: Unaligned> Unaligned for MaybeUninit<T> {}

// SAFETY: `NonZero<i8>` has the same layout as
// `i8`: [0]
//
// > `NonZero<T>` is guaranteed to have the same
// > layout and bit validity as `T`...
//
// [0]: The Rust Standard Library, core::num::NonZero
unsafe impl Unaligned for NonZero<i8> {}

// SAFETY: `NonZero<u8>` has the same layout as
// `u8`: [0]
//
// > `NonZero<T>` is guaranteed to have the same
// > layout and bit validity as `T`...
//
// [0]: The Rust Standard Library, core::num::NonZero
unsafe impl Unaligned for NonZero<u8> {}

// SAFETY: `Option<NonZero<i8>>` has the same
// layout as `NonZero<i8>`: [0]
//
// > Thanks to the null pointer optimization,
// > `NonZero<T>` and `Option<NonZero<T>>` are
// > guaranteed to have the same size and align-
// > ment...
//
// [0]: The Rust Standard Library, core::num::NonZero
unsafe impl Unaligned for Option<NonZero<i8>> {}

// SAFETY: `Option<NonZero<u8>>` has the same
// layout as `NonZero<u8>`: [0]
//
// > Thanks to the null pointer optimization,
// > `NonZero<T>` and `Option<NonZero<T>>` are
// > guaranteed to have the same size and align-
// > ment...
//
// [0]: The Rust Standard Library, core::num::NonZero
unsafe impl Unaligned for Option<NonZero<u8>> {}

// SAFETY: `Ordering` has `i8` representation and
// no explicit alignment, making it have the same
// layout as `i8`: [0]
//
// > For field-less enums, primitive representa-
// > tions set the size and alignment to be the
// > same as the primitive type of the same name.
//
// [0]: The Rust Reference, layout.repr.primitive.enum
unsafe impl Unaligned for cmp::Ordering {}

// SAFETY: `PhantomData` is guaranteed to be un-
// aligned: [0]
//
// > For all `T`, the following are guaranteed:
// >
// > * `size_of::<PhantomData<T>>() == 0`
// > * `align_of::<PhantomData<T>>() == 1`
//
// [0]: The Rust Standard Library, core::marker::PhantomData
unsafe impl<T: ?Sized> Unaligned for PhantomData<T> {}

// SAFETY: NOT GUARANTEED, DO NOT UNCOMMENT.
//unsafe impl Unaligned for PhantomPinned {}

// SAFETY: `Reverse<T>` is a structure transparent
// to `T`.
unsafe impl<T: Unaligned> Unaligned for Reverse<T> {}

// SAFETY: `Saturating<T>` is a structure transpar-
// ent to `T`.
unsafe impl<T: Unaligned> Unaligned for Saturating<T> {}

// SAFETY: Slices have the same layout as arrays:
// [0]
//
// > Slices have the same layout as the section of
// > the array they slice.
//
// [0]: The Rust Reference, layout.slice
unsafe impl<T: Unaligned> Unaligned for [T] {}

// SAFETY: String slices have the same layout as
// octet slices: [0]
//
// > String slices are a UTF-8 representation of
// > characters that have the same layout as slices
// > of type `[u8]`.
//
// [0]: The Rust Reference, layout.str
unsafe impl Unaligned for str {}

// SAFETY: The size of `u8` is `1`. [0] The align-
// ment of a type cannot be greater than its size:
// [1]
//
// > The alignment of primitives is platform-spe-
// > cific. In most cases, their alignment is equal
// to their size, but it may be less.
//
// [0]: The Rust Reference, layout.primitive.size
// [1]: The Rust Reference, layout.primitive.platform-specific-alignement
unsafe impl Unaligned for u8 {}

// SAFETY: `()` always has alignment of `1`: [0]
//
// > ... The exception to this is the unit tuple
// > (`()`), which is guaranteed as a zero-sized
// > type to have a size of 0 and an alignment of
// > 1.
//
// [0]: The Rust Reference, layout.tuple.unit
unsafe impl Unaligned for () {}

// SAFETY: `UnsafeCell<T>` has the same layout as
// `T`: [0]
//
// > Even though `T` and `UnsafeCell<T>` have the
// > same memory layout...
//
// [0]: The Rust Standard Library, core::cell::UnsafeCell
unsafe impl<T: Unaligned> Unaligned for UnsafeCell<T> {}

// SAFETY: `Wrapping<T>` has the same layout as
// `T`: [0]
//
// > `Wrapping<T>` is guaranteed to have the same
// > layout and ABI as `T`.
//
// [0]: The Rust Standard Library, core::num::Wrapping
unsafe impl<T: Unaligned> Unaligned for Wrapping<T> {}