1use std::ops::{Bound, Range, RangeBounds};
8
9use archery::{SharedPointer, SharedPointerKind};
10
11pub(crate) fn clone_ref<A, P>(r: SharedPointer<A, P>) -> A
12where
13 A: Clone,
14 P: SharedPointerKind,
15{
16 SharedPointer::try_unwrap(r).unwrap_or_else(|r| (*r).clone())
17}
18
19#[derive(Clone, Copy, PartialEq, Eq, Debug)]
20pub(crate) enum Side {
21 Left,
22 Right,
23}
24
25pub(crate) fn to_range<R>(range: &R, right_unbounded: usize) -> Range<usize>
26where
27 R: RangeBounds<usize>,
28{
29 let start_index = match range.start_bound() {
30 Bound::Included(i) => *i,
31 Bound::Excluded(i) => *i + 1,
32 Bound::Unbounded => 0,
33 };
34 let end_index = match range.end_bound() {
35 Bound::Included(i) => *i + 1,
36 Bound::Excluded(i) => *i,
37 Bound::Unbounded => right_unbounded,
38 };
39 start_index..end_index
40}
41
42#[cfg(test)]
43macro_rules! assert_covariant {
44 ($name:ident<$($gen:tt),*> in $param:ident) => {
45 #[allow(dead_code, unused_assignments, unused_variables)]
46 const _: () = {
47 type Tmp<$param> = $name<$($gen),*>;
48 fn assign<'a, 'b: 'a>(src: Tmp<&'b i32>, mut dst: Tmp<&'a i32>) {
49 dst = src;
50 }
51 };
52 }
53}