1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use traits::{MatrixShape, MatrixRawSet, MatrixRawGet};
pub trait MatrixIndexGet<T>
{
unsafe fn unsafe_get_idx(&self, mat: &T) -> f64;
fn get_idx(&self, mat: &T) -> f64;
}
pub trait MatrixIndexSet<T>
{
unsafe fn unsafe_set_idx(&self, mat: &T, v: f64);
fn set_idx(&self, mat: &T, v: f64);
}
macro_rules! index_impl
{
($self_: ident, $mat: ident, $idx_type: ty, $rc_expr: expr) =>
{
impl<T: MatrixRawGet + MatrixShape>
MatrixIndexGet<T> for
$idx_type
{
unsafe fn unsafe_get_idx(&self, $mat: &T) -> f64
{
let $self_ = self;
let (r, c) = $rc_expr;
$mat.raw_get(r, c)
}
fn get_idx(&self, $mat: &T) -> f64
{
let $self_ = self;
let (r, c) = $rc_expr;
assert!(r < $mat.nrow());
assert!(c < $mat.ncol());
unsafe
{
$mat.raw_get(r, c)
}
}
}
impl<T: MatrixRawSet + MatrixShape>
MatrixIndexSet<T> for
$idx_type
{
unsafe fn unsafe_set_idx(&self, $mat: &T, v: f64)
{
let $self_ = self;
let (r, c) = $rc_expr;
$mat.raw_set(r, c, v)
}
fn set_idx(&self, $mat: &T, v: f64)
{
let $self_ = self;
let (r, c) = $rc_expr;
assert!(r < $mat.nrow());
assert!(c < $mat.ncol());
unsafe
{
$mat.raw_set(r, c, v)
}
}
}
}
}
fn to_rc(idx: usize, ncol: usize) -> (usize, usize)
{
(idx / ncol, idx % ncol)
}
index_impl!(self_, mat, (usize, usize), {*self_});
index_impl!(self_, mat, (i32, i32), {let (r, c) = *self_; (r as usize, c as usize)});
index_impl!(self_, mat, usize, {to_rc(*self_, mat.ncol())});
index_impl!(self_, mat, i32, {to_rc(*self_ as usize, mat.ncol())});