Skip to content

Commit eb75034

Browse files
authored
Merge pull request #210 from mulimoen/feature/complex
Implement H5Type for complex
2 parents fd4ea35 + 6031bb8 commit eb75034

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- Add a `ByteReader` which implements `std::io::{Read, Seek}` for 1D `u8`
1111
datasets. Usage via `Dataset::as_byte_reader()`.
1212
- Add `chunk_visit` to visit all chunks in a dataset.
13+
- Implement `H5Type` for `num_complex::Complex`.
1314

1415
### Changed
1516

hdf5-types/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ edition.workspace = true
1515

1616
[features]
1717
h5-alloc = []
18+
complex = ["num-complex"]
1819

1920
[dependencies]
2021
ascii = "1.1"
2122
cfg-if = { workspace = true }
2223
hdf5-sys = { workspace = true }
2324
libc = { workspace = true }
25+
num-complex = { version = "0.4", optional = true, default-features = false }
2426

2527
[dev-dependencies]
2628
quickcheck = { version = "1.0", default-features = false }

hdf5-types/src/complex.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use super::{CompoundField, CompoundType, H5Type, TypeDescriptor};
2+
3+
use std::mem::size_of;
4+
5+
use num_complex::Complex;
6+
7+
unsafe impl<T: H5Type> H5Type for Complex<T> {
8+
fn type_descriptor() -> TypeDescriptor {
9+
// Complex<T> should be FFI-equivalent to [T; 2]
10+
// https://docs.rs/num-complex/0.4.3/num_complex/struct.Complex.html#representation-and-foreign-function-interface-compatibility
11+
TypeDescriptor::Compound(CompoundType {
12+
fields: vec![
13+
// Compatible with h5py definition of complex
14+
CompoundField::typed::<T>("r", 0, 0),
15+
CompoundField::typed::<T>("i", size_of::<T>(), 1),
16+
],
17+
size: size_of::<T>() * 2,
18+
})
19+
}
20+
}
21+
22+
#[cfg(test)]
23+
mod tests {
24+
use super::*;
25+
use num_complex::{Complex32, Complex64};
26+
use std::mem::size_of_val;
27+
28+
#[test]
29+
fn complex() {
30+
assert_eq!(Complex32::type_descriptor().size(), 8);
31+
assert_eq!(Complex32::type_descriptor().size(), size_of::<Complex32>());
32+
assert_eq!(Complex64::type_descriptor().size(), 16);
33+
assert_eq!(Complex64::type_descriptor().size(), size_of::<Complex64>());
34+
}
35+
36+
#[test]
37+
fn alignment() {
38+
use std::ptr::addr_of;
39+
40+
let a = Complex { re: 0.0, im: 1.0 };
41+
42+
assert_eq!(size_of_val(&a), size_of_val(&a.re) + size_of_val(&a.im));
43+
assert_eq!(size_of_val(&a.re), size_of_val(&a.im));
44+
45+
let base: *const u8 = addr_of!(a).cast::<u8>();
46+
let ptr_r = addr_of!(a.re).cast::<u8>();
47+
let ptr_i = addr_of!(a.im).cast::<u8>();
48+
49+
assert_eq!(unsafe { ptr_r.offset_from(base) }, 0);
50+
assert_eq!(unsafe { ptr_i.offset_from(base) }, size_of_val(&a.re) as isize);
51+
}
52+
}

hdf5-types/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ pub mod dyn_value;
2222
mod h5type;
2323
mod string;
2424

25+
#[cfg(feature = "complex")]
26+
mod complex;
27+
2528
pub use self::array::VarLenArray;
2629
pub use self::dyn_value::{DynValue, OwnedDynValue};
2730
pub use self::h5type::{

0 commit comments

Comments
 (0)