Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/bytemuck/src/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 7 kB image not shown  

Quelle  must.rs

  Sprache: Rust
 

#![allow(clippy::module_name_repetitions)]
#![allow(clippy::let_unit_value)]
#![allow(clippy::let_underscore_untyped)]
#![allow(clippy::ptr_as_ptr)]

use crate::{AnyBitPattern, NoUninit};
use core::mem::{align_of, size_of};

struct Cast<A, B>((A, B));
impl<A, B> Cast<A, B> {
  const ASSERT_ALIGN_GREATER_THAN_EQUAL: () =
    assert!(align_of::<A>() >= align_of::<B>());
  const ASSERT_SIZE_EQUAL: () = assert!(size_of::<A>() == size_of::<B>());
  const ASSERT_SIZE_MULTIPLE_OF_OR_INPUT_ZST: () = assert!(
    (size_of::<A>() == 0)
      || (size_of::<B>() != 0 && size_of::<A>() % size_of::<B>() == 0)
  );
}

/// Cast `A` into `B` if infalliable, or fail to compile.
///
/// Note that for this particular type of cast, alignment isn't a factor. The
/// input value is semantically copied into the function and then returned to a
/// new memory location which will have whatever the required alignment of the
/// output type is.
///
/// ## Failure
///
/// * If the types don't have the same size this fails to compile.
///
/// ## Examples
/// ```
/// // compiles:
/// let bytes: [u8; 2] = bytemuck::must_cast(12_u16);
/// ```
/// ```compile_fail,E0080
/// // fails to compile (size mismatch):
/// let bytes : [u8; 3] = bytemuck::must_cast(12_u16);
/// ```
#[inline]
pub const fn must_cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B {
  let _ = Cast::<A, B>::ASSERT_SIZE_EQUAL;
  unsafe { transmute!(A; B; a) }
}

/// Convert `&A` into `&B` if infalliable, or fail to compile.
///
/// ## Failure
///
/// * If the target type has a greater alignment requirement.
/// * If the source type and target type aren't the same size.
///
/// ## Examples
/// ```
/// // compiles:
/// let bytes: &[u8; 2] = bytemuck::must_cast_ref(&12_u16);
/// ```
/// ```compile_fail,E0080
/// // fails to compile (size mismatch):
/// let bytes : &[u8; 3] = bytemuck::must_cast_ref(&12_u16);
/// ```
/// ```compile_fail,E0080
/// // fails to compile (alignment requirements increased):
/// let bytes : &u16 = bytemuck::must_cast_ref(&[1u8, 2u8]);
/// ```
#[inline]
pub const fn must_cast_ref<A: NoUninit, B: AnyBitPattern>(a: &A) -> &B {
  let _ = Cast::<A, B>::ASSERT_SIZE_EQUAL;
  let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
  unsafe { &*(a as *const A as *const B) }
}

maybe_const_fn! {
  #[cfg(feature = "must_cast_extra")]
  /// Convert a `&mut A` into `&mut B` if infalliable, or fail to compile.
  ///
  /// As [`must_cast_ref`], but `mut`.
  ///
  /// ## Examples
  /// ```
  /// let mut i = 12_u16;
  /// // compiles:
  /// let bytes: &mut [u8; 2] = bytemuck::must_cast_mut(&mut i);
  /// ```
  /// ```compile_fail,E0080
  /// # let mut bytes: &mut [u8; 2] = &mut [1, 2];
  /// // fails to compile (alignment requirements increased):
  /// let i : &mut u16 = bytemuck::must_cast_mut(bytes);
  /// ```
  /// ```compile_fail,E0080
  /// # let mut i = 12_u16;
  /// // fails to compile (size mismatch):
  /// let bytes : &mut [u8; 3] = bytemuck::must_cast_mut(&mut i);
  /// ```
  #[inline]
  pub fn must_cast_mut<
    A: NoUninit + AnyBitPattern,
    B: NoUninit + AnyBitPattern,
  >(
    a: &mut A,
  ) -> &mut B {
    let _ = Cast::<A, B>::ASSERT_SIZE_EQUAL;
    let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
    unsafe { &mut *(a as *mut A as *mut B) }
  }
}

/// Convert `&[A]` into `&[B]` (possibly with a change in length) if
/// infalliable, or fail to compile.
///
/// * `input.as_ptr() as usize == output.as_ptr() as usize`
/// * `input.len() * size_of::<A>() == output.len() * size_of::<B>()`
///
/// ## Failure
///
/// * If the target type has a greater alignment requirement.
/// * If the target element type doesn't evenly fit into the the current element
///   type (eg: 3 `u16` values is 1.5 `u32` values, so that's a failure).
/// * Similarly, you can't convert from a non-[ZST](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts)
///   to a ZST (e.g. 3 `u8` values is not any number of `()` values).
///
/// ## Examples
/// ```
/// let indicies: &[u16] = &[1, 2, 3];
/// // compiles:
/// let bytes: &[u8] = bytemuck::must_cast_slice(indicies);
/// ```
/// ```
/// let zsts: &[()] = &[(), (), ()];
/// // compiles:
/// let bytes: &[u8] = bytemuck::must_cast_slice(zsts);
/// ```
/// ```compile_fail,E0080
/// # let bytes : &[u8] = &[1, 0, 2, 0, 3, 0];
/// // fails to compile (bytes.len() might not be a multiple of 2):
/// let byte_pairs : &[[u8; 2]] = bytemuck::must_cast_slice(bytes);
/// ```
/// ```compile_fail,E0080
/// # let byte_pairs : &[[u8; 2]] = &[[1, 0], [2, 0], [3, 0]];
/// // fails to compile (alignment requirements increased):
/// let indicies : &[u16] = bytemuck::must_cast_slice(byte_pairs);
/// ```
/// ```compile_fail,E0080
/// let bytes: &[u8] = &[];
/// // fails to compile: (bytes.len() might not be 0)
/// let zsts: &[()] = bytemuck::must_cast_slice(bytes);
/// ```
#[inline]
pub const fn must_cast_slice<A: NoUninit, B: AnyBitPattern>(a: &[A]) -> &[B] {
  let _ = Cast::<A, B>::ASSERT_SIZE_MULTIPLE_OF_OR_INPUT_ZST;
  let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
  let new_len = if size_of::<A>() == size_of::<B>() {
    a.len()
  } else {
    a.len() * (size_of::<A>() / size_of::<B>())
  };
  unsafe { core::slice::from_raw_parts(a.as_ptr() as *const B, new_len) }
}

maybe_const_fn! {
  #[cfg(feature = "must_cast_extra")]
  /// Convert `&mut [A]` into `&mut [B]` (possibly with a change in length) if
  /// infalliable, or fail to compile.
  ///
  /// As [`must_cast_slice`], but `&mut`.
  ///
  /// ## Examples
  /// ```
  /// let mut indicies = [1, 2, 3];
  /// let indicies: &mut [u16] = &mut indicies;
  /// // compiles:
  /// let bytes: &mut [u8] = bytemuck::must_cast_slice_mut(indicies);
  /// ```
  /// ```
  /// let zsts: &mut [()] = &mut [(), (), ()];
  /// // compiles:
  /// let bytes: &mut [u8] = bytemuck::must_cast_slice_mut(zsts);
  /// ```
  /// ```compile_fail,E0080
  /// # let mut bytes = [1, 0, 2, 0, 3, 0];
  /// # let bytes : &mut [u8] = &mut bytes[..];
  /// // fails to compile (bytes.len() might not be a multiple of 2):
  /// let byte_pairs : &mut [[u8; 2]] = bytemuck::must_cast_slice_mut(bytes);
  /// ```
  /// ```compile_fail,E0080
  /// # let mut byte_pairs = [[1, 0], [2, 0], [3, 0]];
  /// # let byte_pairs : &mut [[u8; 2]] = &mut byte_pairs[..];
  /// // fails to compile (alignment requirements increased):
  /// let indicies : &mut [u16] = bytemuck::must_cast_slice_mut(byte_pairs);
  /// ```
  /// ```compile_fail,E0080
  /// let bytes: &mut [u8] = &mut [];
  /// // fails to compile: (bytes.len() might not be 0)
  /// let zsts: &mut [()] = bytemuck::must_cast_slice_mut(bytes);
  /// ```
  #[inline]
  pub fn must_cast_slice_mut<
    A: NoUninit + AnyBitPattern,
    B: NoUninit + AnyBitPattern,
  >(
    a: &mut [A],
  ) -> &mut [B] {
    let _ = Cast::<A, B>::ASSERT_SIZE_MULTIPLE_OF_OR_INPUT_ZST;
    let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
    let new_len = if size_of::<A>() == size_of::<B>() {
      a.len()
    } else {
      a.len() * (size_of::<A>() / size_of::<B>())
    };
    unsafe { core::slice::from_raw_parts_mut(a.as_mut_ptr() as *mut B, new_len) }
  }
}

Messung V0.5 in Prozent
C=83 H=92 G=87

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.