polylane 0.13.0

Portable and versatile SIMD.
Documentation
// Copyright 2025 Gabriel Bjørnager Jensen.
//
// This Source Code Form is subject to the terms of
// the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, you
// can obtain one at:
// <https://mozilla.org/MPL/2.0/>.

use crate::compat;

use core::any::Any;
use core::fmt::Debug;
use core::hash::Hash;
use core::panic::{RefUnwindSafe, UnwindSafe};

// This trait should require all derived traits and
// auto traits that are expected for `Simd`.

pub trait Align:
	'static
	+ Any
	+ compat::bytemuck::AnyBitPattern
	+ Copy
	+ Debug
	+ Default
	+ Eq
	+ compat::Freeze
	+ compat::zerocopy::FromBytes
	+ Hash
	+ compat::zerocopy::IntoBytes
	+ compat::zerocopy::KnownLayout
	+ compat::bytemuck::NoUninit
	+ Ord
	+ PartialEq
	+ PartialOrd
	+ compat::bytemuck::Pod
	+ RefUnwindSafe
	+ Send
	+ Sync
	+ compat::Thin
	+ Unpin
	+ UnwindSafe
	+ compat::bytemuck::Zeroable
{
	const NEW: Self;
}

macro_rules! def_alignements {
	{ $($Ident:ident @ $align:literal),*$(,)? } => {
		$(
			#[repr(align($align), C)]
			#[derive(
				::core::clone::Clone,
				::core::marker::Copy,
				::core::fmt::Debug,
				::core::default::Default,
				::core::cmp::Eq,
				::core::hash::Hash,
				::core::cmp::Ord,
				::core::cmp::PartialEq,
				::core::cmp::PartialOrd,
			)]
			#[cfg_attr(
				feature = "bytemuck",
				derive(
					::bytemuck::Pod,
					::bytemuck::Zeroable,
				),
			)]
			#[cfg_attr(
				feature = "zerocopy",
				derive(
					::zerocopy::FromBytes,
					::zerocopy::IntoBytes,
					::zerocopy::KnownLayout,
				),
			)]
			pub struct $Ident;

			impl ::polylane::simd::align::Align for $Ident {
				const NEW: Self = Self;
			}
		)?
	};
}

// NOTE: Largest possible alignement is for
// `Simd<u128, 64>`.
def_alignements! {
	AlignByteX1    @ 0x001,
	AlignByteX2    @ 0x002,
	AlignByteX4    @ 0x004,
	AlignByteX8    @ 0x008,
	AlignByteX16   @ 0x010,
	AlignByteX32   @ 0x020,
	AlignByteX64   @ 0x040,
	AlignByteX128  @ 0x080,
	AlignByteX256  @ 0x100,
	AlignByteX512  @ 0x200,
	AlignByteX1024 @ 0x400,
}

macro_rules! def_alignement_aliases {
	{ $($Alias:ident = $Align:ty),*$(,)? } => {$(
		pub type $Alias = $Align;
	)*};
}

#[cfg(target_pointer_width = "16")]
def_alignement_aliases! {
	AlignSizeX1  = AlignByteX2,
	AlignSizeX2  = AlignByteX4,
	AlignSizeX4  = AlignByteX8,
	AlignSizeX8  = AlignByteX16,
	AlignSizeX16 = AlignByteX32,
	AlignSizeX32 = AlignByteX64,
	AlignSizeX64 = AlignByteX128,
}

#[cfg(target_pointer_width = "32")]
def_alignement_aliases! {
	AlignSizeX1  = AlignByteX4,
	AlignSizeX2  = AlignByteX8,
	AlignSizeX4  = AlignByteX16,
	AlignSizeX8  = AlignByteX32,
	AlignSizeX16 = AlignByteX64,
	AlignSizeX32 = AlignByteX128,
	AlignSizeX64 = AlignByteX256,
}

#[cfg(target_pointer_width = "64")]
def_alignement_aliases! {
	AlignSizeX1  = AlignByteX8,
	AlignSizeX2  = AlignByteX16,
	AlignSizeX4  = AlignByteX32,
	AlignSizeX8  = AlignByteX64,
	AlignSizeX16 = AlignByteX128,
	AlignSizeX32 = AlignByteX256,
	AlignSizeX64 = AlignByteX512,
}

// SAFETY: Duhhhhhhhhhhhhhhhhh.
#[cfg(feature = "zerocopy")]
unsafe impl zerocopy::Unaligned for AlignByteX1 {
	fn only_derive_is_allowed_to_implement_this_trait() {}
}