// Copyright 2025-2026 Gabriel Bjørnager Jensen.
//
// SPDX: MIT OR Apache-2.0

//! Comparison facilities for [`NVec`].

use core::cmp::Ordering;
use nvec::NVec;

#[cfg(feature = "alloc")]
use alloc::borrow::Cow;

#[cfg(feature = "alloc")]
use alloc::vec::Vec;

impl<T: Eq, const N: usize> Eq for NVec<T, N> {}

impl<T: Ord, const N: usize> Ord for NVec<T, N> {
	#[inline]
	fn cmp(&self, other: &Self) -> Ordering {
		Ord::cmp(&**self, &**other)
	}
}

// SORT: array
impl<T: PartialEq<U>, U, const N: usize, const M: usize> PartialEq<[U; M]> for NVec<T, N> {
	#[inline]
	fn eq(&self, other: &[U; M]) -> bool {
		PartialEq::eq(&**self, other)
	}

	#[inline]
	fn ne(&self, other: &[U; M]) -> bool {
		PartialEq::ne(&**self, other)
	}
}

// SORT: array
impl<T: PartialEq<U>, U, const N: usize, const M: usize> PartialEq<&[U; M]> for NVec<T, N> {
	#[inline]
	fn eq(&self, other: &&[U; M]) -> bool {
		PartialEq::eq(&**self, *other)
	}

	#[inline]
	fn ne(&self, other: &&[U; M]) -> bool {
		PartialEq::ne(&**self, *other)
	}
}

#[cfg(feature = "alloc")]
impl<T: PartialEq<U>, U: Clone, const N: usize> PartialEq<Cow<'_, [U]>> for NVec<T, N> {
	#[inline]
	fn eq(&self, other: &Cow<'_, [U]>) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &Cow<'_, [U]>) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}

impl<T: PartialEq<U>, U, const N: usize, const M: usize> PartialEq<NVec<U, M>> for NVec<T, N> {
	#[inline]
	fn eq(&self, other: &NVec<U, M>) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NVec<U, M>) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}

// SORT: slice
impl<T: PartialEq<U>, U, const N: usize> PartialEq<[U]> for NVec<T, N> {
	#[inline]
	fn eq(&self, other: &[U]) -> bool {
		PartialEq::eq(&**self, other)
	}

	#[inline]
	fn ne(&self, other: &[U]) -> bool {
		PartialEq::ne(&**self, other)
	}
}

// SORT: slice
impl<T: PartialEq<U>, U, const N: usize> PartialEq<&[U]> for NVec<T, N> {
	#[inline]
	fn eq(&self, other: &&[U]) -> bool {
		PartialEq::eq(&**self, *other)
	}

	#[inline]
	fn ne(&self, other: &&[U]) -> bool {
		PartialEq::ne(&**self, *other)
	}
}

// SORT: slice
impl<T: PartialEq<U>, U, const N: usize> PartialEq<&mut [U]> for NVec<T, N> {
	#[inline]
	fn eq(&self, other: &&mut [U]) -> bool {
		PartialEq::eq(&**self, *other)
	}

	#[inline]
	fn ne(&self, other: &&mut [U]) -> bool {
		PartialEq::ne(&**self, *other)
	}
}

#[cfg(feature = "alloc")]
impl<T: PartialEq<U>, U, const N: usize> PartialEq<Vec<U>> for NVec<T, N> {
	#[inline]
	fn eq(&self, other: &Vec<U>) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &Vec<U>) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}

impl<T: PartialOrd, const N: usize, const M: usize> PartialOrd<NVec<T, M>> for NVec<T, N> {
	#[inline]
	fn partial_cmp(&self, other: &NVec<T, M>) -> Option<Ordering> {
		PartialOrd::partial_cmp(&**self, &**other)
	}

	#[inline]
	fn lt(&self, other: &NVec<T, M>) -> bool {
		PartialOrd::lt(&**self, &**other)
	}

	#[inline]
	fn le(&self, other: &NVec<T, M>) -> bool {
		PartialOrd::le(&**self, &**other)
	}

	#[inline]
	fn gt(&self, other: &NVec<T, M>) -> bool {
		PartialOrd::gt(&**self, &**other)
	}

	#[inline]
	fn ge(&self, other: &NVec<T, M>) -> bool {
		PartialOrd::ge(&**self, &**other)
	}
}

#[cfg(feature = "alloc")]
impl<T: PartialEq<U> + Clone, U, const N: usize> PartialEq<NVec<U, N>> for Cow<'_, [T]> {
	#[inline]
	fn eq(&self, other: &NVec<U, N>) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NVec<U, N>) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}

// SORT: slice
impl<T: PartialEq<U>, U, const N: usize> PartialEq<NVec<U, N>> for [T] {
	#[inline]
	fn eq(&self, other: &NVec<U, N>) -> bool {
		PartialEq::eq(self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NVec<U, N>) -> bool {
		PartialEq::ne(self, &**other)
	}
}

// SORT: slice
impl<T: PartialEq<U>, U, const N: usize> PartialEq<NVec<U, N>> for &[T] {
	#[inline]
	fn eq(&self, other: &NVec<U, N>) -> bool {
		PartialEq::eq(*self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NVec<U, N>) -> bool {
		PartialEq::ne(*self, &**other)
	}
}

// SORT: slice
impl<T: PartialEq<U>, U, const N: usize> PartialEq<NVec<U, N>> for &mut [T] {
	#[inline]
	fn eq(&self, other: &NVec<U, N>) -> bool {
		PartialEq::eq(*self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NVec<U, N>) -> bool {
		PartialEq::ne(*self, &**other)
	}
}

#[cfg(feature = "alloc")]
impl<T: PartialEq<U>, U, const N: usize> PartialEq<NVec<U, N>> for Vec<T> {
	#[inline]
	fn eq(&self, other: &NVec<U, N>) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NVec<U, N>) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}
