oct 0.29.2

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

//! Tests for [`FromOcts`].

#![cfg(all(test, miri))]

use core::cell::{Cell, UnsafeCell};
use core::cmp::Reverse;
use core::hint::black_box;
use core::marker::{PhantomData, PhantomPinned};
use core::mem::{ManuallyDrop, MaybeUninit};
use core::num::{NonZero, Saturating, Wrapping};
use core::ptr::NonNull;
use oct::{FromOcts, Zeroable};

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

#[cfg(target_has_atomic = "16")]
use core::sync::atomic::{AtomicI16, AtomicU16};

#[cfg(target_has_atomic = "32")]
use core::sync::atomic::{AtomicI32, AtomicU32};

#[cfg(target_has_atomic = "64")]
use core::sync::atomic::{AtomicI64, AtomicU64};

#[cfg(target_has_atomic = "128")]
use core::sync::atomic::{AtomicI128, AtomicU128};

#[cfg(target_arch = "x86")]
use core::arch::x86::{
	__m128,
	__m128bh,
	__m128d,
	__m128i,
	__m256,
	__m256bh,
	__m256d,
	__m256i,
	__m512,
	__m512bh,
	__m512d,
	__m512i,
};

#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::{
	__m128,
	__m128bh,
	__m128d,
	__m128i,
	__m256,
	__m256bh,
	__m256d,
	__m256i,
	__m512,
	__m512bh,
	__m512d,
	__m512i,
};

#[test]
fn test_oned() {
	fn test<T: FromOcts>() {
		fn test<T: FromOcts>() {
			let value = T::oned();
			black_box(value);
		}

		test::<T>();
		test::<[T; 00]>();
		test::<[T; 01]>();
		test::<[T; 02]>();
		test::<[T; 03]>();
		test::<[T; 04]>();
		test::<[T; 05]>();
		test::<[T; 06]>();
		test::<[T; 07]>();
		test::<[T; 08]>();
		test::<[T; 09]>();
		test::<[T; 10]>();
		test::<[T; 11]>();
		test::<[T; 12]>();
		test::<[T; 13]>();
		test::<[T; 13]>();
		test::<[T; 14]>();
		test::<[T; 15]>();
		test::<[T; 16]>();
		test::<[T; 17]>();
		test::<[T; 18]>();
		test::<[T; 19]>();
		test::<[T; 20]>();
		test::<[T; 21]>();
		test::<[T; 22]>();
		test::<[T; 23]>();
		test::<[T; 23]>();
		test::<[T; 24]>();
		test::<[T; 25]>();
		test::<[T; 26]>();
		test::<[T; 27]>();
		test::<[T; 28]>();
		test::<[T; 29]>();
		test::<[T; 30]>();
		test::<[T; 31]>();
		test::<[T; 32]>();
		test::<Cell<T>>();
		test::<ManuallyDrop<T>>();
		test::<MaybeUninit<T>>();
		test::<Option<NonNull<T>>>();
		test::<PhantomData<T>>();
		test::<Reverse<T>>();
		test::<Saturating<T>>();
		test::<(T,)>();
		test::<(T, T)>();
		test::<(T, T, T)>();
		test::<(T, T, T, T)>();
		test::<(T, T, T, T, T)>();
		test::<(T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T, T, T, T, T)>();
		test::<UnsafeCell<T>>();
		test::<Wrapping<T>>();
	}

	test::<f32>();
	test::<f64>();
	test::<i128>();
	test::<i16>();
	test::<i32>();
	test::<i64>();
	test::<i8>();
	test::<isize>();
	test::<__m128>();
	test::<__m128>();
	test::<__m128bh>();
	test::<__m128bh>();
	test::<__m128d>();
	test::<__m128d>();
	test::<__m128i>();
	test::<__m128i>();
	test::<__m256>();
	test::<__m256>();
	test::<__m256bh>();
	test::<__m256bh>();
	test::<__m256d>();
	test::<__m256d>();
	test::<__m256i>();
	test::<__m256i>();
	test::<__m512>();
	test::<__m512>();
	test::<__m512bh>();
	test::<__m512bh>();
	test::<__m512d>();
	test::<__m512d>();
	test::<__m512i>();
	test::<__m512i>();
	test::<Option<NonNull<u8>>>();
	test::<Option<NonZero<i128>>>();
	test::<Option<NonZero<i16>>>();
	test::<Option<NonZero<i32>>>();
	test::<Option<NonZero<i64>>>();
	test::<Option<NonZero<i8>>>();
	test::<Option<NonZero<isize>>>();
	test::<Option<NonZero<u128>>>();
	test::<Option<NonZero<u16>>>();
	test::<Option<NonZero<u32>>>();
	test::<Option<NonZero<u64>>>();
	test::<Option<NonZero<u8>>>();
	test::<Option<NonZero<usize>>>();
	test::<PhantomPinned>();
	test::<u128>();
	test::<u16>();
	test::<u32>();
	test::<u64>();
	test::<u8>();
	test::<()>();
	test::<usize>();

	#[cfg(feature = "f128")]
	test::<f128>();

	#[cfg(feature = "f16")]
	test::<f16>();

	#[cfg(target_has_atomic = "128")]
	test::<AtomicI128>();

	#[cfg(target_has_atomic = "16")]
	test::<AtomicI16>();

	#[cfg(target_has_atomic = "32")]
	test::<AtomicI32>();

	#[cfg(target_has_atomic = "64")]
	test::<AtomicI64>();

	#[cfg(target_has_atomic = "8")]
	test::<AtomicI8>();

	#[cfg(target_has_atomic = "128")]
	test::<AtomicU128>();

	#[cfg(target_has_atomic = "16")]
	test::<AtomicU16>();

	#[cfg(target_has_atomic = "32")]
	test::<AtomicU32>();

	#[cfg(target_has_atomic = "64")]
	test::<AtomicU64>();

	#[cfg(target_has_atomic = "8")]
	test::<AtomicU8>();
}

#[cfg(feature = "proc_macro")]
#[should_panic]
#[test]
fn test_read_from_octs_aligned_unaligned() {
	#[repr(align(16), C)]
	#[derive(FromOcts, Zeroable)]
	struct Aligned;

	#[repr(align(16), C)]
	#[derive(Default)]
	struct Octs([u8; 2]);

	let octs = &Octs::default().0[1..];

	let _ = Aligned::read_from_octs(octs);
}

#[should_panic]
#[test]
fn test_read_from_octs_unsized() {
	#[repr(align(4), C)]
	#[derive(Default)]
	struct Octs([u8; 3]);

	let octs = &Octs::default().0;

	let _ = i32::read_from_octs(octs);
}