I have complex number data filled into a Vec<f64>
by an external C library (prefer not to change) in the form [i_0_real, i_0_imag, i_1_real, i_1_imag, ...]
and it appears that this Vec<f64>
has the same memory layout as a Vec<num_complex::Complex<f64>>
of half the length would be, given that num_complex::Complex<f64>
's data structure is memory-layout compatible with [f64; 2]
as documented here. I'd like to use it as such without needing a re-allocation of a potentially large buffer.
I'm assuming that it's valid to use from_raw_parts()
in std::vec::Vec
to fake a new Vec
that takes ownership of the old Vec
's memory (by forgetting the old Vec
) and use size / 2
and capacity / 2
, but that requires unsafe code. Is there a "safe" way to do this kind of data re-interpretation?
The Vec
is allocated in Rust as a Vec<f64>
and is populated by a C function using .as_mut_ptr()
that fills in the Vec<f64>
.
My current compiling unsafe implementation:
extern crate num_complex;
pub fn convert_to_complex_unsafe(mut buffer: Vec<f64>) -> Vec<num_complex::Complex<f64>> {
let new_vec = unsafe {
Vec::from_raw_parts(
buffer.as_mut_ptr() as *mut num_complex::Complex<f64>,
buffer.len() / 2,
buffer.capacity() / 2,
)
};
std::mem::forget(buffer);
return new_vec;
}
fn main() {
println!(
"Converted vector: {:?}",
convert_to_complex_unsafe(vec![3.0, 4.0, 5.0, 6.0])
);
}
f64
is not a complex in C – Lysimachus