use std::hash::{Hasher, Hash};
use crate::{ImgRef, ImgVec, ImgRefMut};
impl<'a, T: Hash> Hash for ImgRef<'a, T> {
#[allow(deprecated)]
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.width.hash(state);
self.height.hash(state);
for row in self.rows() {
Hash::hash_slice(row, state);
}
}
}
impl<'a, T: Hash> Hash for ImgRefMut<'a, T> {
#[allow(deprecated)]
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.as_ref().hash(state);
}
}
impl<T: Hash> Hash for ImgVec<T> {
#[inline(always)]
fn hash<H: Hasher>(&self, state: &mut H) {
self.as_ref().hash(state);
}
}
impl<'a, 'b, T, U> PartialEq<ImgRef<'b, U>> for ImgRef<'a, T> where T: PartialEq<U> {
#[allow(deprecated)]
#[inline]
fn eq(&self, other: &ImgRef<'b, U>) -> bool {
self.width == other.width &&
self.height == other.height &&
self.rows().zip(other.rows()).all(|(a,b)| a == b)
}
}
impl<'a, 'b, T, U> PartialEq<ImgRefMut<'b, U>> for ImgRefMut<'a, T> where T: PartialEq<U> {
#[allow(deprecated)]
#[inline]
fn eq(&self, other: &ImgRefMut<'b, U>) -> bool {
self.as_ref().eq(&other.as_ref())
}
}
impl<T, U> PartialEq<ImgVec<U>> for ImgVec<T> where T: PartialEq<U> {
#[allow(deprecated)]
#[inline(always)]
fn eq(&self, other: &ImgVec<U>) -> bool {
self.as_ref().eq(&other.as_ref())
}
}
impl<'a, T, U> PartialEq<ImgRef<'a, U>> for ImgVec<T> where T: PartialEq<U> {
#[allow(deprecated)]
#[inline(always)]
fn eq(&self, other: &ImgRef<'a, U>) -> bool {
self.as_ref().eq(other)
}
}
impl<'a, T, U> PartialEq<ImgVec<U>> for ImgRef<'a, T> where T: PartialEq<U> {
#[allow(deprecated)]
#[inline(always)]
fn eq(&self, other: &ImgVec<U>) -> bool {
self.eq(&other.as_ref())
}
}
impl<'a, 'b, T, U> PartialEq<ImgRef<'b, U>> for ImgRefMut<'a, T> where T: PartialEq<U> {
#[allow(deprecated)]
#[inline(always)]
fn eq(&self, other: &ImgRef<'b, U>) -> bool {
self.as_ref().eq(other)
}
}
impl<'a, 'b, T, U> PartialEq<ImgRefMut<'b, U>> for ImgRef<'a, T> where T: PartialEq<U> {
#[allow(deprecated)]
#[inline(always)]
fn eq(&self, other: &ImgRefMut<'b, U>) -> bool {
self.eq(&other.as_ref())
}
}
impl<'a, T: Eq> Eq for ImgRefMut<'a, T> {
}
impl<'a, T: Eq> Eq for ImgRef<'a, T> {
}
impl<T: Eq> Eq for ImgVec<T> {
}
#[test]
fn test_eq_hash() {
#[derive(Debug)]
struct Comparable(u16);
impl PartialEq<u8> for Comparable {
fn eq(&self, other: &u8) -> bool { self.0 == *other as u16 }
}
let newtype = ImgVec::new(vec![Comparable(0), Comparable(1), Comparable(2), Comparable(3)], 2, 2);
let mut img1 = ImgVec::new(vec![0u8, 1, 2, 3], 2, 2);
let img_ne = ImgVec::new(vec![0u8, 1, 2, 3], 4, 1);
let img2 = ImgVec::new_stride(vec![0u8, 1, 255, 2, 3, 255], 2, 2, 3);
let mut img3 = ImgVec::new_stride(vec![0u8, 1, 255, 2, 3], 2, 2, 3);
assert_eq!(newtype, img1);
equiv(&img1, &img2);
equiv(&img2, &img3);
equiv(&img1, &img3);
assert_ne!(img1, img_ne);
assert_eq!(img1.as_ref(), img2);
assert_eq!(img2, img3.as_ref());
equiv(&img1.as_ref(), &img3.as_ref());
equiv(&img1.as_mut(), &img3.as_mut());
assert_eq!(img2.as_ref(), img3.as_mut());
let mut map = HashSet::new();
img3[(0usize,0usize)] = 100;
assert_ne!(img1, img3);
assert!(map.insert(img1));
assert!(map.insert(img3));
assert!(map.insert(img_ne));
assert!(!map.insert(img2));
}
#[cfg(test)]
use std::fmt::Debug;
#[cfg(test)]
use std::collections::HashSet;
#[cfg(test)]
fn equiv<A>(a: &A, b: &A) where A: Eq + PartialEq + Hash + Debug {
assert_eq!(a, b);
let mut map = HashSet::new();
assert!(map.insert(a));
assert!(!map.insert(b));
assert!(!map.insert(a));
assert!(map.remove(b));
assert!(map.is_empty());
}