Move the `.shape()` method to its own trait: `Shape`.

This commit is contained in:
Sébastien Crozet 2014-10-26 10:46:51 +01:00
parent 3354ffc37b
commit a0fffe93a9
13 changed files with 75 additions and 44 deletions

View File

@ -151,6 +151,7 @@ pub use traits::{
Row, Row,
ScalarAdd, ScalarSub, ScalarAdd, ScalarSub,
ScalarMul, ScalarDiv, ScalarMul, ScalarDiv,
Shape,
ToHomogeneous, ToHomogeneous,
Transform, Transformation, Transform, Transformation,
Translate, Translation, Translate, Translation,
@ -932,6 +933,12 @@ pub fn dim<V: Dim>() -> uint {
Dim::dim(None::<V>) Dim::dim(None::<V>)
} }
/// Gets the indexable range of an object.
#[inline(always)]
pub fn shape<V: Shape<I, N>, I, N>(v: &V) -> I {
v.shape()
}
/* /*
* Cast<T> * Cast<T>
*/ */

View File

@ -10,7 +10,7 @@ use traits::operations::ApproxEq;
use std::mem; use std::mem;
use structs::dvec::{DVec, DVecMulRhs}; use structs::dvec::{DVec, DVecMulRhs};
use traits::operations::{Inv, Transpose, Mean, Cov}; use traits::operations::{Inv, Transpose, Mean, Cov};
use traits::structure::{Cast, ColSlice, RowSlice, Diag, Eye, Indexable}; use traits::structure::{Cast, ColSlice, RowSlice, Diag, Eye, Indexable, Shape};
use std::fmt::{Show, Formatter, Result}; use std::fmt::{Show, Formatter, Result};
@ -261,10 +261,13 @@ impl<N: Clone> Indexable<(uint, uint), N> for DMat<N> {
self.mij.as_mut_slice().swap(offset1, offset2); self.mij.as_mut_slice().swap(offset1, offset2);
} }
}
impl<N> Shape<(uint, uint), N> for DMat<N> {
#[inline]
fn shape(&self) -> (uint, uint) { fn shape(&self) -> (uint, uint) {
(self.nrows, self.ncols) (self.nrows, self.ncols)
} }
} }
impl<N> Index<(uint, uint), N> for DMat<N> { impl<N> Index<(uint, uint), N> for DMat<N> {

View File

@ -9,7 +9,7 @@ use std::slice::{Items, MutItems};
use traits::operations::ApproxEq; use traits::operations::ApproxEq;
use std::iter::FromIterator; use std::iter::FromIterator;
use traits::geometry::{Dot, Norm}; use traits::geometry::{Dot, Norm};
use traits::structure::{Iterable, IterableMut, Indexable}; use traits::structure::{Iterable, IterableMut, Indexable, Shape};
/// Heap allocated, dynamically sized vector. /// Heap allocated, dynamically sized vector.
#[deriving(Eq, PartialEq, Show, Clone)] #[deriving(Eq, PartialEq, Show, Clone)]

View File

@ -44,6 +44,13 @@ macro_rules! dvec_impl(
} }
} }
impl<N> Shape<uint, N> for $dvec<N> {
#[inline]
fn shape(&self) -> uint {
self.len()
}
}
impl<N: Clone> Indexable<uint, N> for $dvec<N> { impl<N: Clone> Indexable<uint, N> for $dvec<N> {
#[inline] #[inline]
fn at(&self, i: uint) -> N { fn at(&self, i: uint) -> N {
@ -68,11 +75,6 @@ macro_rules! dvec_impl(
self.as_mut_slice().swap(i, j); self.as_mut_slice().swap(i, j);
} }
#[inline]
fn shape(&self) -> uint {
self.len()
}
#[inline] #[inline]
unsafe fn unsafe_at(&self, i: uint) -> N { unsafe fn unsafe_at(&self, i: uint) -> N {
(*self.at.as_slice().unsafe_get(i)).clone() (*self.at.as_slice().unsafe_get(i)).clone()

View File

@ -12,7 +12,7 @@ use structs::pnt::{Pnt1, Pnt4, Pnt5, Pnt6, Pnt1MulRhs, Pnt4MulRhs, Pnt5MulRhs, P
use structs::dvec::{DVec1, DVec2, DVec3, DVec4, DVec5, DVec6}; use structs::dvec::{DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable, use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable,
Eye, ColSlice, RowSlice, Diag}; Eye, ColSlice, RowSlice, Diag, Shape};
use traits::operations::{Absolute, Transpose, Inv, Outer}; use traits::operations::{Absolute, Transpose, Inv, Outer};
use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig}; use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig};

View File

@ -184,6 +184,13 @@ macro_rules! dim_impl(
macro_rules! indexable_impl( macro_rules! indexable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> Shape<(uint, uint), N> for $t<N> {
#[inline]
fn shape(&self) -> (uint, uint) {
($dim, $dim)
}
}
impl<N: Clone> Indexable<(uint, uint), N> for $t<N> { impl<N: Clone> Indexable<(uint, uint), N> for $t<N> {
#[inline] #[inline]
fn at(&self, (i, j): (uint, uint)) -> N { fn at(&self, (i, j): (uint, uint)) -> N {
@ -207,11 +214,6 @@ macro_rules! indexable_impl(
} }
} }
#[inline]
fn shape(&self) -> (uint, uint) {
($dim, $dim)
}
#[inline] #[inline]
unsafe fn unsafe_at(&self, (i, j): (uint, uint)) -> N { unsafe fn unsafe_at(&self, (i, j): (uint, uint)) -> N {
(*mem::transmute::<&$t<N>, &[N, ..$dim * $dim]>(self).unsafe_get(i + j * $dim)).clone() (*mem::transmute::<&$t<N>, &[N, ..$dim * $dim]>(self).unsafe_get(i + j * $dim)).clone()

View File

@ -8,7 +8,7 @@ use std::slice::{Items, MutItems};
use std::iter::{Iterator, FromIterator}; use std::iter::{Iterator, FromIterator};
use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual,
PartialGreater, NotComparable, Axpy}; PartialGreater, NotComparable, Axpy};
use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec}; use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, Shape};
use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous}; use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous};
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};

View File

@ -10,7 +10,7 @@ use std::slice::{Items, MutItems};
use structs::{Vec3, Pnt3, Rot3, Mat3, Vec3MulRhs, Pnt3MulRhs}; use structs::{Vec3, Pnt3, Rot3, Mat3, Vec3MulRhs, Pnt3MulRhs};
use traits::operations::{ApproxEq, Inv, POrd, POrdering, NotComparable, PartialLess, use traits::operations::{ApproxEq, Inv, POrd, POrdering, NotComparable, PartialLess,
PartialGreater, PartialEqual, Axpy}; PartialGreater, PartialEqual, Axpy};
use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim}; use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape};
use traits::geometry::{Norm, Cross, Rotation, Rotate, Transform}; use traits::geometry::{Norm, Cross, Rotation, Rotate, Transform};
/// A quaternion. /// A quaternion.

View File

@ -3,10 +3,31 @@ use std::num::{Zero, One, Float, Bounded};
use std::slice::{Items, MutItems}; use std::slice::{Items, MutItems};
use std::iter::{Iterator, FromIterator}; use std::iter::{Iterator, FromIterator};
use traits::operations::ApproxEq; use traits::operations::ApproxEq;
use traits::structure::{Iterable, IterableMut, Indexable, Basis, Dim}; use traits::structure::{Iterable, IterableMut, Indexable, Basis, Dim, Shape};
use traits::geometry::{Translation, Dot, Norm}; use traits::geometry::{Translation, Dot, Norm};
use structs::vec; use structs::vec;
impl<N> Index<uint, N> for vec::Vec0<N> {
#[inline]
fn index(&self, _: &uint) -> &N {
panic!("Canot index a Vec0.")
}
}
impl<N> IndexMut<uint, N> for vec::Vec0<N> {
#[inline]
fn index_mut(&mut self, _: &uint) -> &mut N {
panic!("Canot index a Vec0.")
}
}
impl<N> Shape<uint, N> for vec::Vec0<N> {
#[inline]
fn shape(&self) -> uint {
0
}
}
impl<N> Indexable<uint, N> for vec::Vec0<N> { impl<N> Indexable<uint, N> for vec::Vec0<N> {
#[inline] #[inline]
fn at(&self, _: uint) -> N { fn at(&self, _: uint) -> N {
@ -17,11 +38,6 @@ impl<N> Indexable<uint, N> for vec::Vec0<N> {
fn set(&mut self, _: uint, _: N) { fn set(&mut self, _: uint, _: N) {
} }
#[inline]
fn shape(&self) -> uint {
0
}
#[inline] #[inline]
fn swap(&mut self, _: uint, _: uint) { fn swap(&mut self, _: uint, _: uint) {
} }

View File

@ -10,7 +10,7 @@ use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual,
PartialGreater, NotComparable, Axpy}; PartialGreater, NotComparable, Axpy};
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
Translation, Translate}; Translation, Translate};
use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, VecAsPnt}; use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, VecAsPnt, Shape};
use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6}; use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};

View File

@ -170,6 +170,13 @@ macro_rules! vec_cast_impl(
macro_rules! indexable_impl( macro_rules! indexable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> Shape<uint, N> for $t<N> {
#[inline]
fn shape(&self) -> uint {
$dim
}
}
impl<N: Clone> Indexable<uint, N> for $t<N> { impl<N: Clone> Indexable<uint, N> for $t<N> {
#[inline] #[inline]
fn at(&self, i: uint) -> N { fn at(&self, i: uint) -> N {
@ -185,11 +192,6 @@ macro_rules! indexable_impl(
} }
} }
#[inline]
fn shape(&self) -> uint {
$dim
}
#[inline] #[inline]
fn swap(&mut self, i1: uint, i2: uint) { fn swap(&mut self, i1: uint, i2: uint) {
unsafe { unsafe {

View File

@ -6,7 +6,7 @@ pub use self::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneou
pub use self::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable, Iterable, pub use self::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable, Iterable,
IterableMut, Mat, Row, AnyVec, AnyPnt, PntAsVec, VecAsPnt, ColSlice, IterableMut, Mat, Row, AnyVec, AnyPnt, PntAsVec, VecAsPnt, ColSlice,
RowSlice, Diag, Eye}; RowSlice, Diag, Eye, Shape};
pub use self::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, LMul, Mean, Outer, POrd, pub use self::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, LMul, Mean, Outer, POrd,
RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose}; RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose};

View File

@ -96,36 +96,35 @@ pub trait Diag<V> {
fn diag(&self) -> V; fn diag(&self) -> V;
} }
// FIXME: this trait should not be on nalgebra. /// The shape of an indexable object.
// however, it is needed because std::ops::Index is (strangely) to poor: it pub trait Shape<I, Res>: Index<I, Res> {
// does not have a function to set values. /// Returns the shape of an indexable object.
// Also, using Index with tuples crashes. fn shape(&self) -> I;
}
/// This is a workaround of current Rust limitations. /// This is a workaround of current Rust limitations.
/// ///
/// It exists because the `Index` trait cannot be used to express write access. /// It exists because the `I` trait cannot be used to express write access.
/// Thus, this is the same as the `Index` trait but without the syntactic sugar and with a method /// Thus, this is the same as the `I` trait but without the syntactic sugar and with a method
/// to write to a specific index. /// to write to a specific index.
pub trait Indexable<Index, Res> { pub trait Indexable<I, Res>: Shape<I, Res> + IndexMut<I, Res> {
#[deprecated = "use the Index `[]` overloaded operator instead"] #[deprecated = "use the Index `[]` overloaded operator instead"]
/// Reads the `i`-th element of `self`. /// Reads the `i`-th element of `self`.
fn at(&self, i: Index) -> Res; fn at(&self, i: I) -> Res;
#[deprecated = "use the IndexMut `[]` overloaded operator instead"] #[deprecated = "use the IndexMut `[]` overloaded operator instead"]
/// Writes to the `i`-th element of `self`. /// Writes to the `i`-th element of `self`.
fn set(&mut self, i: Index, Res); fn set(&mut self, i: I, Res);
/// Swaps the `i`-th element of `self` with its `j`-th element. /// Swaps the `i`-th element of `self` with its `j`-th element.
fn swap(&mut self, i: Index, j: Index); fn swap(&mut self, i: I, j: I);
/// Returns the shape of the iterable range.
fn shape(&self) -> Index;
/// Reads the `i`-th element of `self`. /// Reads the `i`-th element of `self`.
/// ///
/// `i` is not checked. /// `i` is not checked.
unsafe fn unsafe_at(&self, i: Index) -> Res; unsafe fn unsafe_at(&self, i: I) -> Res;
/// Writes to the `i`-th element of `self`. /// Writes to the `i`-th element of `self`.
/// ///
/// `i` is not checked. /// `i` is not checked.
unsafe fn unsafe_set(&mut self, i: Index, Res); unsafe fn unsafe_set(&mut self, i: I, Res);
} }
/// This is a workaround of current Rust limitations. /// This is a workaround of current Rust limitations.