1use core::ops::RangeBounds;
2use std::ops::Range;
3
4pub trait Sliceable: HasLength + Sized {
6 #[must_use]
7 fn _slice(&self, range: Range<usize>) -> Self;
8
9 #[must_use]
10 #[inline(always)]
11 fn slice(&self, range: impl RangeBounds<usize>) -> Self {
12 let start = match range.start_bound() {
13 std::ops::Bound::Included(x) => *x,
14 std::ops::Bound::Excluded(x) => x + 1,
15 std::ops::Bound::Unbounded => 0,
16 };
17
18 let end = match range.end_bound() {
19 std::ops::Bound::Included(x) => x + 1,
20 std::ops::Bound::Excluded(x) => *x,
21 std::ops::Bound::Unbounded => self.rle_len(),
22 };
23
24 self._slice(start..end)
25 }
26
27 #[inline(always)]
29 fn slice_(&mut self, range: impl RangeBounds<usize>) {
30 *self = self.slice(range);
31 }
32
33 #[must_use]
34 fn split(&mut self, pos: usize) -> Self {
35 let right = self.slice(pos..);
36 self.slice_(..pos);
37 right
38 }
39
40 fn update_with_split(
49 &mut self,
50 range: impl RangeBounds<usize>,
51 f: impl FnOnce(&mut Self),
52 ) -> (Option<Self>, Option<Self>) {
53 let start = match range.start_bound() {
54 std::ops::Bound::Included(x) => *x,
55 std::ops::Bound::Excluded(x) => x + 1,
56 std::ops::Bound::Unbounded => 0,
57 };
58
59 let end = match range.end_bound() {
60 std::ops::Bound::Included(x) => x + 1,
61 std::ops::Bound::Excluded(x) => *x,
62 std::ops::Bound::Unbounded => self.rle_len(),
63 };
64
65 if start >= end {
66 return (None, None);
67 }
68
69 match (start == 0, end == self.rle_len()) {
70 (true, true) => {
71 f(self);
72 (None, None)
73 }
74 (true, false) => {
75 let right = self.split(end);
76 f(self);
77 (Some(right), None)
78 }
79 (false, true) => {
80 let mut right = self.split(start);
81 f(&mut right);
82 (Some(right), None)
83 }
84 (false, false) => {
85 let right = self.split(end);
86 let mut middle = self.split(start);
87 f(&mut middle);
88 (Some(middle), Some(right))
89 }
90 }
91 }
92}
93
94pub trait Mergeable {
95 fn can_merge(&self, rhs: &Self) -> bool;
99 fn merge_right(&mut self, rhs: &Self);
100 fn merge_left(&mut self, left: &Self);
101}
102
103pub trait HasLength {
104 fn rle_len(&self) -> usize;
105}
106
107pub trait TryInsert {
108 fn try_insert(&mut self, pos: usize, elem: Self) -> Result<(), Self>
109 where
110 Self: Sized;
111}
112
113pub trait CanRemove {
114 fn can_remove(&self) -> bool;
115}
116
117impl CanRemove for () {
118 fn can_remove(&self) -> bool {
119 true
120 }
121}
122impl CanRemove for usize {
123 fn can_remove(&self) -> bool {
124 *self == 0
125 }
126}
127impl CanRemove for isize {
128 fn can_remove(&self) -> bool {
129 *self == 0
130 }
131}
132impl CanRemove for u32 {
133 fn can_remove(&self) -> bool {
134 *self == 0
135 }
136}
137impl CanRemove for i32 {
138 fn can_remove(&self) -> bool {
139 *self == 0
140 }
141}