lattice_graph/hex/shapes/
mod.rs1use std::marker::PhantomData;
4
5use crate::{lattice_abstract::*, unreachable_debug_checked};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub enum AxisR {
10 NE = 0,
11 E = 1,
12 SE = 2,
13}
14
15impl Axis for AxisR {
16 const COUNT: usize = 3;
17 const DIRECTED: bool = false;
18 type Direction = AxisDR;
19
20 fn to_index(&self) -> usize {
21 match self {
22 AxisR::NE => 0,
23 AxisR::E => 1,
24 AxisR::SE => 2,
25 }
26 }
27
28 fn from_index(index: usize) -> Option<Self>
29 where
30 Self: Sized,
31 {
32 Some(match index {
33 0 => AxisR::NE,
34 1 => AxisR::E,
35 2 => AxisR::SE,
36 _ => return None,
37 })
38 }
39
40 unsafe fn from_index_unchecked(index: usize) -> Self {
41 match index {
42 0 => AxisR::NE,
43 1 => AxisR::E,
44 2 => AxisR::SE,
45 _ => unreachable_debug_checked(),
46 }
47 }
48
49 fn foward(self) -> Self::Direction {
50 unsafe { AxisDR::from_index_unchecked(self.to_index()) }
51 }
52
53 fn backward(self) -> Self::Direction {
54 unsafe { AxisDR::from_index_unchecked(self.to_index() + Self::COUNT) }
55 }
56
57 fn from_direction(dir: Self::Direction) -> Self {
58 let i = dir.to_index();
59 unsafe { Self::from_index_unchecked(if i >= Self::COUNT { i - Self::COUNT } else { i }) }
60 }
61
62 fn is_forward_direction(dir: &Self::Direction) -> bool {
63 dir.dir_to_index() < Self::COUNT
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
69pub enum AxisDR {
70 NE = 0,
71 E = 1,
72 SE = 2,
73 SW = 3,
74 W = 4,
75 NW = 5,
76}
77
78impl Axis for AxisDR {
79 const COUNT: usize = 6;
80 const DIRECTED: bool = true;
81 type Direction = Self;
82
83 fn to_index(&self) -> usize {
84 match self {
85 AxisDR::NE => 0,
86 AxisDR::E => 1,
87 AxisDR::SE => 2,
88 AxisDR::SW => 3,
89 AxisDR::W => 4,
90 AxisDR::NW => 5,
91 }
92 }
93
94 fn from_index(index: usize) -> Option<Self>
95 where
96 Self: Sized,
97 {
98 Some(match index {
99 0 => AxisDR::NE,
100 1 => AxisDR::E,
101 2 => AxisDR::SE,
102 3 => AxisDR::SW,
103 4 => AxisDR::W,
104 5 => AxisDR::NW,
105 _ => return None,
106 })
107 }
108
109 unsafe fn from_index_unchecked(index: usize) -> Self {
110 match index {
111 0 => AxisDR::NE,
112 1 => AxisDR::E,
113 2 => AxisDR::SE,
114 3 => AxisDR::SW,
115 4 => AxisDR::W,
116 5 => AxisDR::NW,
117 _ => unreachable_debug_checked(),
118 }
119 }
120
121 fn foward(self) -> Self::Direction {
122 self
123 }
124
125 fn backward(self) -> Self::Direction {
126 match self {
127 AxisDR::NE => AxisDR::SW,
128 AxisDR::E => AxisDR::W,
129 AxisDR::SE => AxisDR::NW,
130 AxisDR::SW => AxisDR::NE,
131 AxisDR::W => AxisDR::E,
132 AxisDR::NW => AxisDR::SE,
133 }
134 }
135
136 fn from_direction(dir: Self::Direction) -> Self {
137 dir
138 }
139}
140
141#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
142pub enum AxisQ {
144 N = 0,
145 NE = 1,
146 SE = 2,
147}
148
149impl Axis for AxisQ {
150 const COUNT: usize = 3;
151 const DIRECTED: bool = false;
152 type Direction = AxisDQ;
153
154 fn to_index(&self) -> usize {
155 match self {
156 AxisQ::N => 0,
157 AxisQ::NE => 1,
158 AxisQ::SE => 2,
159 }
160 }
161
162 fn from_index(index: usize) -> Option<Self>
163 where
164 Self: Sized,
165 {
166 Some(match index {
167 0 => AxisQ::N,
168 1 => AxisQ::NE,
169 2 => AxisQ::SE,
170 _ => return None,
171 })
172 }
173
174 unsafe fn from_index_unchecked(index: usize) -> Self {
175 match index {
176 0 => AxisQ::N,
177 1 => AxisQ::NE,
178 2 => AxisQ::SE,
179 _ => unreachable_debug_checked(),
180 }
181 }
182
183 fn foward(self) -> Self::Direction {
184 unsafe { AxisDQ::from_index_unchecked(self.to_index()) }
185 }
186
187 fn backward(self) -> Self::Direction {
188 unsafe { AxisDQ::from_index_unchecked(self.to_index() + 3) }
189 }
190
191 fn from_direction(dir: Self::Direction) -> Self {
192 let i = dir.dir_to_index();
193 unsafe { Self::from_index_unchecked(if i < Self::COUNT { i } else { i - Self::COUNT }) }
194 }
195
196 fn is_forward_direction(dir: &Self::Direction) -> bool {
197 dir.dir_to_index() < Self::COUNT
198 }
199}
200
201#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
203pub enum AxisDQ {
204 N = 0,
205 NE = 1,
206 SE = 2,
207 S = 3,
208 SW = 4,
209 NW = 5,
210}
211
212impl Axis for AxisDQ {
213 const COUNT: usize = 6;
214 const DIRECTED: bool = true;
215 type Direction = Self;
216
217 fn to_index(&self) -> usize {
218 match self {
219 AxisDQ::N => 0,
220 AxisDQ::NE => 1,
221 AxisDQ::SE => 2,
222 AxisDQ::S => 3,
223 AxisDQ::SW => 4,
224 AxisDQ::NW => 5,
225 }
226 }
227
228 fn from_index(index: usize) -> Option<Self>
229 where
230 Self: Sized,
231 {
232 Some(match index {
233 0 => AxisDQ::N,
234 1 => AxisDQ::NE,
235 2 => AxisDQ::SE,
236 3 => AxisDQ::S,
237 4 => AxisDQ::SW,
238 5 => AxisDQ::NW,
239 _ => return None,
240 })
241 }
242
243 unsafe fn from_index_unchecked(index: usize) -> Self {
244 match index {
245 0 => AxisDQ::N,
246 1 => AxisDQ::NE,
247 2 => AxisDQ::SE,
248 3 => AxisDQ::S,
249 4 => AxisDQ::SW,
250 5 => AxisDQ::NW,
251 _ => unreachable_debug_checked(),
252 }
253 }
254
255 fn foward(self) -> Self::Direction {
256 self
257 }
258
259 fn backward(self) -> Self::Direction {
260 match self {
261 AxisDQ::N => AxisDQ::S,
262 AxisDQ::NE => AxisDQ::SW,
263 AxisDQ::SE => AxisDQ::NW,
264 AxisDQ::S => AxisDQ::N,
265 AxisDQ::SW => AxisDQ::NE,
266 AxisDQ::NW => AxisDQ::SE,
267 }
268 }
269
270 fn from_direction(dir: Self::Direction) -> Self {
271 dir
272 }
273}
274
275pub trait OE {
277 const IS_EVEN: bool;
278 const CONVERT_OFFSET: usize = if Self::IS_EVEN { 1 } else { 0 };
279}
280pub trait RQ {
282 const IS_FLAT_TOP: bool;
283}
284
285#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
287pub enum OddR {}
288impl OE for OddR {
289 const IS_EVEN: bool = false;
290}
291impl RQ for OddR {
292 const IS_FLAT_TOP: bool = false;
293}
294
295#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
297pub enum EvenR {}
298impl OE for EvenR {
299 const IS_EVEN: bool = true;
300}
301impl RQ for EvenR {
302 const IS_FLAT_TOP: bool = false;
303}
304
305#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
307pub enum OddQ {}
308impl OE for OddQ {
309 const IS_EVEN: bool = false;
310}
311impl RQ for OddQ {
312 const IS_FLAT_TOP: bool = false;
313}
314
315#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
317pub enum EvenQ {}
318impl OE for EvenQ {
319 const IS_EVEN: bool = true;
320}
321impl RQ for EvenQ {
322 const IS_FLAT_TOP: bool = false;
323}
324
325pub trait LoopMarker {}
327impl LoopMarker for () {}
329
330#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
332pub enum LoopEW {}
333impl LoopMarker for LoopEW {}
334#[deprecated(note = "Use LoopEW instead.")]
335pub type LEW = LoopEW;
336
337#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
339pub struct DirectedMarker<T>(PhantomData<fn() -> T>);
340impl<T: OE> OE for DirectedMarker<T> {
341 const IS_EVEN: bool = T::IS_EVEN;
342 const CONVERT_OFFSET: usize = T::CONVERT_OFFSET;
343}
344impl<T: RQ> RQ for DirectedMarker<T> {
345 const IS_FLAT_TOP: bool = T::IS_FLAT_TOP;
346}