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,
ScalarAdd, ScalarSub,
ScalarMul, ScalarDiv,
Shape,
ToHomogeneous,
Transform, Transformation,
Translate, Translation,
@ -932,6 +933,12 @@ pub fn dim<V: Dim>() -> uint {
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>
*/

View File

@ -10,7 +10,7 @@ use traits::operations::ApproxEq;
use std::mem;
use structs::dvec::{DVec, DVecMulRhs};
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};
@ -261,10 +261,13 @@ impl<N: Clone> Indexable<(uint, uint), N> for DMat<N> {
self.mij.as_mut_slice().swap(offset1, offset2);
}
}
impl<N> Shape<(uint, uint), N> for DMat<N> {
#[inline]
fn shape(&self) -> (uint, uint) {
(self.nrows, self.ncols)
}
}
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 std::iter::FromIterator;
use traits::geometry::{Dot, Norm};
use traits::structure::{Iterable, IterableMut, Indexable};
use traits::structure::{Iterable, IterableMut, Indexable, Shape};
/// Heap allocated, dynamically sized vector.
#[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> {
#[inline]
fn at(&self, i: uint) -> N {
@ -68,11 +75,6 @@ macro_rules! dvec_impl(
self.as_mut_slice().swap(i, j);
}
#[inline]
fn shape(&self) -> uint {
self.len()
}
#[inline]
unsafe fn unsafe_at(&self, i: uint) -> N {
(*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 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::geometry::{ToHomogeneous, FromHomogeneous, Orig};

View File

@ -184,6 +184,13 @@ macro_rules! dim_impl(
macro_rules! indexable_impl(
($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> {
#[inline]
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]
unsafe fn unsafe_at(&self, (i, j): (uint, uint)) -> N {
(*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 traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual,
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 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 traits::operations::{ApproxEq, Inv, POrd, POrdering, NotComparable, PartialLess,
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};
/// A quaternion.

View File

@ -3,10 +3,31 @@ use std::num::{Zero, One, Float, Bounded};
use std::slice::{Items, MutItems};
use std::iter::{Iterator, FromIterator};
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 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> {
#[inline]
fn at(&self, _: uint) -> N {
@ -17,11 +38,6 @@ impl<N> Indexable<uint, N> for vec::Vec0<N> {
fn set(&mut self, _: uint, _: N) {
}
#[inline]
fn shape(&self) -> uint {
0
}
#[inline]
fn swap(&mut self, _: uint, _: uint) {
}

View File

@ -10,7 +10,7 @@ use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual,
PartialGreater, NotComparable, Axpy};
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
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};

View File

@ -170,6 +170,13 @@ macro_rules! vec_cast_impl(
macro_rules! indexable_impl(
($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> {
#[inline]
fn at(&self, i: uint) -> N {
@ -185,11 +192,6 @@ macro_rules! indexable_impl(
}
}
#[inline]
fn shape(&self) -> uint {
$dim
}
#[inline]
fn swap(&mut self, i1: uint, i2: uint) {
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,
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,
RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose};

View File

@ -96,36 +96,35 @@ pub trait Diag<V> {
fn diag(&self) -> V;
}
// FIXME: this trait should not be on nalgebra.
// however, it is needed because std::ops::Index is (strangely) to poor: it
// does not have a function to set values.
// Also, using Index with tuples crashes.
/// The shape of an indexable object.
pub trait Shape<I, Res>: Index<I, Res> {
/// Returns the shape of an indexable object.
fn shape(&self) -> I;
}
/// This is a workaround of current Rust limitations.
///
/// It exists because the `Index` 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
/// It exists because the `I` trait cannot be used to express write access.
/// Thus, this is the same as the `I` trait but without the syntactic sugar and with a method
/// 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"]
/// 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"]
/// 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.
fn swap(&mut self, i: Index, j: Index);
/// Returns the shape of the iterable range.
fn shape(&self) -> Index;
fn swap(&mut self, i: I, j: I);
/// Reads the `i`-th element of `self`.
///
/// `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`.
///
/// `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.