Skip to main content

hb_subset/
set.rs

1use std::{
2    any::TypeId,
3    fmt,
4    hash::Hash,
5    iter::{FilterMap, FusedIterator},
6    marker::PhantomData,
7    ops::{Bound, RangeBounds},
8};
9
10use crate::{sys, AllocationError, Tag};
11
12/// Set objects represent a mathematical set of integer values.
13///
14/// Sets are used in non-shaping APIs to query certain sets of characters or glyphs, or other integer values.
15pub struct Set<'a, T>(InnerSet, PhantomData<(&'a (), T)>);
16
17impl<T> Set<'static, T> {
18    /// Creates a new, initially empty set.
19    #[doc(alias = "hb_set_create")]
20    pub fn new() -> Result<Self, AllocationError> {
21        let set = unsafe { sys::hb_set_create() };
22        if set.is_null() {
23            return Err(AllocationError);
24        }
25        Ok(Self(InnerSet(set), PhantomData))
26    }
27}
28
29impl<'a, T> Set<'a, T> {
30    /// Tests whether set is empty i.e. contains no elements.
31    #[doc(alias = "hb_set_is_empty")]
32    pub fn is_empty(&self) -> bool {
33        (unsafe { sys::hb_set_is_empty(self.as_raw()) }) != 0
34    }
35
36    /// Returns the number of elements in the set.
37    ///
38    /// Note that this returns the number of elements in the underlying raw set over [`u32`], *not* the number of
39    /// elements that can be represented as `T`. This is especially evident when the set is over [`char`]s and invalid
40    /// code points have been added with [`Self::insert_range`].
41    /// ```
42    /// # use hb_subset::CharSet;
43    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
44    /// let mut set = CharSet::new()?;
45    /// set.insert_range('\u{D7FF}'..'\u{E000}'); // Add all surrogate pairs (and \u{D7FF} for technical reasons)
46    /// assert_eq!(set.len(), 2049);
47    /// # Ok(())
48    /// # }
49    /// ```
50    #[doc(alias = "hb_set_get_population")]
51    pub fn len(&self) -> usize {
52        (unsafe { sys::hb_set_get_population(self.as_raw()) }) as usize
53    }
54
55    /// Clears out the contents of a set.
56    #[doc(alias = "hb_set_clear")]
57    pub fn clear(&mut self) {
58        unsafe { sys::hb_set_clear(self.as_raw()) }
59    }
60
61    /// Makes the contents of `self` equal to the contents of `other`.
62    #[doc(alias = "hb_set_set")]
63    pub fn copy_from(&mut self, other: &Self) {
64        unsafe { sys::hb_set_set(self.as_raw(), other.as_raw()) }
65    }
66
67    /// Tests whether `self` contains `other` set.
68    #[doc(alias = "hb_set_is_subset")]
69    pub fn contains_set(&self, other: &Self) -> bool {
70        (unsafe { sys::hb_set_is_subset(other.as_raw(), self.as_raw()) }) != 0
71    }
72
73    /// Constructs a copy of the set with `'static` lifetime.
74    #[doc(alias = "hb_set_copy")]
75    pub fn clone_static(&self) -> Set<'static, T> {
76        Set(
77            InnerSet(unsafe { sys::hb_set_copy(self.as_raw()) }),
78            PhantomData,
79        )
80    }
81}
82
83impl<'a, T> Set<'a, T>
84where
85    T: Into<u32>,
86{
87    /// Tests whether a value belongs to set.
88    #[doc(alias = "hb_set_has")]
89    pub fn contains(&self, value: T) -> bool {
90        (unsafe { sys::hb_set_has(self.as_raw(), value.into()) }) != 0
91    }
92
93    /// Inserts a value to set.
94    ///
95    /// # Panics
96    ///
97    /// Will panic if `value` is [`sys::HB_SET_VALUE_INVALID`].
98    #[doc(alias = "hb_set_add")]
99    pub fn insert(&mut self, value: T) {
100        let value = value.into();
101        assert_ne!(value, sys::HB_SET_VALUE_INVALID);
102        unsafe { sys::hb_set_add(self.as_raw(), value) }
103    }
104
105    /// Removes a value from set.
106    #[doc(alias = "hb_set_del")]
107    pub fn remove(&mut self, value: T) {
108        unsafe { sys::hb_set_del(self.as_raw(), value.into()) }
109    }
110
111    /// Converts a range to inclusive bounds.
112    fn range_to_bounds(range: impl RangeBounds<T>) -> Option<(u32, u32)>
113    where
114        T: Clone + 'static,
115    {
116        fn bound_to_u32<T: Clone + Into<u32>>(bound: Bound<&T>) -> Bound<u32> {
117            match bound {
118                Bound::Included(b) => Bound::Included(b.clone().into()),
119                Bound::Excluded(b) => Bound::Excluded(b.clone().into()),
120                Bound::Unbounded => Bound::Unbounded,
121            }
122        }
123        let lower = match bound_to_u32(range.start_bound()) {
124            Bound::Included(lower) => lower,
125            Bound::Excluded(lower) => {
126                if lower == u32::MAX {
127                    return None;
128                } else {
129                    lower + 1
130                }
131            }
132            Bound::Unbounded => 0,
133        };
134        let upper = match bound_to_u32(range.end_bound()) {
135            Bound::Included(upper) => {
136                assert_ne!(upper, sys::HB_SET_VALUE_INVALID);
137                upper
138            }
139            Bound::Excluded(upper) => {
140                if upper == 0 {
141                    return None;
142                } else {
143                    upper - 1
144                }
145            }
146            Bound::Unbounded => {
147                // Optimization to allow half-open intervals with character sets
148                if TypeId::of::<T>() == TypeId::of::<char>() {
149                    char::MAX as u32
150                } else {
151                    u32::MAX - 1
152                }
153            }
154        };
155        if upper < lower {
156            return None;
157        }
158        Some((lower, upper))
159    }
160
161    /// Inserts a range of values to set.
162    ///
163    /// # Panics
164    ///
165    /// Will panic if `range` explicitly contains [`sys::HB_SET_VALUE_INVALID`]:
166    /// ```should_panic
167    /// # use hb_subset::U32Set;
168    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
169    /// U32Set::new()?.insert_range(u32::MAX-10..=u32::MAX);
170    /// # Ok(())
171    /// # }
172    /// ```
173    /// These still work:
174    /// ```
175    /// # use hb_subset::U32Set;
176    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
177    /// U32Set::new()?.insert_range(u32::MAX-10..);
178    /// U32Set::new()?.insert_range(u32::MAX-10..u32::MAX);
179    /// # Ok(())
180    /// # }
181    /// ```
182    #[doc(alias = "hb_set_add_range")]
183    pub fn insert_range(&mut self, range: impl RangeBounds<T>)
184    where
185        T: Clone + 'static,
186    {
187        let Some((lower, upper)) = Self::range_to_bounds(range) else {
188            return;
189        };
190        unsafe { sys::hb_set_add_range(self.as_raw(), lower, upper) }
191    }
192
193    /// Removes a range of values from set.
194    #[doc(alias = "hb_set_del_range")]
195    pub fn remove_range(&mut self, range: impl RangeBounds<T>)
196    where
197        T: Clone + 'static,
198    {
199        // TODO: Assert that sys::HB_SET_VALUE_INVALID is u32::MAX like it should be
200        #[allow(clippy::assertions_on_constants, clippy::absurd_extreme_comparisons)]
201        const _: () = assert!(u32::MAX <= sys::HB_SET_VALUE_INVALID);
202        let Some((lower, upper)) = Self::range_to_bounds(range) else {
203            return;
204        };
205        unsafe { sys::hb_set_del_range(self.as_raw(), lower, upper) }
206    }
207}
208
209impl<'a, T> Set<'a, T>
210where
211    T: TryFrom<u32>,
212{
213    /// Constructs an iterator over the set.
214    #[doc(alias = "hb_set_next")]
215    #[doc(alias = "hb_set_previous")]
216    pub fn iter(&self) -> SetIter<'_, 'a, T> {
217        SetIter(SetIterImpl::new(self).filter_map(|v| v.try_into().ok()))
218    }
219}
220
221impl<'a, T> Set<'a, T> {
222    /// Converts the set into raw [`sys::hb_set_t`] pointer.
223    ///
224    /// This method transfers the ownership of the set to the caller. It is up to the caller to call
225    /// [`sys::hb_set_destroy`] to free the pointer, or call [`Self::from_raw`] to convert it back into [`Set`].
226    pub fn into_raw(self) -> *mut sys::hb_set_t {
227        let ptr = self.0 .0;
228        std::mem::forget(self);
229        ptr
230    }
231
232    /// Exposes the raw inner pointer without transferring the ownership.
233    ///
234    /// Unlike [`Self::into_raw`], this method does not transfer the ownership of the pointer to the caller.
235    pub fn as_raw(&self) -> *mut sys::hb_set_t {
236        self.0 .0
237    }
238
239    /// Constructs a set from raw [`sys::hb_set_t`] pointer.
240    ///
241    /// # Safety
242    /// The given `set` pointer must either be constructed by some Harfbuzz function, or be returned from
243    /// [`Self::into_raw`].
244    pub unsafe fn from_raw(set: *mut sys::hb_set_t) -> Self {
245        Self(InnerSet(set), PhantomData)
246    }
247}
248
249impl<'a, T> Hash for Set<'a, T> {
250    #[doc(alias = "hb_set_hash")]
251    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
252        unsafe { sys::hb_set_hash(self.as_raw()) }.hash(state);
253    }
254}
255
256impl<'a, T> PartialEq for Set<'a, T> {
257    #[doc(alias = "hb_set_is_equal")]
258    fn eq(&self, other: &Self) -> bool {
259        (unsafe { sys::hb_set_is_equal(self.as_raw(), other.as_raw()) }) != 0
260    }
261}
262
263impl<'a, T> Eq for Set<'a, T> where T: Eq {}
264
265impl<'a, T> Clone for Set<'a, T> {
266    fn clone(&self) -> Self {
267        self.clone_static()
268    }
269}
270
271impl<'a, T> fmt::Debug for Set<'a, T>
272where
273    T: TryFrom<u32> + fmt::Debug,
274{
275    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276        f.debug_set().entries(self).finish()
277    }
278}
279
280impl<'a, T> FromIterator<T> for Set<'a, T>
281where
282    T: Into<u32>,
283{
284    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
285        let mut set = Set::new().unwrap();
286        for item in iter {
287            set.insert(item);
288        }
289        set
290    }
291}
292
293impl<'s, 'a, T> IntoIterator for &'s Set<'a, T>
294where
295    T: TryFrom<u32>,
296{
297    type Item = T;
298    type IntoIter = SetIter<'s, 'a, T>;
299
300    fn into_iter(self) -> Self::IntoIter {
301        self.iter()
302    }
303}
304
305/// Iterator over [`Set`].
306///
307/// Use [`Set::iter`] to construct a [`SetIter`].
308pub struct SetIter<'s, 'a, T>(SetIterFilter<'s, 'a, T>);
309type SetIterFilter<'s, 'a, T> = FilterMap<SetIterImpl<'s, 'a, T>, fn(u32) -> Option<T>>;
310
311impl<'s, 'a, T> Iterator for SetIter<'s, 'a, T>
312where
313    T: TryFrom<u32>,
314{
315    type Item = T;
316
317    fn next(&mut self) -> Option<Self::Item> {
318        self.0.next()
319    }
320}
321
322impl<'s, 'a, T> DoubleEndedIterator for SetIter<'s, 'a, T>
323where
324    T: TryFrom<u32>,
325{
326    fn next_back(&mut self) -> Option<Self::Item> {
327        self.0.next_back()
328    }
329}
330
331impl<'s, 'a, T> FusedIterator for SetIter<'s, 'a, T> where T: TryFrom<u32> {}
332
333/// Actual implementation for [`SetIter`].
334///
335/// This implementation does not care whether the target type can or cannot represent the target type. It just returns
336/// [`u32`], no matter what. [`SetIter`] is responsible to then filter out invalid values.
337struct SetIterImpl<'s, 'a, T>(&'s Set<'a, T>, u32, u32);
338
339impl<'s, 'a, T> SetIterImpl<'s, 'a, T> {
340    const LAST_VALUE: u32 = sys::HB_SET_VALUE_INVALID - 1;
341    fn new(set: &'s Set<'a, T>) -> Self {
342        #[allow(clippy::assertions_on_constants, clippy::absurd_extreme_comparisons)]
343        const _: () = assert!(u32::MAX == sys::HB_SET_VALUE_INVALID);
344        Self(set, sys::HB_SET_VALUE_INVALID, sys::HB_SET_VALUE_INVALID)
345    }
346
347    fn mark_ended(&mut self) {
348        self.1 = Self::LAST_VALUE;
349        self.2 = 0;
350    }
351}
352
353impl<'s, 'a, T> Iterator for SetIterImpl<'s, 'a, T> {
354    type Item = u32;
355
356    fn next(&mut self) -> Option<Self::Item> {
357        match self.1 {
358            Self::LAST_VALUE => {
359                // Previously last possible value was returned, so the iterator must have been exhausted
360                None
361            }
362            _ => {
363                let has_value =
364                    (unsafe { sys::hb_set_next(self.0.as_raw(), &mut self.1 as *mut u32) }) != 0;
365                if has_value {
366                    if self.1 >= self.2 {
367                        self.mark_ended();
368                        None
369                    } else {
370                        Some(self.1)
371                    }
372                } else {
373                    self.mark_ended();
374                    None
375                }
376            }
377        }
378    }
379}
380
381impl<'s, 'a, T> DoubleEndedIterator for SetIterImpl<'s, 'a, T> {
382    fn next_back(&mut self) -> Option<Self::Item> {
383        match self.2 {
384            0 => {
385                // 0 has been returned, so nothing can be returned from this iterator anymore
386                None
387            }
388            _ => {
389                let has_value =
390                    (unsafe { sys::hb_set_previous(self.0.as_raw(), &mut self.2 as *mut u32) })
391                        != 0;
392                if has_value {
393                    if self.1 != sys::HB_SET_VALUE_INVALID && self.1 >= self.2 {
394                        self.mark_ended();
395                        None
396                    } else {
397                        Some(self.2)
398                    }
399                } else {
400                    self.mark_ended();
401                    None
402                }
403            }
404        }
405    }
406}
407
408/// Implementation detail of Set to hide source reference from drop check.
409///
410/// If the pointer was directly contained in [`Set`] with `Drop` implemented, the following code would not compile:
411/// ```
412/// # use hb_subset::*;
413/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
414/// let mut subset = SubsetInput::new()?;
415/// let mut unicode_set = subset.unicode_set();
416/// // drop(unicode_set);                               // This needs to be called to delete unicode_set,
417/// # let font = FontFace::new(Blob::from_bytes(&[])?)?;
418/// let new_font = subset.subset_font(&font)?;  // otherwise this line would not compile as unicode_set is already
419///                                                     // holding a mutable reference to subset.
420/// # Ok(())
421/// # }
422/// ```
423struct InnerSet(*mut sys::hb_set_t);
424
425impl Drop for InnerSet {
426    #[doc(alias = "hb_set_destroy")]
427    fn drop(&mut self) {
428        unsafe { sys::hb_set_destroy(self.0) }
429    }
430}
431
432/// Set over unicodecode points.
433pub type CharSet<'a> = Set<'a, char>;
434
435/// Set over [`u32`]s, except [`u32::MAX`].
436///
437/// Trying to insert [`u32::MAX`] will cause a panic. [`U32Set`] is commonly used to represent sets of glyph IDs.
438pub type U32Set<'a> = Set<'a, u32>;
439
440/// Set over [`Tag`]s.
441pub type TagSet<'a> = Set<'a, Tag>;
442
443#[cfg(test)]
444mod tests {
445    use super::*;
446
447    #[test]
448    fn is_empty_works() {
449        let mut set = U32Set::new().unwrap();
450        assert!(set.is_empty());
451        assert!(set.is_empty());
452        set.insert(10);
453        assert!(!set.is_empty());
454        set.insert(20);
455        assert!(!set.is_empty());
456        set.remove(10);
457        assert!(!set.is_empty());
458        set.remove(20);
459        assert!(set.is_empty());
460    }
461
462    #[test]
463    fn len_works() {
464        let mut set = U32Set::new().unwrap();
465        assert_eq!(set.len(), 0);
466        set.insert(10);
467        assert_eq!(set.len(), 1);
468        set.insert_range(5..15);
469        assert_eq!(set.len(), 10);
470        set.remove(13);
471        assert_eq!(set.len(), 9);
472    }
473
474    #[test]
475    fn clear_empties_set() {
476        let mut set = U32Set::new().unwrap();
477        set.insert_range(123..456);
478        assert!(!set.is_empty());
479        assert_eq!(set.len(), 333);
480        set.clear();
481        assert!(set.is_empty());
482        assert_eq!(set.len(), 0);
483    }
484
485    #[test]
486    #[should_panic]
487    fn cannot_insert_u32_max() {
488        let mut set = U32Set::new().unwrap();
489        set.insert(u32::MAX);
490    }
491
492    #[test]
493    #[should_panic]
494    fn cannot_insert_range_u32_max() {
495        let mut set = U32Set::new().unwrap();
496        set.insert_range(..=u32::MAX);
497    }
498
499    #[test]
500    fn does_not_contain_u32_max() {
501        let mut set = U32Set::new().unwrap();
502        set.insert_range(..);
503        assert!(!set.contains(u32::MAX));
504    }
505
506    #[test]
507    fn can_contain_max_value() {
508        let mut set = U32Set::new().unwrap();
509        set.insert(u32::MAX - 1);
510        assert!(set.contains(u32::MAX - 1));
511        assert!(!set.is_empty());
512        assert_eq!(set.len(), 1);
513    }
514
515    #[test]
516    fn copy_from_works() {
517        let mut a = U32Set::new().unwrap();
518        a.insert(5);
519        let mut b = U32Set::new().unwrap();
520        b.insert(10);
521        assert_eq!(a.iter().collect::<Vec<_>>(), [5]);
522        assert_eq!(b.iter().collect::<Vec<_>>(), [10]);
523        a.copy_from(&b);
524        assert_eq!(a.iter().collect::<Vec<_>>(), [10]);
525        b.insert(1);
526        assert_eq!(a.iter().collect::<Vec<_>>(), [10]);
527        a.remove(10);
528        assert_eq!(b.iter().collect::<Vec<_>>(), [1, 10]);
529    }
530
531    #[test]
532    fn contains_its_subset() {
533        let mut a = U32Set::new().unwrap();
534        a.insert_range(5..=15);
535        a.insert_range(55..=65);
536        assert!(a.contains_set(&a));
537        let mut b = U32Set::new().unwrap();
538        b.insert_range(7..=14);
539        b.insert(60);
540        assert!(b.contains_set(&b));
541        assert!(a.contains_set(&b));
542        assert!(!b.contains_set(&a));
543        b.insert(65);
544        assert!(a.contains_set(&b));
545        b.insert(66);
546        assert!(!a.contains_set(&b));
547        assert!(!b.contains_set(&a));
548    }
549
550    #[test]
551    fn contains_inserted_values() {
552        let mut set = U32Set::new().unwrap();
553        set.insert(1);
554        assert!(!set.contains(3));
555        set.insert(1);
556        assert!(!set.contains(3));
557        set.insert(3);
558        assert!(set.contains(3));
559        set.remove(1);
560        assert!(set.contains(3));
561        set.remove(3);
562        assert!(!set.contains(3));
563    }
564
565    #[test]
566    fn range_insertions_and_deletions_work() {
567        let mut set = U32Set::new().unwrap();
568        set.insert_range(0..100);
569        assert_eq!(set.len(), 100);
570        set.remove_range(21..=30);
571        assert_eq!(set.len(), 90);
572        set.remove_range(90..200);
573        assert_eq!(set.len(), 80);
574    }
575
576    #[test]
577    fn convert_into_raw_and_back() {
578        let set = U32Set::new().unwrap();
579        let set_ptr = set.into_raw();
580        let set = unsafe { U32Set::from_raw(set_ptr) };
581        drop(set);
582    }
583
584    #[test]
585    fn equal_works() {
586        let mut a = U32Set::new().unwrap();
587        for i in 0..10 {
588            a.insert(i);
589        }
590        assert_eq!(a, a);
591        let mut b = U32Set::new().unwrap();
592        assert_ne!(a, b);
593        b.insert_range(0..10);
594        assert_eq!(a, b);
595    }
596
597    #[test]
598    fn debug_works() {
599        let mut set = U32Set::new().unwrap();
600        set.insert_range(3..=5);
601        set.insert(7);
602        let mut str = String::new();
603        use fmt::Write;
604        write!(&mut str, "{set:?}").unwrap();
605        assert_eq!(str, "{3, 4, 5, 7}");
606    }
607
608    #[test]
609    fn cloned_set_does_not_modify_original() {
610        let mut a = U32Set::new().unwrap();
611        a.insert(3);
612        a.insert(5);
613        let mut b = a.clone();
614        assert_eq!(a.len(), 2);
615        assert_eq!(b.len(), 2);
616        a.insert(10);
617        assert_eq!(a.len(), 3);
618        assert_eq!(b.len(), 2);
619        b.remove(3);
620        assert_eq!(a.len(), 3);
621        assert_eq!(b.len(), 1);
622    }
623
624    #[test]
625    fn iter_works() {
626        let mut set = U32Set::new().unwrap();
627        assert!(set.iter().next().is_none());
628        set.insert(0);
629        assert_eq!(set.iter().collect::<Vec<_>>(), [0]);
630        set.insert(0);
631        assert_eq!(set.iter().collect::<Vec<_>>(), [0]);
632        set.insert(10);
633        assert_eq!(set.iter().collect::<Vec<_>>(), [0, 10]);
634        set.insert_range(6..12);
635        assert_eq!(set.iter().collect::<Vec<_>>(), [0, 6, 7, 8, 9, 10, 11]);
636        set.remove_range(8..=10);
637        assert_eq!(set.iter().collect::<Vec<_>>(), [0, 6, 7, 11]);
638    }
639
640    #[test]
641    fn iter_near_max_works() {
642        let mut set = U32Set::new().unwrap();
643        set.insert(u32::MAX - 3);
644        set.insert(u32::MAX - 2);
645        assert_eq!(set.iter().collect::<Vec<_>>(), [u32::MAX - 3, u32::MAX - 2]);
646        set.insert(u32::MAX - 1);
647        assert_eq!(
648            set.iter().collect::<Vec<_>>(),
649            [u32::MAX - 3, u32::MAX - 2, u32::MAX - 1]
650        );
651        set.clear();
652        assert!(set.is_empty());
653        set.insert_range((Bound::Excluded(u32::MAX - 3), Bound::Unbounded));
654        assert_eq!(set.iter().collect::<Vec<_>>(), [u32::MAX - 2, u32::MAX - 1]);
655    }
656
657    #[test]
658    fn iter_of_invalid_codepoints_works() {
659        let mut set = CharSet::new().unwrap();
660        set.insert_range('\u{D7FF}'..'\u{E001}'); // Add all surrogate pairs, and then some
661        assert_eq!(set.iter().collect::<Vec<_>>(), ['\u{D7FF}', '\u{E000}']);
662
663        let mut set = CharSet::new().unwrap();
664        set.insert_range('\u{10FFFF}'..);
665        assert_eq!(set.iter().collect::<Vec<_>>(), ['\u{10FFFF}']);
666    }
667
668    #[test]
669    fn iter_is_fused() {
670        fn assert_fused(mut iter: impl Iterator) {
671            while let Some(_) = iter.next() {}
672            for _ in 0..10 {
673                assert!(iter.next().is_none());
674            }
675            // Believe that iterator is fused after it has returned 11 Nones
676        }
677        let mut set = U32Set::new().unwrap();
678        assert_fused(set.iter());
679        assert_fused(set.iter().rev());
680        set.insert(0);
681        assert_fused(set.iter());
682        assert_fused(set.iter().rev());
683        set.insert(1);
684        assert_fused(set.iter());
685        assert_fused(set.iter().rev());
686        set.insert(u32::MAX - 3);
687        assert_fused(set.iter());
688        assert_fused(set.iter().rev());
689        set.insert(u32::MAX - 2);
690        assert_fused(set.iter());
691        assert_fused(set.iter().rev());
692        set.insert(u32::MAX - 1);
693        assert_fused(set.iter());
694        assert_fused(set.iter().rev());
695
696        let mut iter = set.iter();
697        assert_eq!(iter.next_back(), Some(u32::MAX - 1));
698        assert_fused(iter);
699
700        let mut iter = set.iter().rev();
701        assert_eq!(iter.next_back(), Some(0));
702        assert_fused(iter);
703    }
704
705    #[test]
706    fn iter_next_back_works() {
707        let mut set = U32Set::new().unwrap();
708        assert!(set.iter().next().is_none());
709        set.insert(0);
710        set.insert_range(6..12);
711        assert_eq!(
712            set.iter().rev().collect::<Vec<_>>(),
713            [11, 10, 9, 8, 7, 6, 0]
714        );
715        set.remove_range(8..=10);
716        assert_eq!(set.iter().rev().collect::<Vec<_>>(), [11, 7, 6, 0]);
717
718        let mut iter = set.iter();
719        assert_eq!(iter.next(), Some(0));
720        assert_eq!(iter.next_back(), Some(11));
721        assert_eq!(iter.next_back(), Some(7));
722        assert_eq!(iter.next(), Some(6));
723        assert_eq!(iter.next(), None);
724        assert_eq!(iter.next_back(), None);
725
726        let mut iter = set.iter();
727        assert_eq!(iter.next_back(), Some(11));
728        assert_eq!(iter.next_back(), Some(7));
729        assert_eq!(iter.next(), Some(0));
730        assert_eq!(iter.next(), Some(6));
731        assert_eq!(iter.next_back(), None);
732        assert_eq!(iter.next(), None);
733
734        let mut iter = set.iter();
735        assert_eq!(iter.next_back(), Some(11));
736        assert_eq!(iter.next_back(), Some(7));
737        assert_eq!(iter.next(), Some(0));
738        assert_eq!(iter.next_back(), Some(6));
739        assert_eq!(iter.next_back(), None);
740        assert_eq!(iter.next(), None);
741
742        let mut iter = set.iter();
743        assert_eq!(iter.next_back(), Some(11));
744        assert_eq!(iter.next_back(), Some(7));
745        assert_eq!(iter.next(), Some(0));
746        assert_eq!(iter.next_back(), Some(6));
747        assert_eq!(iter.next(), None);
748        assert_eq!(iter.next_back(), None);
749    }
750}