1use core::ops::{Bound, Range, RangeBounds};
2
3pub(crate) fn third<A, B, C>(t: (A, B, C)) -> C {
4 t.2
5}
6
7#[track_caller]
8pub(crate) fn simplify_range<R>(range: R, len: usize) -> Range<usize>
9where
10 R: RangeBounds<usize>,
11{
12 let start = match range.start_bound() {
13 Bound::Unbounded => 0,
14 Bound::Included(&i) if i <= len => i,
15 Bound::Excluded(&i) if i < len => i + 1,
16 Bound::Included(i) | Bound::Excluded(i) => {
17 panic!("range start index {i} out of range for slice of length {len}")
18 }
19 };
20 let end = match range.end_bound() {
21 Bound::Unbounded => len,
22 Bound::Excluded(&i) if i <= len => i,
23 Bound::Included(&i) if i < len => i + 1,
24 Bound::Included(i) | Bound::Excluded(i) => {
25 panic!("range end index {i} out of range for slice of length {len}")
26 }
27 };
28 if start > end {
29 panic!(
30 "range start index {:?} should be <= range end index {:?}",
31 range.start_bound(),
32 range.end_bound()
33 );
34 }
35 start..end
36}
37
38pub(crate) fn try_simplify_range<R>(range: R, len: usize) -> Option<Range<usize>>
39where
40 R: RangeBounds<usize>,
41{
42 let start: usize = match range.start_bound() {
43 Bound::Unbounded => 0,
44 Bound::Included(&i: usize) if i <= len => i,
45 Bound::Excluded(&i: usize) if i < len => i + 1,
46 _ => return None,
47 };
48 let end: usize = match range.end_bound() {
49 Bound::Unbounded => len,
50 Bound::Excluded(&i: usize) if i <= len => i,
51 Bound::Included(&i: usize) if i < len => i + 1,
52 _ => return None,
53 };
54 if start > end {
55 return None;
56 }
57 Some(start..end)
58}
59
60// Generic slice equality -- copied from the standard library but adding a custom comparator,
61// allowing for our `Bucket` wrapper on either or both sides.
62pub(crate) fn slice_eq<T, U>(left: &[T], right: &[U], eq: impl Fn(&T, &U) -> bool) -> bool {
63 if left.len() != right.len() {
64 return false;
65 }
66
67 // Implemented as explicit indexing rather
68 // than zipped iterators for performance reasons.
69 // See PR https://github.com/rust-lang/rust/pull/116846
70 for i: usize in 0..left.len() {
71 // bound checks are optimized away
72 if !eq(&left[i], &right[i]) {
73 return false;
74 }
75 }
76
77 true
78}
79