@@ -581,6 +581,34 @@ impl<T: Idx> ThinBitSet<T> {
581
581
}
582
582
}
583
583
584
+ /// Returns `Some(elem)` if the set contains exactly one elemement otherwise returns `None`.
585
+ #[ inline( always) ]
586
+ pub fn only_one_elem ( & self ) -> Option < T > {
587
+ if self . is_inline ( ) {
588
+ let word = unsafe { self . inline } ^ Self :: IS_INLINE_TAG_BIT ;
589
+ if word. is_power_of_two ( ) { Some ( T :: new ( word. trailing_zeros ( ) as usize ) ) } else { None }
590
+ } else if self . is_empty_unallocated ( ) {
591
+ None
592
+ } else {
593
+ let words = self . on_heap ( ) . unwrap ( ) . as_slice ( ) ;
594
+ let mut found_elem = None ;
595
+ for ( i, & word) in words. iter ( ) . enumerate ( ) {
596
+ if word > 0 {
597
+ if found_elem. is_some ( ) {
598
+ return None ;
599
+ }
600
+ if word. is_power_of_two ( ) {
601
+ found_elem =
602
+ Some ( T :: new ( i * WORD_BITS as usize + word. trailing_zeros ( ) as usize ) ) ;
603
+ } else {
604
+ return None ;
605
+ }
606
+ }
607
+ }
608
+ found_elem
609
+ }
610
+ }
611
+
584
612
#[ inline]
585
613
pub fn insert_range ( & mut self , range : Range < T > ) {
586
614
if let Some ( end) = range. end . index ( ) . checked_sub ( 1 ) {
@@ -1633,6 +1661,14 @@ mod tests {
1633
1661
assert_eq ! ( set_1. count( ) , set_1_reference. iter( ) . filter( |&&x| x) . count( ) ) ;
1634
1662
assert_eq ! ( set_2. count( ) , set_2_reference. iter( ) . filter( |&&x| x) . count( ) ) ;
1635
1663
1664
+ // Check `only_one_elem()`.
1665
+ if let Some ( elem) = set_1. only_one_elem ( ) {
1666
+ assert_eq ! ( set_1. count( ) , 1 ) ;
1667
+ assert_eq ! ( elem, set_1. iter( ) . next( ) . unwrap( ) ) ;
1668
+ } else {
1669
+ assert_ne ! ( set_1. count( ) , 1 ) ;
1670
+ }
1671
+
1636
1672
// Check `last_set_in()`.
1637
1673
if domain_size > 0 {
1638
1674
let range = rng. sample_range ( domain_size - 1 ) ;
0 commit comments