ocaml_interop/mlvalues/bigarray.rs
1use core::marker::PhantomData;
2
3/// Bigarray kind
4///
5/// # Safety
6///
7/// This is unsafe to implement, because it allows casts
8/// to the implementing type (through `OCaml<Array1<T>>::as_slice()`).
9///
10/// To make this safe, the type implementing this trait must be
11/// safe to transmute from OCaml data with the relevant KIND.
12//
13// Using a trait for this means a Rust type can only be matched to a
14// single kind. There are enough Rust types that this isn't a problem
15// in practice.
16pub unsafe trait BigarrayElt: Copy {
17 /// OCaml bigarray type identifier
18 const KIND: i32;
19}
20
21// TODO:
22// assert that size_of::<$t>() matches caml_ba_element_size[$k]
23// Not sure we can check this at compile time,
24// when caml_ba_element_size is a C symbol
25macro_rules! make_kind {
26 ($t:ty, $k:ident) => {
27 unsafe impl BigarrayElt for $t {
28 const KIND: i32 = ocaml_sys::bigarray::Kind::$k as i32;
29 }
30 };
31}
32
33// In kind order
34// Skips some kinds OCaml supports: caml_int, complex32, complex64
35make_kind!(f32, FLOAT32);
36make_kind!(f64, FLOAT64);
37make_kind!(i8, SINT8);
38make_kind!(u8, UINT8);
39make_kind!(i16, SINT16);
40make_kind!(u16, UINT16);
41make_kind!(i32, INT32);
42make_kind!(i64, INT64);
43make_kind!(isize, NATIVE_INT);
44make_kind!(char, CHAR);
45
46pub struct Array1<A: BigarrayElt> {
47 _marker: PhantomData<A>,
48}