mod allocator;
pub use allocator::Allocator;
use mlir_sys::{mlirTypeIDCreate, mlirTypeIDEqual, mlirTypeIDHashValue, MlirTypeID};
use std::{
hash::{Hash, Hasher},
marker::PhantomData,
};
#[derive(Clone, Copy, Debug)]
pub struct TypeId<'c> {
raw: MlirTypeID,
_owner: PhantomData<&'c ()>,
}
impl TypeId<'_> {
pub const unsafe fn from_raw(raw: MlirTypeID) -> Self {
Self {
raw,
_owner: PhantomData,
}
}
pub const fn to_raw(self) -> MlirTypeID {
self.raw
}
pub fn create<T>(reference: &T) -> Self {
let ptr = reference as *const _ as *const std::ffi::c_void;
assert_eq!(
ptr.align_offset(8),
0,
"type ID pointer must be 8-byte aligned"
);
unsafe { Self::from_raw(mlirTypeIDCreate(ptr)) }
}
}
impl PartialEq for TypeId<'_> {
fn eq(&self, other: &Self) -> bool {
unsafe { mlirTypeIDEqual(self.raw, other.raw) }
}
}
impl Eq for TypeId<'_> {}
impl Hash for TypeId<'_> {
fn hash<H: Hasher>(&self, hasher: &mut H) {
unsafe {
mlirTypeIDHashValue(self.raw).hash(hasher);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn create_from_reference() {
static VALUE: u64 = 0;
TypeId::create(&VALUE);
}
#[test]
#[should_panic]
fn reject_invalid_alignment() {
static VALUES: [u8; 2] = [1u8; 2];
TypeId::create(&VALUES[1]);
}
}