range_traits/
enumerable.rs

1use crate::MaybeBounded;
2
3/// Type for which instances can be partially enumerated.
4pub trait PartialEnum: PartialOrd + MaybeBounded {
5	fn pred(&self) -> Option<Self>;
6
7	fn succ(&self) -> Option<Self>;
8}
9
10/// Type for which instances can be entirely enumerated.
11pub trait Enum: PartialOrd + MaybeBounded {
12	fn pred(&self) -> Option<Self>;
13
14	fn succ(&self) -> Option<Self>;
15}
16
17impl<T: Enum> PartialEnum for T {
18	fn pred(&self) -> Option<Self> {
19		self.pred()
20	}
21
22	fn succ(&self) -> Option<Self> {
23		self.succ()
24	}
25}
26
27impl Enum for char {
28	fn pred(&self) -> Option<Self> {
29		('\u{0000}'..*self).next_back()
30	}
31
32	fn succ(&self) -> Option<Self> {
33		// we skip one element since that's the current char, not its successor
34		(*self..='\u{10ffff}').nth(1)
35	}
36}
37
38macro_rules! impl_int {
39	($($ty:ident),*) => {
40		$(
41			impl Enum for $ty {
42				fn pred(&self) -> Option<Self> {
43					self.checked_sub(1)
44				}
45
46				fn succ(&self) -> Option<Self> {
47					self.checked_add(1)
48				}
49			}
50		)*
51	};
52}
53
54impl_int!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
55
56macro_rules! impl_float {
57	($($ty:ident),*) => {
58		$(
59			impl PartialEnum for $ty {
60				fn pred(&self) -> Option<Self> {
61					None
62				}
63
64				fn succ(&self) -> Option<Self> {
65					None
66				}
67			}
68		)*
69	};
70}
71
72impl_float!(f32, f64);