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
#![allow(private_bounds)]
use crate::lib::*;

pub fn iter2d<T: Rangeable>(args: impl IterArgs2d<T>) -> impl Iterator<Item = vec2<T>> {
	let (wr, h) = args.get();
	let (mut x, w, mut y, h) = (wr.start, wr.end, h.start, h.end);
	let ident = T::to(1);
	iter::from_fn(move || {
		if y >= h {
			return None;
		}
		let ret = Some((x, y));

		x += ident;
		if x >= w {
			x = wr.start;
			y += ident;
		}
		ret
	})
}

pub fn iter3d<T: Rangeable>(args: impl IterArgs3d<T>) -> impl Iterator<Item = vec3<T>> {
	let (wr, hr, d) = args.get();
	let (mut x, w, mut y, h, mut z, d) = (wr.start, wr.end, hr.start, hr.end, d.start, d.end);
	let ident = T::to(1);
	iter::from_fn(move || {
		if z >= d {
			return None;
		}
		let ret = Some((x, y, z));

		x += ident;
		if x >= w {
			x = wr.start;
			y += ident;
		}
		if y >= h {
			y = hr.start;
			z += ident;
		}
		ret
	})
}

type Args2d<T> = (R<T>, R<T>);
trait IterArgs2d<T> {
	fn get(self) -> Args2d<T>;
}
impl<T> IterArgs2d<T> for Args2d<T> {
	fn get(self) -> Self {
		self
	}
}
impl<T: Rangeable> IterArgs2d<T> for R<T> {
	fn get(self) -> Args2d<T> {
		(self.clone(), self)
	}
}
impl<T: Rangeable> IterArgs2d<T> for T {
	fn get(self) -> Args2d<T> {
		(Def()..self, Def()..self)
	}
}
impl<T: Rangeable> IterArgs2d<T> for (T, T) {
	fn get(self) -> Args2d<T> {
		(Def()..self.0, Def()..self.1)
	}
}

type Args3d<T> = (R<T>, R<T>, R<T>);
trait IterArgs3d<T> {
	fn get(self) -> Args3d<T>;
}
impl<T> IterArgs3d<T> for Args3d<T> {
	fn get(self) -> Self {
		self
	}
}
impl<T: Rangeable> IterArgs3d<T> for R<T> {
	fn get(self) -> Args3d<T> {
		(self.clone(), self.clone(), self)
	}
}
impl<T: Rangeable> IterArgs3d<T> for T {
	fn get(self) -> Args3d<T> {
		(Def()..self, Def()..self, Def()..self)
	}
}
impl<T: Rangeable> IterArgs3d<T> for (T, T, T) {
	fn get(self) -> Args3d<T> {
		(Def()..self.0, Def()..self.1, Def()..self.2)
	}
}

type R<T> = ops::Range<T>;
trait_alias!(Rangeable, Default + ops::AddAssign + Copy + PartialOrd + Cast<u32>);