1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*!
 * Implementations on the raw `mxArray` pointer.
 */
#![allow(bad_style)]

use crate::shim::*;
pub use crate::classid::ClassID;

pub type mxClassID = ::std::os::raw::c_uint;
pub type mxComplexity = ::std::os::raw::c_uint;
// NOTE: Bindgen made these signed types, but Matlab's tmwtypes header says in a comment
// they should be unsigned (which makes more sense tbh)
pub type mwIndex = usize;
pub type mwSize = usize;
pub type mwSignedIndex = isize;

pub const mxClassID_mxUNKNOWN_CLASS: mxClassID = 0;
pub const mxClassID_mxCELL_CLASS: mxClassID = 1;
pub const mxClassID_mxSTRUCT_CLASS: mxClassID = 2;
pub const mxClassID_mxLOGICAL_CLASS: mxClassID = 3;
pub const mxClassID_mxCHAR_CLASS: mxClassID = 4;
pub const mxClassID_mxVOID_CLASS: mxClassID = 5;
pub const mxClassID_mxDOUBLE_CLASS: mxClassID = 6;
pub const mxClassID_mxSINGLE_CLASS: mxClassID = 7;
pub const mxClassID_mxINT8_CLASS: mxClassID = 8;
pub const mxClassID_mxUINT8_CLASS: mxClassID = 9;
pub const mxClassID_mxINT16_CLASS: mxClassID = 10;
pub const mxClassID_mxUINT16_CLASS: mxClassID = 11;
pub const mxClassID_mxINT32_CLASS: mxClassID = 12;
pub const mxClassID_mxUINT32_CLASS: mxClassID = 13;
pub const mxClassID_mxINT64_CLASS: mxClassID = 14;
pub const mxClassID_mxUINT64_CLASS: mxClassID = 15;
pub const mxClassID_mxFUNCTION_CLASS: mxClassID = 16;

pub const mxClassID_mxINDEX_CLASS: mxClassID = 15;

pub const mxClassID_mxOPAQUE_CLASS: mxClassID = 17;
pub const mxClassID_mxOBJECT_CLASS: mxClassID = 18;

pub const mxComplexity_mxREAL: mxComplexity = 0;
pub const mxComplexity_mxCOMPLEX: mxComplexity = 1;

/**
 * The main matlab opaque array type, returned and accepted as argument by various mex
 * functions.
 */
#[allow(non_camel_case_types)]
pub type mxArray = mxArray_tag;

// NOTE: Bindgen derived Copy and Clone for this type, while it definitely is not
// straightforwardly Copy or Clone.
#[repr(C)]
#[allow(non_camel_case_types)]
#[derive(Debug)]
pub struct mxArray_tag {
    _unused: [u8; 0],
}

impl mxArray {
	/// Return the sizes of the constituent dimensions of the mxArray
	pub fn dimensions(&self) -> &[usize] {
		unsafe {
			std::slice::from_raw_parts(
				rustmex_get_dimensions(self),
				rustmex_get_number_of_dimensions(self)
			)
		}
	}

	/// Return the number of elements contained in this array.
	pub fn numel(&self) -> usize {
		unsafe { rustmex_numel(self) }
	}

	/// Return the raw class ID; the number Matlab returns.
	pub fn raw_class_id(&self) -> mxClassID {
		unsafe { rustmex_get_class_id(self) }
	}

	/// Return `Ok(ClassID)` for mxArrays which map to a built-in class (such as
	/// numeric arrays, structure arrays, and cell arrays (_see_ [`ClassID`]);
	/// otherwise it returns the raw class ID in the `Err` variant. These other
	/// values of the raw class ID are used in modern versions of Matlab for custom
	/// classes, defined via _e..g_ `classdef`.
	pub fn class_id(&self) -> Result<ClassID, mxClassID> {
		self.raw_class_id().try_into()
	}

	/// Check whether the backing array is complex. Since the only arrays which can
	/// be complex are numeric arrays, this also implies that.
	pub fn is_complex(&self) -> bool {
		unsafe { rustmex_is_complex(self) }
	}

	/// Check whether the backing array is a sparse matrix
	pub fn is_sparse(&self) -> bool {
		unsafe { rustmex_is_sparse(self) }
	}

	/// Check whether the backing array is a struct array
	pub fn is_struct(&self) -> bool {
		unsafe { rustmex_is_struct(self) }
	}

	/// Check whether the backing array is empty
	pub fn is_empty(&self) -> bool {
		self.numel() == 0
	}

	/// Check whether the backing array only holds one element
	pub fn is_scalar(&self) -> bool {
		self.numel() == 1
	}
}