1use std::marker::PhantomData;
2
3use num::BigUint;
4
5use Construct;
6use Data;
7use Of;
8use space::Space;
9
10pub struct SqPair<T = Data>(PhantomData<T>);
14
15impl<T> Construct for SqPair<T> {
16 fn new() -> Self {SqPair(PhantomData)}
17}
18
19impl Space<usize> for SqPair<Data> {
20 type Dim = usize;
21 type Pos = (usize, usize);
22 fn count(&self, dim: &usize) -> usize {dim * dim}
23 fn zero(&self, _: &usize) -> (usize, usize) {(0, 0)}
24 fn to_index(&self, dim: &usize, &(a, b): &(usize, usize)) -> usize {
25 a + b * dim
26 }
27 fn to_pos(&self, dim: &usize, index: usize, pos: &mut (usize, usize)) {
28 pos.0 = index % dim;
29 pos.1 = index / dim;
30 }
31}
32
33impl Space<BigUint> for SqPair<Data> {
34 type Dim = BigUint;
35 type Pos = (BigUint, BigUint);
36 fn count(&self, dim: &Self::Dim) -> BigUint {dim * dim}
37 fn zero(&self, _: &Self::Dim) -> Self::Pos {(0usize.into(), 0usize.into())}
38 fn to_index(&self, dim: &Self::Dim, (a, b): &Self::Pos) -> BigUint {
39 a + b * dim
40 }
41 fn to_pos(&self, dim: &Self::Dim, index: BigUint, pos: &mut Self::Pos) {
42 pos.0 = &index % dim;
43 pos.1 = &index / dim;
44 }
45}
46
47impl<T, N> Space<N> for SqPair<Of<T>>
48 where T: Space<N>,
49 N: From<usize>,
50 SqPair<Data>: Space<N, Dim = N, Pos = (N, N)>,
51{
52 type Dim = T::Dim;
53 type Pos = (T::Pos, T::Pos);
54 fn count(&self, dim: &Self::Dim) -> N {
55 let of: T = Construct::new();
56 let data: SqPair<Data> = Construct::new();
57 data.count(&of.count(dim))
58 }
59 fn zero(&self, dim: &Self::Dim) -> Self::Pos {
60 let of: T = Construct::new();
61 (of.zero(dim), of.zero(dim))
62 }
63 fn to_index(
64 &self,
65 dim: &Self::Dim,
66 &(ref a, ref b): &Self::Pos
67 ) -> N {
68 let of: T = Construct::new();
69 let data: SqPair<Data> = Construct::new();
70 let a = of.to_index(dim, a);
71 let b = of.to_index(dim, b);
72 data.to_index(&self.count(dim), &(a, b))
73 }
74 fn to_pos(
75 &self,
76 dim: &Self::Dim,
77 index: N,
78 &mut (ref mut a, ref mut b): &mut Self::Pos
79 ) {
80 let of: T = Construct::new();
81 let data: SqPair<Data> = Construct::new();
82 let count = of.count(dim);
83 let mut pair = (0usize.into(), 0usize.into());
84 data.to_pos(&count, index, &mut pair);
85 let (pair_a, pair_b) = pair;
86 of.to_pos(dim, pair_a, a);
87 of.to_pos(dim, pair_b, b);
88 }
89}