GSL 6.0.0

A rust binding for the GSL (the GNU scientific library)
Documentation
//
// A rust binding for the GSL library by Guillaume Gomez (guillaume1.gomez@gmail.com)
//

#![macro_use]

#[doc(hidden)]
macro_rules! ffi_wrap {
    ($name:tt) => {
        unsafe { $crate::ffi::FFI::wrap(sys::$name as *mut _) }
    };
}

#[doc(hidden)]
macro_rules! wrap_callback {
    ($f:expr, $F:ident $(+ $lt:lifetime)?) => {{
        unsafe extern "C" fn trampoline<$($lt,)? F: Fn(f64) -> f64 $( + $lt)?>(
            x: f64,
            params: *mut ::std::os::raw::c_void,
        ) -> f64 {
            let f: &F = &*(params as *const F);
            let x = f(x);
            x
        }

        sys::gsl_function_struct {
            function: Some(trampoline::<$F>),
            params: &$f as *const _ as *mut _,
        }
    }};
}

#[doc(hidden)]
macro_rules! ffi_wrapper {
    ($name:ident $(<$($lt:lifetime),*>)?, *mut $ty:ty, $drop:ident $(;$extra_id:ident: $extra_ty:ty => $extra_expr:expr;)* $(, $doc:expr)?) => {
        ffi_wrapper!($name $(<$($lt),*>)?, *mut $ty $(;$extra_id: $extra_ty => $extra_expr;)* $(, $doc)?);

        impl$(<$($lt),*>)? Drop for $name$(<$($lt),*>)? {
            fn drop(&mut self) {
                unsafe { sys::$drop(self.inner) };
                self.inner = ::std::ptr::null_mut();
            }
        }
    };
    ($name:ident $(<$($lt:lifetime),*>)?, *mut $ty:ty $(;$extra_id:ident: $extra_ty:ty => $extra_expr:expr;)* $(, $doc:expr)?) => {
        $(#[doc = $doc])?
        pub struct $name$(<$($lt),*>)? {
            inner: *mut $ty,
            $($extra_id: $extra_ty,)*
        }

        impl$(<$($lt),*>)? FFI<$ty> for $name$(<$($lt),*>)? {
            fn wrap(inner: *mut $ty) -> Self {
                Self { inner $(, $extra_id: $extra_expr)* }
            }

            fn soft_wrap(r: *mut $ty) -> Self {
                Self::wrap(r)
            }

            #[inline]
            fn unwrap_shared(&self) -> *const $ty {
                self.inner as *const _
            }

            #[inline]
            fn unwrap_unique(&mut self) -> *mut $ty {
                self.inner
            }
        }
    };
    ($name:ident $(<$($lt:lifetime),*>)?, *const $ty:ty $(;$extra_id:ident: $extra_ty:ty => $extra_expr:expr;)* $(, $doc:expr)?) => {
        $(#[doc = $doc])?
        #[derive(Clone, Copy)]
        pub struct $name$(<$($lt),*>)? {
            inner: *const $ty,
            $($extra_id: $extra_ty,)*
        }

        impl$(<$($lt),*>)? FFI<$ty> for $name$(<$($lt),*>)? {
            fn wrap(inner: *mut $ty) -> Self {
                Self { inner $(, $extra_id: $extra_expr)* }
            }

            fn soft_wrap(inner: *mut $ty) -> Self {
                Self { inner $(, $extra_id: $extra_expr)* }
            }

            #[inline]
            fn unwrap_shared(&self) -> *const $ty {
                self.inner
            }

            fn unwrap_unique(&mut self) -> *mut $ty {
                unimplemented!()
            }
        }
    };
    () => {}
}