Implement Arbitrary for (almost) all types
Rot4 and Iso4 had to be left out, since Rot4 apparently lacks a working constructor. Thereby (almost) all types in nalgebra can now be used for quickcheck-style testing. "arbitrary" is now a conditionally compiled feature that contains these impls adding a dependency on quickcheck.
This commit is contained in:
parent
dc7a85ccde
commit
1103996b83
@ -15,5 +15,12 @@ license = "BSD-3-Clause"
|
||||
name = "nalgebra"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[features]
|
||||
# Generate arbitrary instances of nalgebra types for testing with quickcheck
|
||||
arbitrary = ["quickcheck"]
|
||||
|
||||
[dependencies]
|
||||
rustc-serialize = "*"
|
||||
|
||||
[dependencies.quickcheck]
|
||||
optional = true
|
||||
|
@ -89,6 +89,9 @@ Feel free to add your project to this list if you happen to use **nalgebra**!
|
||||
|
||||
extern crate "rustc-serialize" as rustc_serialize;
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
extern crate quickcheck;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate test;
|
||||
|
||||
|
@ -13,6 +13,8 @@ use structs::dvec::DVec;
|
||||
use traits::operations::{Inv, Transpose, Mean, Cov};
|
||||
use traits::structure::{Cast, ColSlice, RowSlice, Diag, Eye, Indexable, Shape, Zero, One, BaseNum};
|
||||
use std::fmt::{Show, Formatter, Result, String};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Matrix with dimensions unknown at compile-time.
|
||||
@ -703,3 +705,13 @@ impl<N: Copy + Sub<N, Output = N>> Sub<N> for DMat<N> {
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary> Arbitrary for DMat<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> DMat<N> {
|
||||
DMat::from_fn(
|
||||
Arbitrary::arbitrary(g), Arbitrary::arbitrary(g),
|
||||
|_, _| Arbitrary::arbitrary(g)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
||||
use traits::operations::{ApproxEq, Axpy};
|
||||
use traits::geometry::{Dot, Norm};
|
||||
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Zero, One};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
/// Heap allocated, dynamically sized vector.
|
||||
#[derive(Eq, PartialEq, Show, Clone)]
|
||||
@ -78,6 +80,13 @@ impl<N> FromIterator<N> for DVec<N> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary> Arbitrary for DVec<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> DVec<N> {
|
||||
DVec { at: Arbitrary::arbitrary(g) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dvec_impl!(DVec);
|
||||
|
||||
|
@ -520,5 +520,13 @@ macro_rules! small_dvec_from_impl (
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Zero> Arbitrary for $dvec<N> {
|
||||
#[inline]
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $dvec<N> {
|
||||
$dvec::from_fn(g.gen_range(0, $dim), |_| Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -15,6 +15,9 @@ use structs::vec::{Vec1, Vec2, Vec3, Vec4};
|
||||
use structs::pnt::{Pnt2, Pnt3, Pnt4};
|
||||
use structs::rot::{Rot2, Rot3, Rot4};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Two dimensional isometry.
|
||||
///
|
||||
@ -112,6 +115,7 @@ translate_impl!(Iso2, Pnt2);
|
||||
iso_mul_iso_impl!(Iso2);
|
||||
iso_mul_pnt_impl!(Iso2, Pnt2);
|
||||
pnt_mul_iso_impl!(Iso2, Pnt2);
|
||||
arbitrary_iso_impl!(Iso2);
|
||||
|
||||
iso_impl!(Iso3, Rot3, Vec3, Vec3);
|
||||
rotation_matrix_impl!(Iso3, Rot3, Vec3, Vec3);
|
||||
@ -131,6 +135,7 @@ translate_impl!(Iso3, Pnt3);
|
||||
iso_mul_iso_impl!(Iso3);
|
||||
iso_mul_pnt_impl!(Iso3, Pnt3);
|
||||
pnt_mul_iso_impl!(Iso3, Pnt3);
|
||||
arbitrary_iso_impl!(Iso3);
|
||||
|
||||
// iso_impl!(Iso4, Rot4, Vec4, Vec4);
|
||||
// rotation_matrix_impl!(Iso4, Rot4, Vec4, Vec4);
|
||||
@ -150,3 +155,5 @@ translate_impl!(Iso4, Pnt4);
|
||||
iso_mul_iso_impl!(Iso4);
|
||||
iso_mul_pnt_impl!(Iso4, Pnt4);
|
||||
pnt_mul_iso_impl!(Iso4, Pnt4);
|
||||
// FIXME: as soon as Rot4<N>: Arbitrary
|
||||
// arbitrary_iso_impl!(Iso4);
|
||||
|
@ -364,3 +364,17 @@ macro_rules! absolute_rotate_impl(
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! arbitrary_iso_impl(
|
||||
($t: ident) => (
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
Arbitrary::arbitrary(g),
|
||||
Arbitrary::arbitrary(g)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -15,6 +15,8 @@ use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable,
|
||||
use traits::operations::{Absolute, Transpose, Inv, Outer, EigenQR};
|
||||
use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig};
|
||||
use linalg;
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Special identity matrix. All its operation are no-ops.
|
||||
@ -72,6 +74,7 @@ to_homogeneous_impl!(Mat1, Mat2, 1, 2);
|
||||
from_homogeneous_impl!(Mat1, Mat2, 1, 2);
|
||||
outer_impl!(Vec1, Mat1);
|
||||
eigen_qr_impl!(Mat1, Vec1);
|
||||
arbitrary_impl!(Mat1, m11);
|
||||
|
||||
/// Square matrix of dimension 2.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -120,6 +123,7 @@ to_homogeneous_impl!(Mat2, Mat3, 2, 3);
|
||||
from_homogeneous_impl!(Mat2, Mat3, 2, 3);
|
||||
outer_impl!(Vec2, Mat2);
|
||||
eigen_qr_impl!(Mat2, Vec2);
|
||||
arbitrary_impl!(Mat2, m11, m12, m21, m22);
|
||||
|
||||
/// Square matrix of dimension 3.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -202,6 +206,11 @@ to_homogeneous_impl!(Mat3, Mat4, 3, 4);
|
||||
from_homogeneous_impl!(Mat3, Mat4, 3, 4);
|
||||
outer_impl!(Vec3, Mat3);
|
||||
eigen_qr_impl!(Mat3, Vec3);
|
||||
arbitrary_impl!(Mat3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
|
||||
/// Square matrix of dimension 4.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -302,6 +311,12 @@ to_homogeneous_impl!(Mat4, Mat5, 4, 5);
|
||||
from_homogeneous_impl!(Mat4, Mat5, 4, 5);
|
||||
outer_impl!(Vec4, Mat4);
|
||||
eigen_qr_impl!(Mat4, Vec4);
|
||||
arbitrary_impl!(Mat4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
|
||||
/// Square matrix of dimension 5.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -416,6 +431,13 @@ to_homogeneous_impl!(Mat5, Mat6, 5, 6);
|
||||
from_homogeneous_impl!(Mat5, Mat6, 5, 6);
|
||||
outer_impl!(Vec5, Mat5);
|
||||
eigen_qr_impl!(Mat5, Vec5);
|
||||
arbitrary_impl!(Mat5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
|
||||
/// Square matrix of dimension 6.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -532,3 +554,11 @@ row_slice_impl!(Mat6, Vec6, DVec6, 6);
|
||||
diag_impl!(Mat6, Vec6, 6);
|
||||
outer_impl!(Vec6, Mat6);
|
||||
eigen_qr_impl!(Mat6, Vec6);
|
||||
arbitrary_impl!(Mat6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
m41, m42, m43, m44, m45, m46,
|
||||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
|
@ -2,6 +2,10 @@ use std::num;
|
||||
use traits::structure::BaseFloat;
|
||||
use structs::{Pnt3, Vec3, Mat4};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// A 3D orthographic projection stored without any matrix.
|
||||
///
|
||||
/// Reading or modifying its individual properties is cheap but applying the transformation is costly.
|
||||
@ -47,6 +51,17 @@ impl<N: BaseFloat> Ortho3<N> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for Ortho3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Ortho3<N> {
|
||||
let width = reject(g, |x| !::is_zero(x));
|
||||
let height = reject(g, |x| !::is_zero(x));
|
||||
let znear = Arbitrary::arbitrary(g);
|
||||
let zfar = reject(g, |&x: &N| !::is_zero(&(x - znear)));
|
||||
Ortho3::new(width, height, znear, zfar)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + Clone> Ortho3<N> {
|
||||
/// The width of the view cuboid.
|
||||
#[inline]
|
||||
@ -232,3 +247,20 @@ impl<N: BaseFloat + Clone> OrthoMat3<N> {
|
||||
self.mat.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for OrthoMat3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> OrthoMat3<N> {
|
||||
let x: Ortho3<N> = Arbitrary::arbitrary(g);
|
||||
x.to_persp_mat()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Simple helper function for rejection sampling
|
||||
#[cfg(feature="arbitrary")]
|
||||
#[inline]
|
||||
pub fn reject<G: Gen, F: FnMut(&T) -> bool, T: Arbitrary>(g: &mut G, f: F) -> T {
|
||||
use std::iter::repeat;
|
||||
repeat(()).map(|_| Arbitrary::arbitrary(g)).filter(f).next().unwrap()
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
use traits::structure::BaseFloat;
|
||||
use structs::{Pnt3, Vec3, Mat4};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// A 3D perspective projection stored without any matrix.
|
||||
///
|
||||
/// Reading or modifying its individual properties is cheap but applying the transformation is costly.
|
||||
@ -45,6 +49,16 @@ impl<N: BaseFloat> Persp3<N> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for Persp3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Persp3<N> {
|
||||
use structs::ortho::reject;
|
||||
let znear = Arbitrary::arbitrary(g);
|
||||
let zfar = reject(g, |&x: &N| !::is_zero(&(x - znear)));
|
||||
Persp3::new(Arbitrary::arbitrary(g), Arbitrary::arbitrary(g), znear, zfar)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + Clone> Persp3<N> {
|
||||
/// Gets the `width / height` aspect ratio.
|
||||
#[inline]
|
||||
@ -263,3 +277,11 @@ impl<N: BaseFloat + Clone> PerspMat3<N> {
|
||||
self.mat.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for PerspMat3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> PerspMat3<N> {
|
||||
let x: Persp3<N> = Arbitrary::arbitrary(g);
|
||||
x.to_persp_mat()
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, S
|
||||
NumPnt, FloatPnt, BaseFloat, BaseNum, Zero, One, Bounded};
|
||||
use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous};
|
||||
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Point of dimension 0.
|
||||
@ -69,6 +71,7 @@ iterable_mut_impl!(Pnt1, 1);
|
||||
pnt_to_homogeneous_impl!(Pnt1, Pnt2, y, x);
|
||||
pnt_from_homogeneous_impl!(Pnt1, Pnt2, y, x);
|
||||
num_float_pnt_impl!(Pnt1, Vec1);
|
||||
arbitrary_pnt_impl!(Pnt1, x);
|
||||
|
||||
/// Point of dimension 2.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -109,6 +112,7 @@ iterable_mut_impl!(Pnt2, 2);
|
||||
pnt_to_homogeneous_impl!(Pnt2, Pnt3, z, x, y);
|
||||
pnt_from_homogeneous_impl!(Pnt2, Pnt3, z, x, y);
|
||||
num_float_pnt_impl!(Pnt2, Vec2);
|
||||
arbitrary_pnt_impl!(Pnt2, x, y);
|
||||
|
||||
/// Point of dimension 3.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -151,6 +155,7 @@ iterable_mut_impl!(Pnt3, 3);
|
||||
pnt_to_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z);
|
||||
pnt_from_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z);
|
||||
num_float_pnt_impl!(Pnt3, Vec3);
|
||||
arbitrary_pnt_impl!(Pnt3, x, y, z);
|
||||
|
||||
/// Point of dimension 4.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -195,6 +200,7 @@ iterable_mut_impl!(Pnt4, 4);
|
||||
pnt_to_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w);
|
||||
pnt_from_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w);
|
||||
num_float_pnt_impl!(Pnt4, Vec4);
|
||||
arbitrary_pnt_impl!(Pnt4, x, y, z, w);
|
||||
|
||||
/// Point of dimension 5.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -241,6 +247,7 @@ iterable_mut_impl!(Pnt5, 5);
|
||||
pnt_to_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a);
|
||||
pnt_from_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a);
|
||||
num_float_pnt_impl!(Pnt5, Vec5);
|
||||
arbitrary_pnt_impl!(Pnt5, x, y, z, w, a);
|
||||
|
||||
/// Point of dimension 6.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -287,3 +294,4 @@ axpy_impl!(Pnt6, x, y, z, w, a, b);
|
||||
iterable_impl!(Pnt6, 6);
|
||||
iterable_mut_impl!(Pnt6, 6);
|
||||
num_float_pnt_impl!(Pnt6, Vec6);
|
||||
arbitrary_pnt_impl!(Pnt6, x, y, z, w, a, b);
|
||||
|
@ -141,3 +141,17 @@ macro_rules! num_float_pnt_impl(
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! arbitrary_pnt_impl(
|
||||
($t: ident, $($compN: ident),*) => (
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary> Arbitrary for $t<N> {
|
||||
#[inline]
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
|
||||
$t {
|
||||
$($compN: Arbitrary::arbitrary(g),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -15,6 +15,10 @@ use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, Base
|
||||
One, Bounded};
|
||||
use traits::geometry::{Norm, Rotation, Rotate, Transform};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// A quaternion.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
pub struct Quat<N> {
|
||||
@ -146,6 +150,7 @@ impl<N: ApproxEq<N> + BaseFloat> Div<Quat<N>> for Quat<N> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A unit quaternion that can represent a 3D rotation.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Show, Copy)]
|
||||
pub struct UnitQuat<N> {
|
||||
@ -470,6 +475,14 @@ impl<N: BaseNum> Transform<Pnt3<N>> for UnitQuat<N> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuat<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> UnitQuat<N> {
|
||||
UnitQuat::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ord_impl!(Quat, w, i, j, k);
|
||||
vec_axis_impl!(Quat, w, i, j, k);
|
||||
vec_cast_impl!(Quat, w, i, j, k);
|
||||
@ -495,5 +508,6 @@ bounded_impl!(Quat, w, i, j, k);
|
||||
axpy_impl!(Quat, w, i, j, k);
|
||||
iterable_impl!(Quat, 4);
|
||||
iterable_mut_impl!(Quat, 4);
|
||||
arbitrary_impl!(Quat, w, i, j, k);
|
||||
|
||||
dim_impl!(UnitQuat, 3);
|
||||
|
@ -11,6 +11,8 @@ use traits::operations::{Absolute, Inv, Transpose, ApproxEq};
|
||||
use structs::vec::{Vec1, Vec2, Vec3, Vec4};
|
||||
use structs::pnt::{Pnt2, Pnt3, Pnt4};
|
||||
use structs::mat::{Mat2, Mat3, Mat4, Mat5};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Two dimensional rotation matrix.
|
||||
@ -19,13 +21,13 @@ pub struct Rot2<N> {
|
||||
submat: Mat2<N>
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat + Neg<Output = N> + Copy> Rot2<N> {
|
||||
impl<N: Clone + BaseFloat + Neg<Output = N>> Rot2<N> {
|
||||
/// Builds a 2 dimensional rotation matrix from an angle in radian.
|
||||
pub fn new(angle: Vec1<N>) -> Rot2<N> {
|
||||
let (sia, coa) = angle.x.sin_cos();
|
||||
|
||||
Rot2 {
|
||||
submat: Mat2::new(coa.clone(), -sia, sia.clone(), coa)
|
||||
submat: Mat2::new(coa.clone(), -sia, sia, coa)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,6 +89,14 @@ impl<N: BaseFloat> AbsoluteRotate<Vec2<N>> for Rot2<N> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Clone + BaseFloat + Neg<Output = N>> Arbitrary for Rot2<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Rot2<N> {
|
||||
Rot2::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 3d rotation
|
||||
*/
|
||||
@ -287,6 +297,14 @@ impl<N: BaseFloat> AbsoluteRotate<Vec3<N>> for Rot3<N> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Clone + BaseFloat> Arbitrary for Rot3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Rot3<N> {
|
||||
Rot3::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Four dimensional rotation matrix.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Show, Hash, Copy)]
|
||||
pub struct Rot4<N> {
|
||||
|
@ -14,6 +14,9 @@ use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, VecA
|
||||
NumVec, FloatVec, BaseFloat, BaseNum, Zero, One, Bounded};
|
||||
use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Vector of dimension 0.
|
||||
#[derive(Eq, PartialEq, RustcDecodable, Clone, Rand, Show, Copy)]
|
||||
@ -81,6 +84,7 @@ transform_impl!(Vec1, Pnt1);
|
||||
vec_as_pnt_impl!(Vec1, Pnt1, x);
|
||||
num_float_vec_impl!(Vec1);
|
||||
absolute_vec_impl!(Vec1, x);
|
||||
arbitrary_impl!(Vec1, x);
|
||||
|
||||
/// Vector of dimension 2.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -132,6 +136,7 @@ transform_impl!(Vec2, Pnt2);
|
||||
vec_as_pnt_impl!(Vec2, Pnt2, x, y);
|
||||
num_float_vec_impl!(Vec2);
|
||||
absolute_vec_impl!(Vec2, x, y);
|
||||
arbitrary_impl!(Vec2, x, y);
|
||||
|
||||
/// Vector of dimension 3.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -185,6 +190,7 @@ transform_impl!(Vec3, Pnt3);
|
||||
vec_as_pnt_impl!(Vec3, Pnt3, x, y, z);
|
||||
num_float_vec_impl!(Vec3);
|
||||
absolute_vec_impl!(Vec3, x, y, z);
|
||||
arbitrary_impl!(Vec3, x, y, z);
|
||||
|
||||
|
||||
/// Vector of dimension 4.
|
||||
@ -241,6 +247,7 @@ transform_impl!(Vec4, Pnt4);
|
||||
vec_as_pnt_impl!(Vec4, Pnt4, x, y, z, w);
|
||||
num_float_vec_impl!(Vec4);
|
||||
absolute_vec_impl!(Vec4, x, y, z, w);
|
||||
arbitrary_impl!(Vec4, x, y, z, w);
|
||||
|
||||
/// Vector of dimension 5.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -298,6 +305,7 @@ transform_impl!(Vec5, Pnt5);
|
||||
vec_as_pnt_impl!(Vec5, Pnt5, x, y, z, w, a);
|
||||
num_float_vec_impl!(Vec5);
|
||||
absolute_vec_impl!(Vec5, x, y, z, w, a);
|
||||
arbitrary_impl!(Vec5, x, y, z, w, a);
|
||||
|
||||
/// Vector of dimension 6.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Rand, Show, Copy)]
|
||||
@ -355,3 +363,4 @@ transform_impl!(Vec6, Pnt6);
|
||||
vec_as_pnt_impl!(Vec6, Pnt6, x, y, z, w, a, b);
|
||||
num_float_vec_impl!(Vec6);
|
||||
absolute_vec_impl!(Vec6, x, y, z, w, a, b);
|
||||
arbitrary_impl!(Vec6, x, y, z, w, a, b);
|
||||
|
@ -844,3 +844,15 @@ macro_rules! absolute_vec_impl(
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! arbitrary_impl(
|
||||
($t: ident, $($compN: ident),*) => (
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary> Arbitrary for $t<N> {
|
||||
#[inline]
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
|
||||
$t { $($compN: Arbitrary::arbitrary(g),)* }
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
64
tests/arbitrary.rs
Normal file
64
tests/arbitrary.rs
Normal file
@ -0,0 +1,64 @@
|
||||
#![cfg(feature="arbitrary")]
|
||||
|
||||
extern crate "nalgebra" as na;
|
||||
extern crate quickcheck;
|
||||
|
||||
use std::rand;
|
||||
use quickcheck::{Arbitrary, StdGen};
|
||||
use na::*;
|
||||
|
||||
|
||||
macro_rules! trivial_arb_test(
|
||||
($t: ty, $name: ident) => (
|
||||
#[test]
|
||||
fn $name() {
|
||||
let mut g = StdGen::new(rand::thread_rng(), 100);
|
||||
let _: $t = Arbitrary::arbitrary(&mut g);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
trivial_arb_test!(Vec1<f64>, arb_vec1);
|
||||
trivial_arb_test!(Vec2<f64>, arb_vec2);
|
||||
trivial_arb_test!(Vec3<f64>, arb_vec3);
|
||||
trivial_arb_test!(Vec4<f64>, arb_vec4);
|
||||
trivial_arb_test!(Vec5<f64>, arb_vec5);
|
||||
trivial_arb_test!(Vec6<f64>, arb_vec6);
|
||||
|
||||
trivial_arb_test!(Pnt1<f64>, arb_pnt1);
|
||||
trivial_arb_test!(Pnt2<f64>, arb_pnt2);
|
||||
trivial_arb_test!(Pnt3<f64>, arb_pnt3);
|
||||
trivial_arb_test!(Pnt4<f64>, arb_pnt4);
|
||||
trivial_arb_test!(Pnt5<f64>, arb_pnt5);
|
||||
trivial_arb_test!(Pnt6<f64>, arb_pnt6);
|
||||
|
||||
trivial_arb_test!(Mat1<f64>, arb_mat1);
|
||||
trivial_arb_test!(Mat2<f64>, arb_mat2);
|
||||
trivial_arb_test!(Mat3<f64>, arb_mat3);
|
||||
trivial_arb_test!(Mat4<f64>, arb_mat4);
|
||||
trivial_arb_test!(Mat5<f64>, arb_mat5);
|
||||
trivial_arb_test!(Mat6<f64>, arb_mat6);
|
||||
|
||||
trivial_arb_test!(DVec1<f64>, arb_dvec1);
|
||||
trivial_arb_test!(DVec2<f64>, arb_dvec2);
|
||||
trivial_arb_test!(DVec3<f64>, arb_dvec3);
|
||||
trivial_arb_test!(DVec4<f64>, arb_dvec4);
|
||||
trivial_arb_test!(DVec5<f64>, arb_dvec5);
|
||||
trivial_arb_test!(DVec6<f64>, arb_dvec6);
|
||||
|
||||
trivial_arb_test!(DMat<f64>, arb_dmat);
|
||||
trivial_arb_test!(DVec<f64>, arb_dvec);
|
||||
|
||||
trivial_arb_test!(Quat<f64>, arb_quat);
|
||||
trivial_arb_test!(UnitQuat<f64>, arb_unit_quat);
|
||||
|
||||
trivial_arb_test!(Iso2<f64>, arb_iso2);
|
||||
trivial_arb_test!(Iso3<f64>, arb_iso3);
|
||||
|
||||
trivial_arb_test!(Rot2<f64>, arb_rot2);
|
||||
trivial_arb_test!(Rot3<f64>, arb_rot3);
|
||||
|
||||
trivial_arb_test!(Ortho3<f64>, arb_ortho3);
|
||||
trivial_arb_test!(OrthoMat3<f64>, arb_ortho_mat3);
|
||||
trivial_arb_test!(Persp3<f64>, arb_persp3);
|
||||
trivial_arb_test!(PerspMat3<f64>, arb_persp_mat3);
|
Loading…
Reference in New Issue
Block a user