rgsl/
macros.rs

1//
2// A rust binding for the GSL library by Guillaume Gomez (guillaume1.gomez@gmail.com)
3//
4
5#![macro_use]
6
7#[doc(hidden)]
8macro_rules! ffi_wrap {
9    ($name:tt) => {
10        unsafe { $crate::ffi::FFI::wrap(sys::$name as *mut _) }
11    };
12}
13
14#[doc(hidden)]
15macro_rules! wrap_callback {
16    ($f:expr, $F:ident $(+ $lt:lifetime)?) => {{
17        unsafe extern "C" fn trampoline<$($lt,)? F: Fn(f64) -> f64 $( + $lt)?>(
18            x: f64,
19            params: *mut std::os::raw::c_void,
20        ) -> f64 {
21            let f: &F = &*(params as *const F);
22            let x = f(x);
23            x
24        }
25
26        sys::gsl_function_struct {
27            function: Some(trampoline::<$F>),
28            params: &$f as *const _ as *mut _,
29        }
30    }};
31}
32
33#[doc(hidden)]
34macro_rules! ffi_wrapper {
35    ($name:ident $(<$($lt:lifetime),*>)?, *mut $ty:ty, $drop:ident $(;$extra_id:ident: $extra_ty:ty => $extra_expr:expr;)* $(, $doc:expr)?) => {
36        ffi_wrapper!($name $(<$($lt),*>)?, *mut $ty $(;$extra_id: $extra_ty => $extra_expr;)* $(, $doc)?);
37
38        impl$(<$($lt),*>)? Drop for $name$(<$($lt),*>)? {
39            fn drop(&mut self) {
40                unsafe { sys::$drop(self.inner) };
41                self.inner = std::ptr::null_mut();
42            }
43        }
44    };
45    ($name:ident $(<$($lt:lifetime),*>)?, *mut $ty:ty $(;$extra_id:ident: $extra_ty:ty => $extra_expr:expr;)* $(, $doc:expr)?) => {
46        $(#[doc = $doc])?
47        pub struct $name$(<$($lt),*>)? {
48            inner: *mut $ty,
49            $($extra_id: $extra_ty,)*
50        }
51
52        impl$(<$($lt),*>)? FFI<$ty> for $name$(<$($lt),*>)? {
53            fn wrap(inner: *mut $ty) -> Self {
54                Self { inner $(, $extra_id: $extra_expr)* }
55            }
56
57            fn soft_wrap(r: *mut $ty) -> Self {
58                Self::wrap(r)
59            }
60
61            #[inline]
62            fn unwrap_shared(&self) -> *const $ty {
63                self.inner as *const _
64            }
65
66            #[inline]
67            fn unwrap_unique(&mut self) -> *mut $ty {
68                self.inner
69            }
70        }
71    };
72    ($name:ident $(<$($lt:lifetime),*>)?, *const $ty:ty $(;$extra_id:ident: $extra_ty:ty => $extra_expr:expr;)* $(, $doc:expr)?) => {
73        $(#[doc = $doc])?
74        #[derive(Clone, Copy)]
75        pub struct $name$(<$($lt),*>)? {
76            inner: *const $ty,
77            $($extra_id: $extra_ty,)*
78        }
79
80        impl$(<$($lt),*>)? FFI<$ty> for $name$(<$($lt),*>)? {
81            fn wrap(inner: *mut $ty) -> Self {
82                Self { inner $(, $extra_id: $extra_expr)* }
83            }
84
85            fn soft_wrap(inner: *mut $ty) -> Self {
86                Self { inner $(, $extra_id: $extra_expr)* }
87            }
88
89            #[inline]
90            fn unwrap_shared(&self) -> *const $ty {
91                self.inner
92            }
93
94            fn unwrap_unique(&mut self) -> *mut $ty {
95                unimplemented!()
96            }
97        }
98    };
99    () => {}
100}
101
102#[doc(hidden)]
103macro_rules! result_handler {
104    ($ret:ident, $value:expr) => {{
105        if $ret == crate::sys::GSL_SUCCESS {
106            Ok($value)
107        } else {
108            Err(crate::Value::from($ret))
109        }
110    }};
111}