#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Default)]
pub struct Complex<F> {
pub re: F,
pub im: F,
}
impl<F> Complex<F> {
pub const fn new(re: F, im: F) -> Self {
Complex { re, im }
}
}
impl<F: Copy> Complex<F> {
pub const fn re(self) -> F {
self.re
}
pub const fn im(self) -> F {
self.im
}
}
pub type Complex64 = Complex<f64>;
pub type Complex32 = Complex<f32>;
#[cfg(test)]
mod tests {
use super::*;
use std::convert::TryInto;
#[test]
fn layout_matches_c_complex_double() {
assert_eq!(std::mem::size_of::<Complex64>(), 16);
assert_eq!(
std::mem::align_of::<Complex64>(),
std::mem::align_of::<f64>()
);
let z = Complex64::new(1.0, 2.0);
let bytes: [u8; 16] = unsafe { std::mem::transmute(z) };
let re_back = f64::from_le_bytes(bytes[..8].try_into().unwrap());
let im_back = f64::from_le_bytes(bytes[8..].try_into().unwrap());
assert_eq!(re_back, 1.0);
assert_eq!(im_back, 2.0);
}
#[test]
fn layout_matches_c_complex_float() {
assert_eq!(std::mem::size_of::<Complex32>(), 8);
assert_eq!(
std::mem::align_of::<Complex32>(),
std::mem::align_of::<f32>()
);
}
}