#![cfg_attr(feature = "unstable", feature(test, core_intrinsics, trace_macros))]

#[macro_use]
extern crate gut_derive;

#[macro_use]
pub mod index;

pub mod bbox;
pub mod interval;
pub mod ops;
pub mod prim;

pub mod algo;
pub mod mesh;

#[cfg(feature = "io")]
pub mod io;

pub(crate) mod utils {
    #[cfg(feature = "rayon")]
    pub mod chashset;
    pub mod math;
    pub mod slice;
}

// public re-exports
pub use self::index::Index;
pub use crate::mesh::topology::*;

/// Plain old data trait. Types that implement this trait contain no references and can be copied
/// with `memcpy`. The additional `Any` trait lets us inspect the type more easily.
pub trait Pod: 'static + Copy + Sized + Send + Sync + std::any::Any {}
impl<T> Pod for T where T: 'static + Copy + Sized + Send + Sync + std::any::Any {}

pub trait Real:
    math::BaseNum + math::BaseFloat + num_traits::Float + ::std::fmt::Debug + std::iter::Sum + Pod
{
}
impl<T> Real for T where
    T: math::BaseNum
        + math::BaseFloat
        + num_traits::Float
        + ::std::fmt::Debug
        + std::iter::Sum
        + Pod
{
}

// Temporary utils to wrap unsafe reinterpret casts into a safe API.
pub(crate) fn index_vec_into_usize(vec: Vec<Index>) -> Vec<usize> {
    // SAFETY: Index is transparent and has exactly the same size and data representation as usize.
    unsafe { reinterpret::reinterpret_vec(vec) }
}

pub(crate) fn into_flat_vec3(vec: Vec<[usize; 3]>) -> Vec<usize> {
    // SAFETY: A continguous vec of [usize; 3] can be reinterpreted as a contiguous vec of usize
    unsafe { reinterpret::reinterpret_vec(vec) }
}

pub(crate) fn into_flat_vec4(vec: Vec<[usize; 4]>) -> Vec<usize> {
    // SAFETY: A continguous vec of [usize; 4] can be reinterpreted as a contiguous vec of usize
    unsafe { reinterpret::reinterpret_vec(vec) }
}
