Make array type parameters associated types
This commit is contained in:
parent
0584bcac64
commit
a434f18ba4
5 changed files with 53 additions and 20 deletions
31
src/array.rs
31
src/array.rs
|
@ -18,14 +18,19 @@ use std::ptr;
|
|||
use std::ops::*;
|
||||
|
||||
/// An array containing elements of type `Element`
|
||||
pub trait Array1<Element: Copy>: Index<usize, Output=Element> + IndexMut<usize, Output=Element> {
|
||||
pub trait Array1 where
|
||||
Self: Index<usize, Output = <Self as Array1>::Element>,
|
||||
Self: IndexMut<usize, Output = <Self as Array1>::Element>,
|
||||
{
|
||||
type Element: Copy;
|
||||
|
||||
/// Get the pointer to the first element of the array.
|
||||
fn ptr<'a>(&'a self) -> &'a Element {
|
||||
fn ptr<'a>(&'a self) -> &'a Self::Element {
|
||||
&self[0]
|
||||
}
|
||||
|
||||
/// Get a mutable pointer to the first element of the array.
|
||||
fn mut_ptr<'a>(&'a mut self) -> &'a mut Element {
|
||||
fn mut_ptr<'a>(&'a mut self) -> &'a mut Self::Element {
|
||||
&mut self[0]
|
||||
}
|
||||
|
||||
|
@ -38,21 +43,27 @@ pub trait Array1<Element: Copy>: Index<usize, Output=Element> + IndexMut<usize,
|
|||
|
||||
/// Replace an element in the array.
|
||||
#[inline]
|
||||
fn replace_elem(&mut self, i: usize, src: Element) -> Element {
|
||||
fn replace_elem(&mut self, i: usize, src: Self::Element) -> Self::Element {
|
||||
mem::replace(&mut self[i], src)
|
||||
}
|
||||
}
|
||||
|
||||
/// A column-major array
|
||||
pub trait Array2<Column: Array1<Element>+'static, Row: Array1<Element>, Element: Copy>:
|
||||
Index<usize, Output=Column> + IndexMut<usize, Output=Column> {
|
||||
pub trait Array2 where
|
||||
Self: Index<usize, Output = <Self as Array2>::Column>,
|
||||
Self: IndexMut<usize, Output = <Self as Array2>::Column>,
|
||||
{
|
||||
type Element: Copy;
|
||||
type Column: Array1<Element = Self::Element>;
|
||||
type Row: Array1<Element = Self::Element>;
|
||||
|
||||
/// Get the pointer to the first element of the array.
|
||||
fn ptr<'a>(&'a self) -> &'a Element {
|
||||
fn ptr<'a>(&'a self) -> &'a Self::Element {
|
||||
&self[0][0]
|
||||
}
|
||||
|
||||
/// Get a mutable pointer to the first element of the array.
|
||||
fn mut_ptr<'a>(&'a mut self) -> &'a mut Element {
|
||||
fn mut_ptr<'a>(&'a mut self) -> &'a mut Self::Element {
|
||||
&mut self[0][0]
|
||||
}
|
||||
|
||||
|
@ -64,12 +75,12 @@ pub trait Array2<Column: Array1<Element>+'static, Row: Array1<Element>, Element:
|
|||
|
||||
/// Replace a column in the array.
|
||||
#[inline]
|
||||
fn replace_col(&mut self, c: usize, src: Column) -> Column {
|
||||
fn replace_col(&mut self, c: usize, src: Self::Column) -> Self::Column {
|
||||
mem::replace(&mut self[c], src)
|
||||
}
|
||||
|
||||
/// Get a row from this array by-value.
|
||||
fn row(&self, r: usize) -> Row;
|
||||
fn row(&self, r: usize) -> Self::Row;
|
||||
|
||||
/// Swap two rows of this array.
|
||||
fn swap_rows(&mut self, a: usize, b: usize);
|
||||
|
|
|
@ -249,7 +249,9 @@ impl<S: Copy + Neg<Output = S>> Matrix4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Matrix<S: BaseFloat, V: Vector<S> + 'static>: Array2<V, V, S> + ApproxEq<Epsilon = S> + Sized // where
|
||||
pub trait Matrix<S: BaseFloat, V: Vector<S>> where
|
||||
Self: Array2<Element = S, Column = V, Row = V>,
|
||||
Self: ApproxEq<Epsilon = S> + Sized,
|
||||
// FIXME: blocked by rust-lang/rust#20671
|
||||
//
|
||||
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
|
||||
|
@ -359,7 +361,11 @@ pub trait Matrix<S: BaseFloat, V: Vector<S> + 'static>: Array2<V, V, S> + Approx
|
|||
fn is_symmetric(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<S: Copy + 'static> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> {
|
||||
impl<S: Copy + 'static> Array2 for Matrix2<S> {
|
||||
type Element = S;
|
||||
type Column = Vector2<S>;
|
||||
type Row = Vector2<S>;
|
||||
|
||||
#[inline]
|
||||
fn row(&self, r: usize) -> Vector2<S> {
|
||||
Vector2::new(self[0][r],
|
||||
|
@ -373,7 +379,11 @@ impl<S: Copy + 'static> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Copy + 'static> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> {
|
||||
impl<S: Copy + 'static> Array2 for Matrix3<S> {
|
||||
type Element = S;
|
||||
type Column = Vector3<S>;
|
||||
type Row = Vector3<S>;
|
||||
|
||||
#[inline]
|
||||
fn row(&self, r: usize) -> Vector3<S> {
|
||||
Vector3::new(self[0][r],
|
||||
|
@ -389,7 +399,11 @@ impl<S: Copy + 'static> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Copy + 'static> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
|
||||
impl<S: Copy + 'static> Array2 for Matrix4<S> {
|
||||
type Element = S;
|
||||
type Column = Vector4<S>;
|
||||
type Row = Vector4<S>;
|
||||
|
||||
#[inline]
|
||||
fn row(&self, r: usize) -> Vector4<S> {
|
||||
Vector4::new(self[0][r],
|
||||
|
|
10
src/point.rs
10
src/point.rs
|
@ -66,7 +66,7 @@ impl<S: BaseNum> Point3<S> {
|
|||
}
|
||||
|
||||
/// Specifies the numeric operations for point types.
|
||||
pub trait Point<S: BaseNum>: Array1<S> + Clone // where
|
||||
pub trait Point<S: BaseNum>: Array1<Element = S> + Clone // where
|
||||
// FIXME: blocked by rust-lang/rust#20671
|
||||
//
|
||||
// for<'a, 'b> &'a Self: Add<&'b V, Output = Self>,
|
||||
|
@ -123,7 +123,9 @@ pub trait Point<S: BaseNum>: Array1<S> + Clone // where
|
|||
fn max(&self, p: &Self) -> Self;
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Array1<S> for Point2<S> {}
|
||||
impl<S: BaseNum> Array1 for Point2<S> {
|
||||
type Element = S;
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Point<S> for Point2<S> {
|
||||
type Vector = Vector2<S>;
|
||||
|
@ -200,7 +202,9 @@ impl<S: BaseFloat> ApproxEq for Point2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Array1<S> for Point3<S> {}
|
||||
impl<S: BaseNum> Array1 for Point3<S> {
|
||||
type Element = S;
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Point<S> for Point3<S> {
|
||||
type Vector = Vector3<S>;
|
||||
|
|
|
@ -40,7 +40,9 @@ pub struct Quaternion<S> {
|
|||
pub v: Vector3<S>,
|
||||
}
|
||||
|
||||
impl<S: Copy + BaseFloat> Array1<S> for Quaternion<S> {}
|
||||
impl<S: Copy + BaseFloat> Array1 for Quaternion<S> {
|
||||
type Element = S;
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> Quaternion<S> {
|
||||
/// Construct a new quaternion from one scalar component and three
|
||||
|
|
|
@ -111,7 +111,7 @@ use num::{BaseNum, BaseFloat};
|
|||
/// A trait that specifies a range of numeric operations for vectors. Not all
|
||||
/// of these make sense from a linear algebra point of view, but are included
|
||||
/// for pragmatic reasons.
|
||||
pub trait Vector<S: BaseNum>: Array1<S> + Clone // where
|
||||
pub trait Vector<S: BaseNum>: Array1<Element = S> + Clone // where
|
||||
// FIXME: blocked by rust-lang/rust#20671
|
||||
//
|
||||
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
|
||||
|
@ -245,7 +245,9 @@ macro_rules! vec {
|
|||
}
|
||||
}
|
||||
|
||||
impl<$S: Copy> Array1<$S> for $VectorN<$S> {}
|
||||
impl<S: Copy> Array1 for $VectorN<S> {
|
||||
type Element = S;
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Vector<S> for $VectorN<S> {
|
||||
#[inline] fn from_value(s: S) -> $VectorN<S> { $VectorN { $($field: s),+ } }
|
||||
|
|
Loading…
Reference in a new issue