polylane 0.6.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/>.

mod seal {
	pub trait SimdElement { }
}

use crate::mask::MaskElement;

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

pub(crate) use seal::SimdElement as SealedSimdElement;

/// Denotes a type suitable as a SIMD vector element.
///
/// Only primitive, arithmetic types may be vector elements.
///
/// # Safety
///
/// [`Mask`](Self::Mask) must have the exact same size as `Self`.
pub unsafe trait SimdElement: Copy + SealedSimdElement {
	/// The appropriate mask element type for this type.
	type Mask: MaskElement;
}

macro_rules! impl_simd_element {
	{
		$($Ty:ty => $Mask:ty),*$(,)?
	} => {
		$(
			impl ::polylane::simd::SealedSimdElement for $Ty { }

			unsafe impl ::polylane::simd::SimdElement for $Ty {
				type Mask = $Mask;
			}
		)*
	};
}

impl_simd_element! {
	u8    => i8,
	i8    => i8,
	u16   => i16,
	i16   => i16,
	u32   => i32,
	i32   => i32,
	u64   => i64,
	i64   => i64,
	u128  => i128,
	i128  => i128,
	usize => isize,
	isize => isize,

	f32 => i32,
	f64 => i64,
}

#[cfg(feature = "f16")]
impl_simd_element! { f16 => i16 }

#[cfg(feature = "f128")]
impl_simd_element! { f128 => i128 }

#[cfg(feature = "ptr")]
impl<T: Thin> SealedSimdElement for *const T { }

#[cfg(feature = "ptr")]
unsafe impl<T: Thin> SimdElement for *const T {
	type Mask = isize;
}

#[cfg(feature = "ptr")]
impl<T: Thin> SealedSimdElement for *mut T { }

#[cfg(feature = "ptr")]
unsafe impl<T: Thin> SimdElement for *mut T {
	type Mask = isize;
}