use std::cmp::Ordering;
use std::convert::TryInto;
use std::mem;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
pub type HilbertIndex = moore_hilbert_sys::BitmaskT;
pub type HilbertCoordinate = u64;
pub type BitsPerDimensionType = usize;
const BITS_PER_BYTE: usize = 8;
pub fn coordinates_to_index(
bits_per_dimension: BitsPerDimensionType,
coords: &[HilbertCoordinate],
) -> Result<HilbertIndex, ()> {
if bits_per_dimension * coords.len() > mem::size_of::<HilbertIndex>() * BITS_PER_BYTE {
panic!("number of coordinates * bits_per_dimension > sizeof(HilbertIndex) * BITS_PER_BYTE");
}
unsafe {
return Ok(moore_hilbert_sys::hilbert_c2i(
coords.len().try_into().unwrap(),
bits_per_dimension.try_into().unwrap(),
coords.as_ptr(),
));
}
}
pub fn index_to_coordinates(
bits_per_dimension: BitsPerDimensionType,
index: HilbertIndex,
coords: &mut [HilbertCoordinate],
) -> () {
if bits_per_dimension as usize * coords.len() > mem::size_of::<HilbertIndex>() * BITS_PER_BYTE {
panic!("number of coordinates * bits_per_dimension > mem::size_of(HilbertIndex) * BITS_PER_BYTE");
}
unsafe {
return moore_hilbert_sys::hilbert_i2c(
coords.len().try_into().unwrap(),
bits_per_dimension.try_into().unwrap(),
index,
coords.as_mut_ptr(),
);
}
}
pub fn hilbert_cmp(
bits_per_dimension: BitsPerDimensionType,
coord1: &[HilbertCoordinate],
coord2: &[HilbertCoordinate],
) -> Ordering {
if bits_per_dimension as usize > mem::size_of::<HilbertIndex>() * BITS_PER_BYTE {
panic!("bits_per_dimension > mem::size_of::<HilbertIndex>() * BITS_PER_BYTE");
}
if coord1.len() != coord2.len() {
panic!("Coordinates supplied are not equal in length");
}
unsafe {
let r = moore_hilbert_sys::hilbert_cmp(
coord1.len().try_into().unwrap(),
mem::size_of::<HilbertCoordinate>().try_into().unwrap(),
bits_per_dimension.try_into().unwrap(),
coord1.as_ptr() as *const std::ffi::c_void,
coord2.as_ptr() as *const std::ffi::c_void,
);
if r == -1 {
return Ordering::Less;
}
if r == 0 {
return Ordering::Equal;
}
return Ordering::Greater;
}
}
pub fn hilbert_ieee_cmp(coord1: &[f64], coord2: &[f64]) -> Ordering {
if coord1.len() != coord2.len() {
panic!("Coordinates supplied are not equal in length");
}
unsafe {
let r = moore_hilbert_sys::hilbert_ieee_cmp(
coord1.len().try_into().unwrap(),
coord1.as_ptr(),
coord2.as_ptr(),
);
if r == -1 {
return Ordering::Less;
}
if r == 0 {
return Ordering::Equal;
}
return Ordering::Greater;
}
}
pub fn hilbert_incr(
bits_per_dimension: BitsPerDimensionType,
coord: &mut [HilbertCoordinate],
) -> () {
if bits_per_dimension as usize > mem::size_of::<HilbertIndex>() * BITS_PER_BYTE {
panic!("bits_per_dimension > mem::size_of::<HilbertIndex>() * BITS_PER_BYTE");
}
unsafe {
moore_hilbert_sys::hilbert_incr(
coord.len().try_into().unwrap(),
bits_per_dimension.try_into().unwrap(),
coord.as_mut_ptr(),
);
}
}
pub fn hilbert_box_vtx(
bits_per_dimension: BitsPerDimensionType,
find_min: bool,
coord1: &mut [HilbertCoordinate],
coord2: &mut [HilbertCoordinate],
) -> usize {
if coord1.len() != coord2.len() {
panic!("Coordinates supplied are not equal in length");
}
if bits_per_dimension as usize > mem::size_of::<HilbertIndex>() * BITS_PER_BYTE {
panic!("bits_per_dimension > mem::size_of::<HilbertIndex>() * BITS_PER_BYTE");
}
unsafe {
return moore_hilbert_sys::hilbert_box_vtx(
coord1.len().try_into().unwrap(),
mem::size_of::<HilbertCoordinate>().try_into().unwrap(),
bits_per_dimension.try_into().unwrap(),
if find_min { 1 } else { 0 },
coord1.as_ptr() as *mut std::ffi::c_void,
coord2.as_ptr() as *mut std::ffi::c_void,
) as usize;
}
}
pub fn hilbert_ieee_box_vtx(find_min: bool, coord1: &mut [f64], coord2: &mut [f64]) -> usize {
if coord1.len() != coord2.len() {
panic!("Coordinates supplied are not equal in length");
}
unsafe {
return moore_hilbert_sys::hilbert_ieee_box_vtx(
coord1.len().try_into().unwrap(),
if find_min { 1 } else { 0 },
coord1.as_mut_ptr(),
coord2.as_mut_ptr(),
) as usize;
}
}
pub fn hilbert_box_pt(
bits_per_dimension: BitsPerDimensionType,
find_min: bool,
coord1: &mut [HilbertCoordinate],
coord2: &mut [HilbertCoordinate],
) -> usize {
if coord1.len() != coord2.len() {
panic!("Coordinates supplied are not equal in length");
}
unsafe {
return moore_hilbert_sys::hilbert_box_pt(
coord1.len().try_into().unwrap(),
mem::size_of::<HilbertCoordinate>().try_into().unwrap(),
bits_per_dimension.try_into().unwrap(),
if find_min { 1 } else { 0 },
coord1.as_mut_ptr() as *mut std::ffi::c_void,
coord2.as_mut_ptr() as *mut std::ffi::c_void,
) as usize;
}
}
pub fn hilbert_ieee_box_pt(find_min: bool, coord1: &mut [f64], coord2: &mut [f64]) -> usize {
if coord1.len() != coord2.len() {
panic!("Coordinates supplied are not equal in length");
}
unsafe {
return moore_hilbert_sys::hilbert_ieee_box_pt(
coord1.len().try_into().unwrap(),
if find_min { 1 } else { 0 },
coord1.as_mut_ptr(),
coord2.as_mut_ptr(),
) as usize;
}
}
pub fn hilbert_nextinbox(
bits_per_dimension: BitsPerDimensionType,
find_prev: bool,
coord1: &mut [HilbertCoordinate],
coord2: &mut [HilbertCoordinate],
point: &[HilbertCoordinate],
) -> bool {
if coord1.len() != coord2.len() {
panic!("Coordinates supplied are not equal in length");
}
if point.len() != coord1.len() {
panic!("Coordinates supplied are not equal in length to the point supplied");
}
unsafe {
if moore_hilbert_sys::hilbert_nextinbox(
coord1.len().try_into().unwrap(),
mem::size_of::<HilbertCoordinate>().try_into().unwrap(),
bits_per_dimension.try_into().unwrap(),
if find_prev { 1 } else { 0 },
coord1.as_mut_ptr() as *mut std::ffi::c_void,
coord2.as_mut_ptr() as *mut std::ffi::c_void,
point.as_ptr() as *mut std::ffi::c_void,
) == 1
{
true
} else {
false
}
}
}