/rust/registry/src/index.crates.io-6f17d22bba15001f/roaring-0.10.10/src/bitmap/util.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use core::ops::{Bound, RangeBounds, RangeInclusive}; |
2 | | |
3 | | /// Returns the container key and the index |
4 | | /// in this container for a given integer. |
5 | | #[inline] |
6 | 0 | pub fn split(value: u32) -> (u16, u16) { |
7 | 0 | ((value >> 16) as u16, value as u16) |
8 | 0 | } Unexecuted instantiation: roaring::bitmap::util::split Unexecuted instantiation: roaring::bitmap::util::split |
9 | | |
10 | | /// Returns the original integer from the container |
11 | | /// key and the index of it in the container. |
12 | | #[inline] |
13 | 0 | pub fn join(high: u16, low: u16) -> u32 { |
14 | 0 | (u32::from(high) << 16) + u32::from(low) |
15 | 0 | } |
16 | | |
17 | | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
18 | | pub enum ConvertRangeError { |
19 | | Empty, |
20 | | StartGreaterThanEnd, |
21 | | StartAndEndEqualExcluded, |
22 | | } |
23 | | |
24 | | /// Convert a `RangeBounds<u32>` object to `RangeInclusive<u32>`, |
25 | 0 | pub fn convert_range_to_inclusive<R>(range: R) -> Result<RangeInclusive<u32>, ConvertRangeError> |
26 | 0 | where |
27 | 0 | R: RangeBounds<u32>, |
28 | 0 | { |
29 | 0 | let start_bound = range.start_bound().cloned(); |
30 | 0 | let end_bound = range.end_bound().cloned(); |
31 | 0 | match (start_bound, end_bound) { |
32 | 0 | (Bound::Excluded(s), Bound::Excluded(e)) if s == e => { |
33 | 0 | Err(ConvertRangeError::StartAndEndEqualExcluded) |
34 | | } |
35 | 0 | (Bound::Included(s) | Bound::Excluded(s), Bound::Included(e) | Bound::Excluded(e)) |
36 | 0 | if s > e => |
37 | | { |
38 | 0 | Err(ConvertRangeError::StartGreaterThanEnd) |
39 | | } |
40 | | _ => { |
41 | 0 | let start = match start_bound { |
42 | 0 | Bound::Included(s) => s, |
43 | 0 | Bound::Excluded(s) => s.checked_add(1).ok_or(ConvertRangeError::Empty)?, |
44 | 0 | Bound::Unbounded => 0, |
45 | | }; |
46 | | |
47 | 0 | let end = match end_bound { |
48 | 0 | Bound::Included(e) => e, |
49 | 0 | Bound::Excluded(e) => e.checked_sub(1).ok_or(ConvertRangeError::Empty)?, |
50 | 0 | Bound::Unbounded => u32::MAX, |
51 | | }; |
52 | | |
53 | 0 | if start > end { |
54 | | // This handles e.g. `x..x`: we've ruled out `start > end` overall, so a value must |
55 | | // have been changed via exclusion. |
56 | 0 | Err(ConvertRangeError::Empty) |
57 | | } else { |
58 | 0 | Ok(start..=end) |
59 | | } |
60 | | } |
61 | | } |
62 | 0 | } |
63 | | |
64 | | #[cfg(test)] |
65 | | mod test { |
66 | | use super::{convert_range_to_inclusive, join, split, ConvertRangeError}; |
67 | | use core::ops::Bound; |
68 | | |
69 | | #[test] |
70 | | fn test_split_u32() { |
71 | | assert_eq!((0x0000u16, 0x0000u16), split(0x0000_0000u32)); |
72 | | assert_eq!((0x0000u16, 0x0001u16), split(0x0000_0001u32)); |
73 | | assert_eq!((0x0000u16, 0xFFFEu16), split(0x0000_FFFEu32)); |
74 | | assert_eq!((0x0000u16, 0xFFFFu16), split(0x0000_FFFFu32)); |
75 | | assert_eq!((0x0001u16, 0x0000u16), split(0x0001_0000u32)); |
76 | | assert_eq!((0x0001u16, 0x0001u16), split(0x0001_0001u32)); |
77 | | assert_eq!((0xFFFFu16, 0xFFFEu16), split(0xFFFF_FFFEu32)); |
78 | | assert_eq!((0xFFFFu16, 0xFFFFu16), split(0xFFFF_FFFFu32)); |
79 | | } |
80 | | |
81 | | #[test] |
82 | | fn test_join_u32() { |
83 | | assert_eq!(0x0000_0000u32, join(0x0000u16, 0x0000u16)); |
84 | | assert_eq!(0x0000_0001u32, join(0x0000u16, 0x0001u16)); |
85 | | assert_eq!(0x0000_FFFEu32, join(0x0000u16, 0xFFFEu16)); |
86 | | assert_eq!(0x0000_FFFFu32, join(0x0000u16, 0xFFFFu16)); |
87 | | assert_eq!(0x0001_0000u32, join(0x0001u16, 0x0000u16)); |
88 | | assert_eq!(0x0001_0001u32, join(0x0001u16, 0x0001u16)); |
89 | | assert_eq!(0xFFFF_FFFEu32, join(0xFFFFu16, 0xFFFEu16)); |
90 | | assert_eq!(0xFFFF_FFFFu32, join(0xFFFFu16, 0xFFFFu16)); |
91 | | } |
92 | | |
93 | | #[test] |
94 | | #[allow(clippy::reversed_empty_ranges)] |
95 | | fn test_convert_range_to_inclusive() { |
96 | | assert_eq!(Ok(1..=5), convert_range_to_inclusive(1..6)); |
97 | | assert_eq!(Ok(1..=u32::MAX), convert_range_to_inclusive(1..)); |
98 | | assert_eq!(Ok(0..=u32::MAX), convert_range_to_inclusive(..)); |
99 | | assert_eq!(Ok(16..=16), convert_range_to_inclusive(16..=16)); |
100 | | assert_eq!( |
101 | | Ok(11..=19), |
102 | | convert_range_to_inclusive((Bound::Excluded(10), Bound::Excluded(20))) |
103 | | ); |
104 | | |
105 | | assert_eq!(Err(ConvertRangeError::Empty), convert_range_to_inclusive(0..0)); |
106 | | assert_eq!(Err(ConvertRangeError::Empty), convert_range_to_inclusive(5..5)); |
107 | | assert_eq!(Err(ConvertRangeError::StartGreaterThanEnd), convert_range_to_inclusive(1..0)); |
108 | | assert_eq!(Err(ConvertRangeError::StartGreaterThanEnd), convert_range_to_inclusive(10..5)); |
109 | | assert_eq!( |
110 | | Err(ConvertRangeError::Empty), |
111 | | convert_range_to_inclusive((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX))) |
112 | | ); |
113 | | assert_eq!( |
114 | | Err(ConvertRangeError::StartAndEndEqualExcluded), |
115 | | convert_range_to_inclusive((Bound::Excluded(u32::MAX), Bound::Excluded(u32::MAX))) |
116 | | ); |
117 | | assert_eq!( |
118 | | Err(ConvertRangeError::Empty), |
119 | | convert_range_to_inclusive((Bound::Excluded(0), Bound::Included(0))) |
120 | | ); |
121 | | } |
122 | | } |