1use crate::NonZeroChar;
2use core::ops::RangeInclusive;
3use core::iter::FusedIterator;
4
5#[inline]
6fn pack(x: Option<char>) -> Option<NonZeroChar> {
7 x.map(|ch| {
8 unsafe { NonZeroChar::new_unchecked(ch) }
10 })
11}
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash)]
14pub struct RangeInclusiveIter {
15 pub(crate) iter: <RangeInclusive<char> as IntoIterator>::IntoIter,
16}
17
18impl RangeInclusiveIter {
19 pub fn is_empty(&self) -> bool {
20 self.iter.is_empty()
21 }
22
23 pub fn contains<U>(&self, item: &U) -> bool
24 where U: PartialOrd<char> + ?Sized,
25 char: PartialOrd<U>,
26 {
27 self.iter.contains(item)
28 }
29}
30
31impl Default for RangeInclusiveIter {
32 fn default() -> Self {
33 let min = NonZeroChar::MIN.get();
34 let iter = min..=min;
35 Self { iter: iter.into_iter() }
36 }
37}
38
39impl Iterator for RangeInclusiveIter {
40 type Item = NonZeroChar;
41
42 #[inline]
43 fn next(&mut self) -> Option<Self::Item> {
44 pack(self.iter.next())
45 }
46
47 #[inline]
48 fn nth(&mut self, n: usize) -> Option<Self::Item> {
49 pack(self.iter.nth(n))
50 }
51
52 #[inline]
53 fn min(self) -> Option<Self::Item> {
54 pack(self.iter.min())
55 }
56
57 #[inline]
58 fn max(self) -> Option<Self::Item> {
59 pack(self.iter.max())
60 }
61
62 #[inline]
63 fn is_sorted(self) -> bool {
64 self.iter.is_sorted()
65 }
66
67 #[inline]
68 fn size_hint(&self) -> (usize, Option<usize>) {
69 self.iter.size_hint()
70 }
71}
72
73impl DoubleEndedIterator for RangeInclusiveIter {
74 #[inline]
75 fn next_back(&mut self) -> Option<Self::Item> {
76 pack(self.iter.next_back())
77 }
78
79 #[inline]
80 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
81 pack(self.iter.nth_back(n))
82 }
83}
84
85impl FusedIterator for RangeInclusiveIter { }
86
87#[test]
88fn iter_all() {
89 let mut last = '\0';
90 for ch in NonZeroChar::MIN.iter_inclusive(NonZeroChar::MAX) {
91 last = ch.get();
92 }
93 assert_ne!(last, '\0')
94}