use core::mem::MaybeUninit;
use crate::encode::{Encode, Encoding};
use super::InnerIvarType;
#[repr(transparent)]
pub struct IvarEncode<T>(MaybeUninit<T>);
unsafe impl<T: Encode> Encode for IvarEncode<T> {
const ENCODING: Encoding = T::ENCODING;
}
impl<T: Encode> super::ivar::private::Sealed for IvarEncode<T> {}
unsafe impl<T: Encode> InnerIvarType for IvarEncode<T> {
type Output = T;
#[inline]
unsafe fn __deref(&self) -> &Self::Output {
unsafe { self.0.assume_init_ref() }
}
#[inline]
unsafe fn __deref_mut(&mut self) -> &mut Self::Output {
unsafe { self.0.assume_init_mut() }
}
}
#[cfg(test)]
mod tests {
use super::*;
use core::mem;
#[test]
fn needs_drop() {
assert!(!mem::needs_drop::<IvarEncode<i32>>());
assert!(!mem::needs_drop::<IvarEncode<&i32>>());
#[repr(transparent)]
struct DropAndEncode(i32);
unsafe impl Encode for DropAndEncode {
const ENCODING: Encoding = i32::ENCODING;
}
impl Drop for DropAndEncode {
fn drop(&mut self) {}
}
assert!(mem::needs_drop::<DropAndEncode>());
assert!(!mem::needs_drop::<IvarEncode<DropAndEncode>>());
assert_eq!(mem::size_of::<IvarEncode<i32>>(), mem::size_of::<i32>());
}
}