polylane 0.12.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::Freeze;
use crate::compat::bytemuck;
use crate::compat::zerocopy;

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 Alignement:
	'static
	+ Any
	+ bytemuck::AnyBitPattern
	+ Copy
	+ Debug
	+ Default
	+ Eq
	+ Freeze
	+ zerocopy::FromBytes
	+ Hash
	+ zerocopy::IntoBytes
	+ zerocopy::KnownLayout
	+ bytemuck::NoUninit
	+ Ord
	+ PartialEq
	+ PartialOrd
	+ bytemuck::Pod
	+ RefUnwindSafe
	+ Send
	+ Sync
	+ Unpin
	+ UnwindSafe
	+ bytemuck::Zeroable
{
	const NEW: Self;
}

macro_rules! def_alignements {
	{ $($Ident:ident @ $align:literal),*$(,)? } => {
		$(
			#[repr(align($align), C)]
			#[derive(
				::core::clone::Clone,
				::core::cmp::Eq,
				::core::cmp::Ord,
				::core::cmp::PartialEq,
				::core::cmp::PartialOrd,
				::core::default::Default,
				::core::fmt::Debug,
				::core::hash::Hash,
				::core::marker::Copy,
			)]
			#[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::Alignement for $Ident {
				const NEW: Self = Self;
			}
		)?
	};
}

def_alignements! {
	AlignementByteX1    @ 0x001,
	AlignementByteX2    @ 0x002,
	AlignementByteX4    @ 0x004,
	AlignementByteX8    @ 0x008,
	AlignementByteX16   @ 0x010,
	AlignementByteX32   @ 0x020,
	AlignementByteX64   @ 0x040,
	AlignementByteX128  @ 0x080,
	AlignementByteX256  @ 0x100,
	AlignementByteX512  @ 0x200,
	AlignementByteX1024 @ 0x400,
}

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

#[cfg(target_pointer_width = "16")]
def_alignement_aliases! {
	AlignementSizeX1  = AlignementByteX2,
	AlignementSizeX2  = AlignementByteX4,
	AlignementSizeX4  = AlignementByteX8,
	AlignementSizeX8  = AlignementByteX16,
	AlignementSizeX16 = AlignementByteX32,
	AlignementSizeX32 = AlignementByteX64,
	AlignementSizeX64 = AlignementByteX128,
}

#[cfg(target_pointer_width = "32")]
def_alignement_aliases! {
	AlignementSizeX1  = AlignementByteX4,
	AlignementSizeX2  = AlignementByteX8,
	AlignementSizeX4  = AlignementByteX16,
	AlignementSizeX8  = AlignementByteX32,
	AlignementSizeX16 = AlignementByteX64,
	AlignementSizeX32 = AlignementByteX128,
	AlignementSizeX64 = AlignementByteX256,
}

#[cfg(target_pointer_width = "64")]
def_alignement_aliases! {
	AlignementSizeX1  = AlignementByteX8,
	AlignementSizeX2  = AlignementByteX16,
	AlignementSizeX4  = AlignementByteX32,
	AlignementSizeX8  = AlignementByteX64,
	AlignementSizeX16 = AlignementByteX128,
	AlignementSizeX32 = AlignementByteX256,
	AlignementSizeX64 = AlignementByteX512,
}