multidimension/
int.rs

1//! A variety of [`Index`]es and [`View`]s based on `usize`.
2//!
3//! `usize` itself implements `Index`.
4//!
5//! [`View`]: super::View
6
7use super::{div_mod, NonTuple, Index};
8
9impl Index for usize {
10    type Size = usize;
11
12    #[inline(always)]
13    fn length(size: Self::Size) -> usize { size }
14
15    #[inline(always)]
16    fn to_usize(self, size: Self::Size) -> usize {
17        assert!(self < size, "Index {:?} is out of bounds for size {:?}", self, size);
18        self
19    }
20
21    fn from_usize(size: Self::Size, index: usize) -> (usize, Self) { div_mod(index, size) }
22
23    fn each(size: Self::Size, mut f: impl FnMut(Self)) {
24        for i in 0..size { f(i); }
25    }
26}
27
28// ----------------------------------------------------------------------------
29
30/// An `usize`-like [`Index`] with a compile-time constant size.
31#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
32#[repr(transparent)]
33pub struct Fixed<const SIZE: usize>(pub usize);
34
35impl<const SIZE: usize> NonTuple for Fixed<SIZE> {}
36
37impl<const SIZE: usize> Index for Fixed<SIZE> {
38    type Size = ();
39
40    #[inline(always)]
41    fn length(_: ()) -> usize { SIZE }
42
43    #[inline(always)]
44    fn to_usize(self, _: ()) -> usize { self.0 }
45
46    fn from_usize(_: Self::Size, index: usize) -> (usize, Self) {
47        let (index, i) = div_mod(index, SIZE);
48        (index, Fixed(i))
49    }
50
51    fn each(_: (), mut f: impl FnMut(Self)) {
52        for i in 0..SIZE { f(Fixed(i)); }
53    }
54}
55
56// ----------------------------------------------------------------------------
57
58fn reverse(size: usize, index: usize) -> usize {
59    (size - 1) - index
60}
61
62/// A `usize`-like [`Index`] that counts backwards.
63#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
64#[repr(transparent)]
65pub struct Reversed(pub usize);
66
67impl NonTuple for Reversed {}
68
69impl Index for Reversed {
70    type Size = usize;
71
72    #[inline(always)]
73    fn length(size: Self::Size) -> usize { size }
74
75    #[inline(always)]
76    fn to_usize(self, size: Self::Size) -> usize { reverse(size, self.0) }
77
78    fn from_usize(size: Self::Size, index: usize) -> (usize, Self) {
79        let (q, r) = div_mod(index, size);
80        (q, Reversed(reverse(size, r)))
81    }
82
83    fn each(size: Self::Size, mut f: impl FnMut(Self)) {
84        for i in 0..size { f(Reversed(reverse(size, i))); }
85    }
86}