Skip to main content

fso_graph_builder/
index.rs

1use std::fmt::Debug;
2use std::iter::Sum;
3use std::ops::{Range, RangeInclusive};
4use std::sync::atomic::Ordering;
5
6use atoi::FromRadix10;
7use atomic::Atomic;
8use bytemuck::NoUninit;
9
10pub trait Idx:
11    Copy
12    + std::ops::Add<Output = Self>
13    + std::ops::AddAssign
14    + std::ops::Sub<Output = Self>
15    + std::ops::Div<Output = Self>
16    + std::ops::Mul<Output = Self>
17    + Ord
18    + Debug
19    + Send
20    + Sum
21    + Sync
22    + Sized
23    + NoUninit
24    + 'static
25{
26    fn new(idx: usize) -> Self;
27
28    fn zero() -> Self;
29
30    fn index(self) -> usize;
31
32    type RangeIter: Iterator<Item = Self>;
33
34    fn range(self, end: Self) -> Self::RangeIter;
35
36    type RangeInclusiveIter: Iterator<Item = Self>;
37
38    fn range_inclusive(self, end: Self) -> Self::RangeInclusiveIter;
39
40    fn parse(bytes: &[u8]) -> (Self, usize);
41
42    fn get_and_increment(this: &Atomic<Self>, order: Ordering) -> Self {
43        Self::fetch_add(this, Self::new(1), order)
44    }
45
46    fn fetch_add(this: &Atomic<Self>, val: Self, order: Ordering) -> Self;
47}
48
49macro_rules! impl_idx {
50    ($TYPE:ty) => {
51        impl Idx for $TYPE {
52            #[inline]
53            fn new(idx: usize) -> Self {
54                assert!(idx <= <$TYPE>::MAX as usize);
55                idx as $TYPE
56            }
57
58            #[inline]
59            fn zero() -> Self {
60                0
61            }
62
63            #[inline]
64            fn index(self) -> usize {
65                self as usize
66            }
67
68            type RangeIter = Range<Self>;
69
70            #[inline]
71            fn range(self, end: Self) -> Self::RangeIter {
72                self..end
73            }
74
75            type RangeInclusiveIter = RangeInclusive<Self>;
76
77            #[inline]
78            fn range_inclusive(self, end: Self) -> Self::RangeInclusiveIter {
79                self..=end
80            }
81
82            #[inline]
83            fn parse(bytes: &[u8]) -> (Self, usize) {
84                FromRadix10::from_radix_10(bytes)
85            }
86
87            #[inline]
88            fn fetch_add(this: &Atomic<$TYPE>, val: $TYPE, order: Ordering) -> $TYPE {
89                this.fetch_add(val, order)
90            }
91        }
92    };
93}
94
95impl_idx!(u8);
96impl_idx!(u16);
97impl_idx!(u32);
98impl_idx!(u64);
99impl_idx!(usize);
100
101impl_idx!(i8);
102impl_idx!(i16);
103impl_idx!(i32);
104impl_idx!(i64);
105impl_idx!(isize);