macro_rules! llzk_op_type {
($type:ident, $isa:ident, $opname:literal) => {
#[doc = concat!("Represents an owned '", $opname, "' op.")]
pub struct $type<'c> {
raw: mlir_sys::MlirOperation,
_context: std::marker::PhantomData<&'c melior::Context>,
}
impl<'c> $type<'c> {
#[doc = concat!("The MLIR operation must be a valid pointer of type ", stringify!($type) ,".")]
pub unsafe fn from_raw(raw: mlir_sys::MlirOperation) -> Self {
Self {
raw,
_context: std::marker::PhantomData,
}
}
pub const fn into_raw(self) -> mlir_sys::MlirOperation {
let operation = self.raw;
core::mem::forget(self);
operation
}
#[doc = concat!("Creates an optional operation from a raw object of type '", $opname, "'.")]
pub fn from_option_raw(raw: mlir_sys::MlirOperation) -> Option<Self> {
if raw.ptr.is_null() || unsafe { !$isa(raw) } {
None
} else {
unsafe { Some(Self::from_raw(raw)) }
}
}
}
impl<'a, 'c: 'a> melior::ir::operation::OperationLike<'c, 'a> for $type<'c> {
fn to_raw(&self) -> mlir_sys::MlirOperation {
self.raw
}
}
impl<'c: 'a, 'a> melior::ir::operation::OperationMutLike<'c, 'a> for $type<'c> {}
impl Clone for $type<'_> {
fn clone(&self) -> Self {
unsafe { Self::from_raw(mlir_sys::mlirOperationClone(self.raw)) }
}
}
impl Drop for $type<'_> {
fn drop(&mut self) {
unsafe { mlir_sys::mlirOperationDestroy(self.raw) };
}
}
impl<'a, 'c: 'a, T: melior::ir::operation::OperationLike<'c, 'a>> PartialEq<T> for $type<'c> {
fn eq(&self, other: &T) -> bool {
unsafe { mlir_sys::mlirOperationEqual(self.raw, other.to_raw()) }
}
}
impl Eq for $type<'_> {}
impl std::fmt::Display for $type<'_> {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
let r = unsafe { melior::ir::operation::OperationRef::from_raw(self.raw) };
std::fmt::Display::fmt(&r, formatter)
}
}
impl std::fmt::Debug for $type<'_> {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
writeln!(formatter, "{}(", stringify!($type))?;
std::fmt::Display::fmt(self, formatter)?;
write!(formatter, ")")
}
}
impl<'c> From<$type<'c>> for melior::ir::operation::Operation<'c> {
fn from(op: $type<'c>) -> melior::ir::operation::Operation<'c> {
unsafe { melior::ir::operation::Operation::from_raw(op.into_raw()) }
}
}
impl<'c> TryFrom<melior::ir::operation::Operation<'c>> for $type<'c> {
type Error = crate::error::Error;
fn try_from(op: melior::ir::operation::Operation<'c>) -> Result<Self, Self::Error> {
if unsafe { $isa(melior::ir::operation::OperationLike::to_raw(&op)) } {
Ok(unsafe { Self::from_raw(op.into_raw()) })
} else {
Err(Self::Error::OperationExpected($opname, op.to_string()))
}
}
}
paste::paste! {
#[doc = concat!("Represents a non-owned reference to a '", $opname, "' op.")]
#[derive(Copy, Clone)]
pub struct [<$type Ref>]<'c, 'a> {
raw: mlir_sys::MlirOperation,
_context: std::marker::PhantomData<&'a melior::ir::operation::Operation<'c>>,
}
impl<'c, 'a> [<$type Ref>]<'c, 'a> {
#[doc = concat!("Returns an operation of type '", $opname, "' op.")]
pub unsafe fn to_ref(&self) -> &'a $type<'c> {
unsafe { std::mem::transmute(self) }
}
pub const fn to_raw(self) -> mlir_sys::MlirOperation {
self.raw
}
#[doc = concat!("The MLIR operation must be a valid pointer of type ", stringify!([<$type Ref>]) ,".")]
pub unsafe fn from_raw(raw: mlir_sys::MlirOperation) -> Self {
Self {
raw,
_context: std::marker::PhantomData,
}
}
#[doc = concat!("The MLIR operation must be a valid pointer of type ", stringify!([<$type Ref>]) ,".")]
pub fn from_option_raw(raw: mlir_sys::MlirOperation) -> Option<Self> {
if raw.ptr.is_null() || unsafe { !$isa(raw) } {
None
} else {
unsafe { Some(Self::from_raw(raw)) }
}
}
}
impl<'a, 'c: 'a> melior::ir::operation::OperationLike<'c, 'a> for [<$type Ref>]<'c, 'a> {
fn to_raw(&self) -> mlir_sys::MlirOperation {
self.raw
}
}
impl<'c> std::ops::Deref for [<$type Ref>]<'c, '_> {
type Target = $type<'c>;
fn deref(&self) -> &Self::Target {
unsafe { self.to_ref() }
}
}
impl<'a, 'c: 'a, T: melior::ir::operation::OperationLike<'c, 'a>> PartialEq<T> for [<$type Ref>]<'c, 'a> {
fn eq(&self, other: &T) -> bool {
unsafe { mlir_sys::mlirOperationEqual(self.raw, other.to_raw()) }
}
}
impl Eq for [<$type Ref>]<'_, '_> {}
impl std::fmt::Display for [<$type Ref>]<'_,'_> {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
use std::ops::Deref;
std::fmt::Display::fmt(self.deref(), formatter)
}
}
impl std::fmt::Debug for [<$type Ref>]<'_,'_> {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
use std::ops::Deref;
std::fmt::Debug::fmt(self.deref(), formatter)
}
}
impl<'c,'a> From<[<$type Ref>]<'c, 'a>> for melior::ir::operation::OperationRef<'c,'a> {
fn from(op: [<$type Ref>]<'c,'a>) -> Self {
unsafe { Self::from_raw(op.to_raw()) }
}
}
impl<'c,'a> TryFrom<melior::ir::operation::OperationRef<'c,'a>> for [<$type Ref>]<'c,'a> {
type Error = crate::error::Error;
fn try_from(op: melior::ir::operation::OperationRef<'c,'a>) -> Result<Self, Self::Error> {
if unsafe { $isa(melior::ir::operation::OperationLike::to_raw(&op)) } {
Ok(unsafe { Self::from_raw(op.to_raw()) })
} else {
Err(Self::Error::OperationExpected($opname, op.to_string()))
}
}
}
#[doc = concat!("Represents a non-owned mutable reference to a '", $opname, "' op.")]
#[derive(Clone, Copy)]
pub struct [<$type RefMut>]<'c, 'a> {
raw: mlir_sys::MlirOperation,
_reference: std::marker::PhantomData<&'a melior::ir::operation::Operation<'c>>,
}
impl [<$type RefMut>]<'_, '_> {
pub const fn to_raw(self) -> mlir_sys::MlirOperation {
self.raw
}
#[doc = concat!("A raw object must be valid and of type '", $opname, "'.")]
pub unsafe fn from_raw(raw: mlir_sys::MlirOperation) -> Self {
Self {
raw,
_reference: Default::default(),
}
}
pub fn from_option_raw(raw: mlir_sys::MlirOperation) -> Option<Self> {
if raw.ptr.is_null() || unsafe { !$isa(raw) } {
None
} else {
unsafe { Some(Self::from_raw(raw)) }
}
}
}
impl<'c, 'a> melior::ir::operation::OperationLike<'c, 'a> for [<$type RefMut>]<'c, 'a> {
fn to_raw(&self) -> mlir_sys::MlirOperation {
self.raw
}
}
impl<'c, 'a> melior::ir::operation::OperationMutLike<'c, 'a> for [<$type RefMut>]<'c, 'a> {}
impl<'c> std::ops::Deref for [<$type RefMut>]<'c, '_> {
type Target = $type<'c>;
fn deref(&self) -> &Self::Target {
unsafe { std::mem::transmute(self) }
}
}
impl std::ops::DerefMut for [<$type RefMut>]<'_, '_> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { std::mem::transmute(self) }
}
}
impl<'a, 'c: 'a, T: melior::ir::operation::OperationLike<'c, 'a>> PartialEq<T> for [<$type RefMut>]<'c, 'a> {
fn eq(&self, other: &T) -> bool {
unsafe { mlir_sys::mlirOperationEqual(self.raw, other.to_raw()) }
}
}
impl Eq for [<$type RefMut>]<'_, '_> {}
impl std::fmt::Display for [<$type RefMut>]<'_, '_> {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
use std::ops::Deref;
std::fmt::Display::fmt(self.deref(), formatter)
}
}
impl std::fmt::Debug for [<$type RefMut>]<'_, '_> {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
use std::ops::Deref;
std::fmt::Debug::fmt(self.deref(), formatter)
}
}
impl<'c, 'a> From<[<$type Ref>]<'c, 'a>> for [<$type RefMut>]<'c, 'a> {
fn from(op: [<$type Ref>]<'c, 'a>) -> Self {
unsafe { Self::from_raw(op.to_raw()) }
}
}
impl<'c,'a> From<[<$type RefMut>]<'c, 'a>> for melior::ir::operation::OperationRefMut<'c,'a> {
fn from(op: [<$type RefMut>]<'c,'a>) -> Self {
unsafe { Self::from_raw(op.to_raw()) }
}
}
impl<'c,'a> TryFrom<melior::ir::operation::OperationRefMut<'c,'a>> for [<$type RefMut>]<'c,'a> {
type Error = crate::error::Error;
fn try_from(op: melior::ir::operation::OperationRefMut<'c,'a>) -> Result<Self, Self::Error> {
if unsafe { $isa(melior::ir::operation::OperationLike::to_raw(&op)) } {
Ok(unsafe { Self::from_raw(op.to_raw()) })
} else {
Err(Self::Error::OperationExpected($opname, op.to_string()))
}
}
}
}
};
}
pub(crate) use llzk_op_type;