use core::marker::PhantomData;
use super::super::low;
use super::super::middle;
#[derive(Clone, Debug)]
pub struct Type<T> {
untyped: middle::Type,
_marker: PhantomData<*mut T>,
}
impl<T> Type<T> {
pub fn make(untyped: middle::Type) -> Self {
Type {
untyped,
_marker: PhantomData,
}
}
pub fn into_middle(self) -> middle::Type {
self.untyped
}
}
pub unsafe trait CType: Copy {
fn reify() -> Type<Self>;
type RetType: std::convert::From<Self> + std::convert::TryInto<Self>;
}
macro_rules! impl_ffi_type {
($type_:ty, $ret_:ty, $cons:ident) => {
unsafe impl CType for $type_ {
fn reify() -> Type<Self> {
Type::make(middle::Type::$cons())
}
type RetType = $ret_;
}
};
($type_:ident, $ret_:ty) => {
impl_ffi_type!($type_, $ret_, $type_);
};
($type_:ident) => {
impl_ffi_type!($type_, $type_, $type_);
};
}
impl_ffi_type!(u8, low::ffi_arg);
impl_ffi_type!(i8, low::ffi_sarg);
impl_ffi_type!(u16, low::ffi_arg);
impl_ffi_type!(i16, low::ffi_sarg);
impl_ffi_type!(u32, low::ffi_arg);
impl_ffi_type!(i32, low::ffi_sarg);
impl_ffi_type!(u64);
impl_ffi_type!(i64);
impl_ffi_type!(f32);
impl_ffi_type!(f64);
impl_ffi_type!(usize);
impl_ffi_type!(isize);
impl_ffi_type!((), (), void);
#[allow(non_camel_case_types)]
#[cfg(feature = "complex")]
pub type c_c32 = [f32; 2];
#[allow(non_camel_case_types)]
#[cfg(feature = "complex")]
pub type c_c64 = [f64; 2];
#[cfg(feature = "complex")]
impl_ffi_type!(c_c32, c32);
#[cfg(feature = "complex")]
impl_ffi_type!(c_c64, c64);
unsafe impl<T> CType for *const T {
fn reify() -> Type<Self> {
Type::make(middle::Type::pointer())
}
type RetType = *const T;
}
unsafe impl<T> CType for *mut T {
fn reify() -> Type<Self> {
Type::make(middle::Type::pointer())
}
type RetType = *mut T;
}