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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use super::*;

/// Trait for backing stores for a [`GridBuf`]
///
/// This provides a simple abstraction over a fixed size array of items. It is implemented for
/// [`Vec`] and [`BitVec`].
///
pub trait GridStorage {

	type Item;

	fn storage_get (& self, idx: usize) -> Option <Self::Item>;
	fn storage_set (& mut self, idx: usize, item: Self::Item);
	fn storage_len (& self) -> usize;

}

impl <Item, const LEN: usize> GridStorage for [Item; LEN] where Item: Clone {
	type Item = Item;

	#[ inline ]
	fn storage_get (& self, idx: usize) -> Option <Item> {
		self.get (idx).cloned ()
	}

	#[ inline ]
	fn storage_set (& mut self, idx: usize, item: Self::Item) {
		self [idx] = item;
	}

	#[ inline ]
	fn storage_len (& self) -> usize {
		self.len ()
	}

}

impl <Item> GridStorage for Vec <Item> where Item: Clone {
	type Item = Item;

	#[ inline ]
	fn storage_get (& self, idx: usize) -> Option <Item> {
		self.get (idx).cloned ()
	}

	#[ inline ]
	fn storage_set (& mut self, idx: usize, item: Self::Item) {
		self [idx] = item;
	}

	#[ inline ]
	fn storage_len (& self) -> usize {
		self.len ()
	}

}

impl <Item, Encoding> GridStorage for BitVec <Item, Encoding>
	where
		Encoding: BitVecEncoding <Item>,
		Item: Clone {

	type Item = Item;

	#[ inline ]
	fn storage_get (& self, idx: usize) -> Option <Item> {
		self.get (idx)
	}

	#[ inline ]
	fn storage_set (& mut self, idx: usize, item: Self::Item) {
		self.set (idx, item);
	}

	#[ inline ]
	fn storage_len (& self) -> usize {
		self.len ()
	}

}

/// Additional trait for backing stores which which can provide references to items
///
pub trait GridStorageMut: GridStorage {
	fn storage_ref (& self, idx: usize) -> Option <& Self::Item>;
	fn storage_mut (& mut self, idx: usize) -> Option <& mut Self::Item>;
}

impl <Item> GridStorageMut for Vec <Item> where Item: Clone {

	#[ inline ]
	fn storage_ref (& self, idx: usize) -> Option <& Item> {
		self.get (idx)
	}

	#[ inline ]
	fn storage_mut (& mut self, idx: usize) -> Option <& mut Item> {
		self.get_mut (idx)
	}

}

/// Extra trait for [`GridStorage`] to support iteration.
///
/// This is a separate trait to make the lifetimes work. It should be implemented on a reference to
/// the storage, rather than directly. This allows us to capture the lifetime without polluting the
/// main trait.
///
pub trait GridStorageIntoIter {

	type Item;
	type Iter: Iterator <Item = Self::Item>;

	fn storage_iter (& self) -> Self::Iter;

}

impl <'sto, Item> GridStorageIntoIter for & 'sto Vec <Item> where Item: Clone {

	type Item = Item;
	type Iter = GridStorageClone <SliceIter <'sto, Item>>;

	#[ inline ]
	fn storage_iter (& self) -> Self::Iter {
		GridStorageClone::new (self.iter ())
	}

}

impl <'sto, Item, Encoding> GridStorageIntoIter for & 'sto BitVec <Item, Encoding>
	where
		Encoding: BitVecEncoding <Item>,
		Item: Clone {

	type Item = Item;
	type Iter = BitVecIter <'sto, Item, Encoding>;

	#[ inline ]
	fn storage_iter (& self) -> Self::Iter {
		self.iter ()
	}

}