//! Math types and traits
//!
//! ## Scalars
//!
//! - [`Positive`]
//! - [`NonNegative`]
//! - [`NonZero`]
//! - [`Normalized`]
//! - [`NormalSigned`]
//! - [`Unit`]
//! - [`Deg`]
//! - [`Rad`]
//! - [`Turn`]
//! - [`AngleWrapped`]
//! - [`AngleWrappedSigned`]
//!
//! ## Vectors & points
//!
//! - [`Vector2`]
//! - [`Vector3`]
//! - [`Vector4`]
//! - [`Point2`]
//! - [`Point3`]
//! - [`Point4`]
//! - [`Unit2`]
//! - [`Unit3`]
//! - [`Unit4`]
//! - [`NonZero2`]
//! - [`NonZero3`]
//! - [`NonZero4`]
//!
//! ## Matrices & linear transformations
//!
//! Matrices are *column-major* for SIMD efficiency.
//!
//! - [`Angles3`]
//! - [`Matrix2`]
//! - [`Matrix3`]
//! - [`Matrix4`]
//! - [`LinearIso`]
//! - [`LinearAuto`]
//! - [`Rotation2`]
//! - [`Rotation3`]
//! - [`Quaternion`]
//! - [`Versor`]
//!
//! ## Affine transformations and frames
//!
//! - [`Pose3`]
//! - [`AffineMap`]
//! - [`Affinity`]
//! - [`Projectivity`]
//! - [`frame::Line2`]
//! - [`frame::Plane2`]
//! - [`frame::Line3`]
//! - [`frame::Plane3`]
//! - [`frame::Space3`]

#![feature(decl_macro)]
#![feature(stmt_expr_attributes)]
#![cfg_attr(test, feature(test))]

pub use vek::approx;
pub use vek::num_traits as num;
pub use vek;

pub mod data;
pub mod geometry;
pub mod algebra;

mod fixed;
mod traits;
mod types;

pub use self::fixed::*;
pub use self::traits::*;
pub use self::types::*;

/// 0
pub const COMPONENT_INDEX_X : usize = 0;
/// 1
pub const COMPONENT_INDEX_Y : usize = 1;
/// 2
pub const COMPONENT_INDEX_Z : usize = 2;
/// 3
pub const COMPONENT_INDEX_W : usize = 3;


/// Convenience macro
#[doc(hidden)]
#[macro_export]
macro_rules! show {
  ($e:expr) => { println!("{}: {:?}", stringify!($e), $e); }
}

/// Convenience macro
#[doc(hidden)]
#[macro_export]
macro_rules! display {
  ($e:expr) => { println!("{}: {}", stringify!($e), $e); }
}

/// Print the sizes of some types
pub fn report_sizes() {
  use std::mem::size_of;
  println!("report sizes...");
  show!(size_of::<Vector2 <f32>>());
  show!(size_of::<Vector3 <f32>>());
  show!(size_of::<Vector4 <f32>>());
  show!(size_of::<Matrix2 <f32>>());
  show!(size_of::<Matrix3 <f32>>());
  show!(size_of::<Rotation2 <f32>>());
  show!(size_of::<Rotation3 <f32>>());
  show!(size_of::<AffineMap <f32, Point3 <f32>, Point3 <f32>, Matrix3 <f32>>>());
  show!(size_of::<AffineMap <f32, Point4 <f32>, Point4 <f32>, Matrix4 <f32>>>());
  println!("...report sizes");
}
