Skip to main content

diffsol_c/
host_array_c.rs

1use std::ptr;
2
3use crate::c_invalid_arg;
4use crate::host_array::HostArray;
5use crate::scalar_type_c::{scalar_type_from_i32, scalar_type_to_i32};
6
7/// Allocate a one-dimensional host array of the requested length and scalar type.
8///
9/// # Safety
10/// The returned pointer must be freed with `diffsol_host_array_free`. `dtype`
11/// must be a valid scalar type enum defined by this library.
12#[unsafe(no_mangle)]
13pub unsafe extern "C" fn diffsol_host_array_alloc_vector(len: usize, dtype: i32) -> *mut HostArray {
14    let dtype = match scalar_type_from_i32(dtype) {
15        Some(value) => value,
16        None => {
17            c_invalid_arg!("invalid dtype");
18            return ptr::null_mut();
19        }
20    };
21    let array = HostArray::alloc_vector(len, dtype);
22    Box::into_raw(Box::new(array))
23}
24
25/// Free a host array previously returned by this library.
26///
27/// # Safety
28/// `array` must be either null or a pointer returned by this library that has
29/// not already been freed.
30#[unsafe(no_mangle)]
31pub unsafe extern "C" fn diffsol_host_array_free(array: *mut HostArray) {
32    if array.is_null() {
33        c_invalid_arg!("host array is null");
34        return;
35    }
36    unsafe {
37        drop(Box::from_raw(array));
38    }
39}
40
41/// Return the raw data pointer stored by a host array.
42///
43/// # Safety
44/// `array` must be a valid pointer to a `HostArray` created by this library.
45/// The returned pointer is borrowed and remains owned by the array.
46#[unsafe(no_mangle)]
47pub unsafe extern "C" fn diffsol_host_array_ptr(array: *const HostArray) -> *const u8 {
48    if array.is_null() {
49        c_invalid_arg!("host array is null");
50        return ptr::null();
51    }
52    let array = unsafe { &*array };
53    array.data_ptr()
54}
55
56/// Return the number of dimensions in a host array.
57///
58/// # Safety
59/// `array` must be a valid pointer to a `HostArray` created by this library.
60#[unsafe(no_mangle)]
61pub unsafe extern "C" fn diffsol_host_array_ndim(array: *const HostArray) -> usize {
62    if array.is_null() {
63        c_invalid_arg!("host array is null");
64        return 0;
65    }
66    let array = unsafe { &*array };
67    array.ndim()
68}
69
70/// Return the size of a single dimension in a host array.
71///
72/// # Safety
73/// `array` must be a valid pointer to a `HostArray` created by this library.
74/// `index` must be in bounds for the array shape.
75#[unsafe(no_mangle)]
76pub unsafe extern "C" fn diffsol_host_array_dim(array: *const HostArray, index: usize) -> usize {
77    if array.is_null() {
78        c_invalid_arg!("host array is null");
79        return 0;
80    }
81    let array = unsafe { &*array };
82    array.dim(index)
83}
84
85/// Return the stride, in bytes, for a single dimension in a host array.
86///
87/// # Safety
88/// `array` must be a valid pointer to a `HostArray` created by this library.
89/// `index` must be in bounds for the array shape.
90#[unsafe(no_mangle)]
91pub unsafe extern "C" fn diffsol_host_array_stride(array: *const HostArray, index: usize) -> usize {
92    if array.is_null() {
93        c_invalid_arg!("host array is null");
94        return 0;
95    }
96    let array = unsafe { &*array };
97    array.stride(index)
98}
99
100/// Return the scalar type enum stored by a host array.
101///
102/// # Safety
103/// `array` must be a valid pointer to a `HostArray` created by this library.
104#[unsafe(no_mangle)]
105pub unsafe extern "C" fn diffsol_host_array_dtype(array: *const HostArray) -> i32 {
106    if array.is_null() {
107        c_invalid_arg!("host array is null");
108        return -1;
109    }
110    let array = unsafe { &*array };
111    scalar_type_to_i32(array.dtype())
112}