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
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
//! 3x3 allocation-free array implementation of Grid3.

use crate::{
    range::Range0To,
    grid3::*,
};
use mint::Vector3;

pub struct Inline3x3x3Grid<T> {
    array: [[[T; 3]; 3]; 3],
}

impl<T> Inline3x3x3Grid<T> {
    pub fn new<I, F>(mut startval: F) -> Self 
    where
        I: From<Vector3<i32>>,
        F: FnMut(I) -> T
    {
        fn xyz<I: From<Vector3<i32>>>(x: i32, y: i32, z: i32) -> I {
            I::from(Vector3 { x, y, z })
        }
        
        let array =
        [
            [
                [startval(xyz(0, 0, 0)), startval(xyz(0, 0, 1)), startval(xyz(0, 0, 2))],
                [startval(xyz(0, 1, 0)), startval(xyz(0, 1, 1)), startval(xyz(0, 1, 2))],
                [startval(xyz(0, 2, 0)), startval(xyz(0, 2, 1)), startval(xyz(0, 2, 2))],
            ],
            [
                [startval(xyz(1, 0, 0)), startval(xyz(1, 0, 1)), startval(xyz(1, 0, 2))],
                [startval(xyz(1, 1, 0)), startval(xyz(1, 1, 1)), startval(xyz(1, 1, 2))],
                [startval(xyz(1, 2, 0)), startval(xyz(1, 2, 1)), startval(xyz(1, 2, 2))],
            ],
            [
                [startval(xyz(2, 0, 0)), startval(xyz(2, 0, 1)), startval(xyz(2, 0, 2))],
                [startval(xyz(2, 1, 0)), startval(xyz(2, 1, 1)), startval(xyz(2, 1, 2))],
                [startval(xyz(2, 2, 0)), startval(xyz(2, 2, 1)), startval(xyz(2, 2, 2))],
            ]
        ];
        Inline3x3x3Grid { array }
    }
    
    
    pub fn broadcast(startval: T) -> Self 
    where
        T: Clone
    {
        Self::new(|_: Vector3<i32>| startval.clone())
    }
}

impl<T> From<[[[T; 3]; 3]; 3]> for Inline3x3x3Grid<T> {
    fn from(array: [[[T; 3]; 3]; 3]) -> Self {
        Inline3x3x3Grid { array }
    }
}

impl<T> Grid3 for Inline3x3x3Grid<T> {
    type Item = T;
    type XBound = Range0To;
    type YBound = Range0To;
    type ZBound = Range0To;
    
    fn x_bound(&self) -> Range0To {
        Range0To { end: 3 }
    }
    
    fn y_bound(&self) -> Range0To {
        Range0To { end: 3 }
    }
    
    fn z_bound(&self) -> Range0To {
        Range0To { end: 3 }
    }
}

impl<T> Grid3Len for Inline3x3x3Grid<T> {}

impl<T> Grid3Ref for Inline3x3x3Grid<T> {
    fn idx<I>(&self, coord: I) -> &Self::Item
    where
        I: Into<Vector3<i32>>
    {
        let coord = coord.into();
        &self.array[coord.x as usize][coord.y as usize][coord.z as usize]
    }
}

impl<T> Grid3Mut for Inline3x3x3Grid<T> {
    fn midx<I>(&mut self, coord: I) -> &mut Self::Item
    where
        I: Into<Vector3<i32>>
    {
        let coord = coord.into();
        &mut self.array[coord.x as usize][coord.y as usize][coord.z as usize]
    }
}

impl<T: Clone> Grid3Get for Inline3x3x3Grid<T> {
    fn get<I: Into<Vector3<i32>>>(&self, coord: I) -> Self::Item 
    { self.idx(coord).clone() }
}

impl<T> Grid3Set for Inline3x3x3Grid<T> {
    fn set<I: Into<Vector3<i32>>>(&mut self, coord: I, elem: Self::Item) 
    { *self.midx(coord) = elem; }
}