rc_slice2/
rc.rs

1use alloc::rc::Rc;
2use core::borrow::Borrow;
3use core::cmp::Ordering;
4use core::fmt;
5use core::hash::{Hash, Hasher};
6use core::ops::{Bound, Deref, Range, RangeBounds};
7
8use crate::RcSliceContainer;
9
10/// A read-only view into part of an underlying reference-counted slice.
11///
12/// The associated functions provided for this type do not take a receiver to avoid conflicting
13/// with (present or future) methods on `[T]`, since `RcSlice<T>: Deref<Target = [T]>`. To reduce
14/// the length of code, it is recommended to include `use RcSlice as Rcs` where needed.
15pub struct RcSlice<T: ?Sized> {
16    /// The underlying container.
17    underlying: Rc<T>,
18    /// The start of the slice's range, inclusive.
19    ///
20    /// Must always be less than or equal to `end`.
21    ///
22    /// Must always be less than or equal to `underlying.len()`
23    start: usize,
24    /// The end of the slice's range, exclusive. There are no constraints on its value.
25    ///
26    /// Must always be greater than or equal to `start`.
27    ///
28    /// Must always be less than or equal to `underlying.len()`
29    end: usize,
30}
31
32impl<T: RcSliceContainer + ?Sized> RcSlice<T> {
33    /////////////////////////////////////////////
34    // Constructors
35    //
36
37    /// Create a new RcSlice.
38    ///
39    /// ```
40    /// # extern crate alloc;
41    /// # use rc_slice2::RcSlice;
42    /// # use alloc::rc::Rc;
43    /// use RcSlice as Rcs;
44    ///
45    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
46    ///
47    /// assert_eq!(*Rcs::new(&buffer, 1..4), [4, 6, 8]);
48    /// assert_eq!(*Rcs::new(&buffer, ..), [2, 4, 6, 8, 10]);
49    /// assert_eq!(*Rcs::new(&buffer, 0..=2), [2, 4, 6]);
50    /// assert_eq!(*Rcs::new(&buffer, 10..), []);
51    /// ```
52    pub fn new<R: RangeBounds<usize>>(underlying: &Rc<T>, range: R) -> Self {
53        let start = match range.start_bound() {
54            Bound::Excluded(x) => usize::min(x.saturating_add(1), underlying.len()),
55            Bound::Included(x) => usize::min(*x, underlying.len()),
56            Bound::Unbounded => 0,
57        };
58        let end = match range.end_bound() {
59            Bound::Excluded(x) => usize::min(*x, underlying.len()),
60            Bound::Included(x) => usize::min(x.saturating_add(1), underlying.len()),
61            Bound::Unbounded => underlying.len(),
62        };
63        Self {
64            underlying: underlying.clone(),
65            start,
66            end: usize::max(start, end),
67        }
68    }
69
70    /////////////////////////////////////////////
71    // Slice methods, but for RcSlice.
72    //
73
74    /// Returns the number of elements in the slice. This associated function
75    /// is faster than `self.len()`, and avoids accessing the inner Rc.
76    ///
77    ///  ```
78    /// # extern crate alloc;
79    /// # use rc_slice2::RcSlice;
80    /// # use alloc::rc::Rc;
81    /// use RcSlice as Rcs;
82    ///
83    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
84    ///
85    /// assert_eq!(Rcs::len(&Rcs::new(&buffer, ..)), 5);
86    /// assert_eq!(Rcs::len(&Rcs::new(&buffer, 1..3)), 2);
87    /// ```
88    #[inline]
89    pub fn len(it: &Self) -> usize {
90        // Note: This assumes the constraints for start and end are upheld;
91        // we know the subtraction won't underflow because `start <= end`,
92        // and we know the entire range corresponds to real elements in `underlying`
93        // because `end <= underlying.len()`.
94        it.end - it.start
95    }
96
97    /// Returns true if the slice has a length of 0. This associated function
98    /// is faster than `self.is_empty()`, and avoids accessing the inner Rc.
99    ///
100    ///  ```
101    /// # extern crate alloc;
102    /// # use rc_slice2::RcSlice;
103    /// # use alloc::rc::Rc;
104    /// use RcSlice as Rcs;
105    ///
106    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
107    ///
108    /// assert_eq!(Rcs::is_empty(&Rcs::new(&buffer, ..)), false);
109    /// assert_eq!(Rcs::is_empty(&Rcs::new(&buffer, 1..1)), true);
110    /// ```
111    #[inline]
112    pub fn is_empty(it: &Self) -> bool {
113        it.end == it.start
114    }
115
116    /// Divides one slice into two at an index.
117    ///
118    /// The first will contain all indices from `[0, mid)` (excluding the index `mid` itself)
119    /// and the second will contain all indices from `[mid, len)` (excluding the index `len` itself).
120    ///
121    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
122    ///
123    /// # Panics
124    ///
125    /// Panics if `mid > it.len()`.
126    ///
127    /// ```
128    /// # extern crate alloc;
129    /// # use rc_slice2::RcSlice;
130    /// # use alloc::rc::Rc;
131    /// use RcSlice as Rcs;
132    ///
133    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
134    /// let slice = Rcs::new(&buffer, 1..);
135    /// assert_eq!(*slice, [4, 6, 8, 10]);
136    ///
137    /// let (low, high) = Rcs::split_at(&slice, 2);
138    /// assert_eq!(*low, [4, 6]);
139    /// assert_eq!(*high, [8, 10]);
140    /// ```
141    pub fn split_at(it: &Self, mid: usize) -> (Self, Self) {
142        assert!(mid <= RcSlice::len(it));
143        // This addition is guaranteed not to overflow because of the above
144        // assertion, and the invariant `start <= end`.
145        let real_mid = it.start + mid;
146
147        (
148            RcSlice::new(&it.underlying, it.start..real_mid),
149            RcSlice::new(&it.underlying, real_mid..it.end),
150        )
151    }
152
153    /// This is the same as [`split_at`](RcSlice::split_at), but returns `None` if `mid > len` instead
154    /// of panicking.
155    ///
156    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
157    ///
158    /// ```
159    /// # extern crate alloc;
160    /// # use rc_slice2::RcSlice;
161    /// # use alloc::rc::Rc;
162    /// use RcSlice as Rcs;
163    ///
164    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
165    /// let slice = Rcs::new(&buffer, 1..);
166    /// assert_eq!(*slice, [4, 6, 8, 10]);
167    ///
168    /// let (low, high) = Rcs::try_split_at(&slice, 2).unwrap();
169    /// assert_eq!(*low, [4, 6]);
170    /// assert_eq!(*high, [8, 10]);
171    ///
172    /// assert_eq!(Rcs::try_split_at(&slice, 5), None);
173    /// ```
174    pub fn try_split_at(it: &Self, mid: usize) -> Option<(Self, Self)> {
175        if mid <= RcSlice::len(it) {
176            Some(RcSlice::split_at(it, mid))
177        } else {
178            None
179        }
180    }
181
182    /// This is an in-place version of [`try_split_at`](RcSlice::try_split_at).
183    ///
184    /// If `mid` is valid, mutates `it` to the upper half, and returns the lower half.
185    /// Specifically, this will mutate the slice `it` to be `[mid, len)`, and returns the slice `[0, mid)`.
186    ///
187    /// Returns `None` and leaves `it` unchanged if `mid` is outside the bounds of the slice.
188    ///
189    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
190    ///
191    ///  ```
192    /// # extern crate alloc;
193    /// # use rc_slice2::RcSlice;
194    /// # use alloc::rc::Rc;
195    /// use RcSlice as Rcs;
196    ///
197    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
198    /// let mut slice = Rcs::new(&buffer, 1..);
199    /// assert_eq!(*slice, [4, 6, 8, 10]);
200    ///
201    /// let (low, high) = Rcs::split_at(&slice, 2);
202    /// assert_eq!(*low, [4, 6]);
203    /// assert_eq!(*high, [8, 10]);
204    ///
205    /// let other_high = Rcs::split_off_before(&mut slice, 2).unwrap();
206    /// assert_eq!(*other_high, [4, 6]);
207    /// assert_eq!(*slice, [8, 10]);
208    ///
209    /// assert_eq!(Rcs::split_off_before(&mut slice, 5), None);
210    /// assert_eq!(*slice, [8, 10]);
211    /// ```
212    pub fn split_off_before(it: &mut Self, index: usize) -> Option<Self> {
213        let cut = it.start.checked_add(index)?;
214
215        if cut <= it.end {
216            let mut front = it.clone();
217            front.end = cut;
218            it.start = cut;
219
220            Some(front)
221        } else {
222            None
223        }
224    }
225
226    /// This is an in-place version of [`try_split_at`](RcSlice::try_split_at).
227    ///
228    /// If `mid` is valid, mutates `it` to the lower half, and returns the upper half.
229    /// Specifically, this will mutate the slice `it` to be `[0, mid)`, and returns the slice `[mid, len)`.
230    ///
231    /// Returns `None` and leaves `it` unchanged if `mid` is outside the bounds of the slice.
232    ///
233    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
234    ///
235    ///  ```
236    /// # extern crate alloc;
237    /// # use rc_slice2::RcSlice;
238    /// # use alloc::rc::Rc;
239    /// use RcSlice as Rcs;
240    ///
241    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
242    /// let mut slice = Rcs::new(&buffer, 1..);
243    /// assert_eq!(*slice, [4, 6, 8, 10]);
244    ///
245    /// let (low, high) = Rcs::split_at(&slice, 2);
246    /// assert_eq!(*low, [4, 6]);
247    /// assert_eq!(*high, [8, 10]);
248    ///
249    /// let other_high = Rcs::split_off_after(&mut slice, 2).unwrap();
250    /// assert_eq!(*other_high, [8, 10]);
251    /// assert_eq!(*slice, [4, 6]);
252    ///
253    /// assert_eq!(Rcs::split_off_after(&mut slice, 5), None);
254    /// assert_eq!(*slice, [4, 6]);
255    /// ```
256    pub fn split_off_after(it: &mut Self, index: usize) -> Option<Self> {
257        let cut = it.start.checked_add(index)?;
258
259        if cut <= it.end {
260            let mut back = it.clone();
261            back.start = cut;
262            it.end = cut;
263
264            Some(back)
265        } else {
266            None
267        }
268    }
269
270    /////////////////////////////////////////////
271    // Methods related to being a view of a
272    // larger container.
273    //
274
275    /// Returns the starting and ending indices of the view `it` within the underlying slice.
276    /// ```
277    /// # #![allow(deprecated)]
278    /// # extern crate alloc;
279    /// # use rc_slice2::RcSlice;
280    /// # use alloc::rc::Rc;
281    /// use RcSlice as Rcs;
282    ///
283    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
284    ///
285    /// assert_eq!(Rcs::bounds(&Rcs::new(&buffer, ..)), (0, 5));
286    /// assert_eq!(Rcs::bounds(&Rcs::new(&buffer, 1..3)), (1, 3));
287    /// ```
288    #[deprecated(since = "0.4.0", note = "Use `bounds_range` instead.")]
289    pub fn bounds(it: &Self) -> (usize, usize) {
290        (it.start, it.end)
291    }
292
293    /// Returns the inner buffer.
294    pub fn inner(it: &Self) -> &Rc<T> {
295        &it.underlying
296    }
297
298    /// Returns the range that this slice represents.
299    ///
300    ///  ```
301    /// # extern crate alloc;
302    /// # use rc_slice2::RcSlice;
303    /// # use alloc::rc::Rc;
304    /// use RcSlice as Rcs;
305    ///
306    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
307    ///
308    /// assert_eq!(Rcs::bounds_range(&Rcs::new(&buffer, ..)), 0..5);
309    /// assert_eq!(Rcs::bounds_range(&Rcs::new(&buffer, 1..3)), 1..3);
310    /// ```
311    pub fn bounds_range(it: &Self) -> Range<usize> {
312        it.start..it.end
313    }
314
315    /// Increases the starting index of `self` by `incr` places, and returns a reference to the
316    /// elements cut off by this operation. The end of the slice is not affected.
317    ///
318    /// Returns `None` and leaves `self` unchanged if this operation would make the starting index
319    /// greater than the ending index.
320    ///
321    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
322    ///
323    /// ```
324    /// # #![allow(deprecated)]
325    /// # extern crate alloc;
326    /// # use alloc::rc::Rc;
327    /// # use rc_slice2::RcSlice;
328    /// use RcSlice as Rcs;
329    ///
330    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10, 12, 14, 16, 18]);
331    /// let mut slice = Rcs::new(&buffer, 1..8);
332    ///
333    /// assert_eq!(*slice, [4, 6, 8, 10, 12, 14, 16]);
334    ///
335    /// // Take the first two
336    /// assert_eq!(Rcs::advance(&mut slice, 2), Some([4, 6].as_slice()));
337    /// assert_eq!(*slice, [8, 10, 12, 14, 16]);
338    ///
339    /// // Take three more
340    /// assert_eq!(Rcs::advance(&mut slice, 3), Some([8, 10, 12].as_slice()));
341    /// assert_eq!(*slice, [14, 16]);
342    ///
343    /// // Try to take three, but can't. Slice is unchanged.
344    /// assert_eq!(Rcs::advance(&mut slice, 3), None);
345    /// assert_eq!(*slice, [14, 16]);
346    ///
347    /// // Take the rest.
348    /// assert_eq!(Rcs::advance(&mut slice, 2), Some([14, 16].as_slice()));
349    /// assert_eq!(*slice, []);
350    /// ```
351    pub fn advance(it: &mut Self, incr: usize) -> Option<&[T::Item]> {
352        let cut = it.start.checked_add(incr)?;
353
354        if cut <= it.end {
355            let shed = it.underlying.get(it.start..cut)?;
356            it.start = cut;
357
358            Some(shed)
359        } else {
360            None
361        }
362    }
363
364    /// Increases the starting index of `self` by `incr` places, and returns a reference to the
365    /// elements cut off by this operation. The end of the slice is not affected.
366    ///
367    /// If the slice doesn't contain enough elements, returns all available elements.
368    ///
369    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
370    ///
371    /// ```
372    /// # #![allow(deprecated)]
373    /// # extern crate alloc;
374    /// # use alloc::rc::Rc;
375    /// # use rc_slice2::RcSlice;
376    /// use RcSlice as Rcs;
377    ///
378    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10, 12, 14, 16, 18]);
379    /// let mut slice = Rcs::new(&buffer, 1..8);
380    ///
381    /// assert_eq!(*slice, [4, 6, 8, 10, 12, 14, 16]);
382    ///
383    /// // Take the first two
384    /// assert_eq!(Rcs::saturating_advance(&mut slice, 2), [4, 6]);
385    /// assert_eq!(*slice, [8, 10, 12, 14, 16]);
386    ///
387    /// // Take three more
388    /// assert_eq!(Rcs::saturating_advance(&mut slice, 3), [8, 10, 12]);
389    /// assert_eq!(*slice, [14, 16]);
390    ///
391    /// // Try to take three, but can only take 2.
392    /// assert_eq!(Rcs::saturating_advance(&mut slice, 3), [14, 16]);
393    /// assert_eq!(*slice, []);
394    ///
395    /// // Try to take two, but slice is empty.
396    /// assert_eq!(Rcs::saturating_advance(&mut slice, 2), []);
397    /// assert_eq!(*slice, []);
398    /// ```
399    pub fn saturating_advance(it: &mut Self, incr: usize) -> &[T::Item] {
400        let cut = usize::min(it.start.saturating_add(incr), it.end);
401
402        // TODO: Evaluate whether this will panic, and when.
403        // I believe it will only panic if the container trait impl
404        // is implemented weirdly.
405        let shed = it.underlying.get(it.start..cut).unwrap();
406        it.start = cut;
407        shed
408    }
409
410    /// Decreases the ending index of `it` by `decr` places, and returns a reference to the
411    /// elements cut off by this operation.
412    ///
413    /// Returns `None` and leaves `it` unchanged if this operation would make the ending index less
414    /// than the starting index.
415    ///
416    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
417    ///
418    /// ```
419    /// # #![allow(deprecated)]
420    /// # extern crate alloc;
421    /// # use alloc::rc::Rc;
422    /// # use rc_slice2::RcSlice;
423    /// use RcSlice as Rcs;
424    ///
425    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10, 12, 14, 16, 18]);
426    /// let mut slice = Rcs::new(&buffer, 1..8);
427    ///
428    /// assert_eq!(*slice, [4, 6, 8, 10, 12, 14, 16]);
429    ///
430    /// // Take the first two
431    /// assert_eq!(Rcs::retract(&mut slice, 2), Some([14, 16].as_slice()));
432    /// assert_eq!(*slice, [4, 6, 8, 10, 12]);
433    ///
434    /// // Take three more
435    /// assert_eq!(Rcs::retract(&mut slice, 3), Some([8, 10, 12].as_slice()));
436    /// assert_eq!(*slice, [4, 6]);
437    ///
438    /// // Try to take three, but can't. Slice is unchanged.
439    /// assert_eq!(Rcs::retract(&mut slice, 3), None);
440    /// assert_eq!(*slice, [4, 6]);
441    ///
442    /// // Take the rest.
443    /// assert_eq!(Rcs::retract(&mut slice, 2), Some([4, 6].as_slice()));
444    /// assert_eq!(*slice, []);
445    /// ```
446    pub fn retract(it: &mut Self, decr: usize) -> Option<&[T::Item]> {
447        let cut = it.end.checked_sub(decr)?;
448
449        if cut >= it.start {
450            let shed = it.underlying.get(cut..it.end)?;
451            it.end = cut;
452
453            Some(shed)
454        } else {
455            None
456        }
457    }
458
459    /// Decreases the ending index of `it` by `decr` places, and returns a reference to the
460    /// elements cut off by this operation.
461    ///
462    /// If the slice doesn't contain enough elements, returns all available elements.
463    ///
464    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
465    ///
466    /// ```
467    /// # extern crate alloc;
468    /// # use alloc::rc::Rc;
469    /// # use rc_slice2::RcSlice;
470    /// use RcSlice as Rcs;
471    ///
472    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10, 12, 14, 16, 18]);
473    /// let mut slice = Rcs::new(&buffer, 1..8);
474    ///
475    /// assert_eq!(*slice, [4, 6, 8, 10, 12, 14, 16]);
476    ///
477    /// // Take the first two
478    /// assert_eq!(Rcs::saturating_retract(&mut slice, 2), [14, 16]);
479    /// assert_eq!(*slice, [4, 6, 8, 10, 12]);
480    ///
481    /// // Take three more
482    /// assert_eq!(Rcs::saturating_retract(&mut slice, 3), [8, 10, 12]);
483    /// assert_eq!(*slice, [4, 6]);
484    ///
485    /// // Try to take three, but can only take 2.
486    /// assert_eq!(Rcs::saturating_retract(&mut slice, 3), [4, 6]);
487    /// assert_eq!(*slice, []);
488    ///
489    /// // Try to take two, but slice is empty.
490    /// assert_eq!(Rcs::saturating_retract(&mut slice, 2), []);
491    /// assert_eq!(*slice, []);
492    /// ```
493    pub fn saturating_retract(it: &mut Self, decr: usize) -> &[T::Item] {
494        let cut = usize::max(it.end.saturating_sub(decr), it.start);
495
496        // TODO: Evaluate whether this will panic, and when.
497        // I believe it will only panic if the container trait impl
498        // is implemented weirdly.
499        let shed = it.underlying.get(cut..it.end).unwrap();
500        it.end = cut;
501        shed
502    }
503
504    /// Adjusts the range of the slice. Roughly equivalent to `RcSlice::new(it.inner(), new_range)`,
505    /// but the change is made in-place.
506    ///
507    /// Returns the actual range of the new slice.
508    ///
509    /// This function DOES NOT DELETE unused parts of the original buffer. See [`shrink`](RcSlice::shrink).
510    ///
511    /// ```
512    /// # extern crate alloc;
513    /// # use alloc::rc::Rc;
514    /// # use rc_slice2::RcSlice;
515    /// use RcSlice as Rcs;
516    ///
517    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10, 12, 14, 16, 18]);
518    /// let mut slice = Rcs::new(&buffer, 1..4);
519    ///
520    /// assert_eq!(*slice, [4, 6, 8]);
521    /// assert_eq!(Rcs::change_range(&mut slice, 3..), 3..9);
522    /// assert_eq!(*slice, [8, 10, 12, 14, 16, 18]);
523    /// ```
524    pub fn change_range<R: RangeBounds<usize>>(it: &mut Self, new_range: R) -> Range<usize> {
525        let mut start = match new_range.start_bound() {
526            Bound::Excluded(x) => usize::min(x.saturating_add(1), it.underlying.len()),
527            Bound::Included(x) => usize::min(*x, it.underlying.len()),
528            Bound::Unbounded => 0,
529        };
530        let end = match new_range.end_bound() {
531            Bound::Excluded(x) => usize::min(*x, it.underlying.len()),
532            Bound::Included(x) => usize::min(x.saturating_add(1), it.underlying.len()),
533            Bound::Unbounded => it.underlying.len(),
534        };
535        start = usize::min(start, end);
536        it.start = start;
537        it.end = end;
538        start..end
539    }
540
541    /////////////////////////////////////////////
542    // Methods related to `Rc`
543
544    /// Returns a mutable reference into the given slice, if there are no other
545    /// RcSlice pointers to anywhere else in the underlying array.
546    ///
547    /// ```
548    /// # extern crate alloc;
549    /// # use alloc::rc::Rc;
550    /// # use rc_slice2::RcSlice;
551    /// use RcSlice as Rcs;
552    ///
553    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10, 12, 14, 16, 18]);
554    /// let mut slice = Rcs::new(&buffer, 1..8);
555    ///
556    /// // The original Rc buffer is still alive, so get_mut doesn't work.
557    /// assert_eq!(Rcs::get_mut(&mut slice), None);
558    ///
559    /// std::mem::drop(buffer);
560    /// // Now there's only one RcSlice for this array, so get_mut is allowed.
561    /// assert_eq!(Rcs::get_mut(&mut slice), Some([4, 6, 8, 10, 12, 14, 16].as_mut_slice()));
562    ///
563    /// // We can use the mutable reference.
564    /// Rcs::get_mut(&mut slice).unwrap().reverse();
565    /// assert_eq!(*slice, [16, 14, 12, 10, 8, 6, 4]);
566    ///
567    /// // The mutation changed the original buffer (though we need to create a new reference to see it).
568    /// let buffer = Rc::clone(Rcs::inner(&slice));
569    /// assert_eq!(*buffer, [2, 16, 14, 12, 10, 8, 6, 4, 18]);
570    ///
571    /// // Drop the buffer Rc again.
572    /// std::mem::drop(buffer);
573    /// assert_eq!(Rcs::get_mut(&mut slice), Some([16, 14, 12, 10, 8, 6, 4].as_mut_slice()));
574    ///
575    /// // Disjoint RcSlices still prevent mutation.
576    /// let (mut low, high) = Rcs::split_at(&slice, 4);
577    /// assert_eq!(*low, [16, 14, 12, 10]);
578    /// assert_eq!(*high, [8, 6, 4]);
579    /// assert_eq!(Rcs::get_mut(&mut low), None);
580    /// ```
581    pub fn get_mut(it: &mut Self) -> Option<&mut [T::Item]> {
582        let start = it.start;
583        let end = it.end;
584        Rc::get_mut(&mut it.underlying)
585            .map(|s| s.get_mut(start..end))
586            .flatten()
587    }
588
589    /// Checks if two RcSlices reference the same slice of the same array in memory.
590    ///
591    /// ```
592    /// # extern crate alloc;
593    /// # use alloc::rc::Rc;
594    /// # use rc_slice2::RcSlice;
595    /// use RcSlice as Rcs;
596    ///
597    /// let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10, 12, 14, 16, 18]);
598    /// let first_slice = Rcs::new(&buffer, ..4);
599    /// let second_slice = Rcs::new(&buffer, ..8);
600    ///
601    /// // These slices point to the same buffer, but different ranges.
602    /// assert_eq!(Rcs::ptr_eq(&first_slice, &second_slice), false);
603    ///
604    /// let (low, _) = Rcs::split_at(&second_slice, 4);
605    /// assert_eq!(first_slice, low);
606    ///
607    /// // These slices use the same buffer, and the same range.
608    /// assert_eq!(Rcs::ptr_eq(&first_slice, &low), true);
609    ///
610    /// let other_buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10, 12, 14, 16, 18]);
611    /// let other_slice = Rcs::new(&other_buffer, ..4);
612    ///
613    /// // The elements for `other_slice` are the same
614    /// assert_eq!(first_slice, other_slice);
615    ///
616    /// // But they use different memory locations.
617    /// assert_eq!(Rcs::ptr_eq(&first_slice, &other_slice), false);
618    /// ```
619    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
620        Rc::ptr_eq(&this.underlying, &other.underlying)
621            && this.start == other.start
622            && this.end == other.end
623    }
624
625    /// This is like a normal slice indexing operation, but produces an RcSlice instead.
626    /// ```
627    /// # extern crate alloc;
628    /// # use rc_slice2::RcSlice;
629    /// # use alloc::vec::Vec;
630    /// # use alloc::rc::Rc;
631    /// use RcSlice as Rcs;
632    ///
633    /// let buffer: Rc<Vec<u8>> = Rc::new((0..10).into_iter().collect());
634    /// let slice = Rcs::new(&buffer, 3..8);
635    /// assert_eq!(*slice, [3, 4, 5, 6, 7]);
636    ///
637    /// // Returns an RcSlice of the same buffer.
638    /// assert_eq!(Rcs::index(&slice, 2..4), Rcs::new(&buffer, 5..7));
639    ///
640    /// // All kinds of ranges work.
641    /// assert_eq!(*Rcs::index(&slice, ..), [3, 4, 5, 6, 7]);
642    /// assert_eq!(*Rcs::index(&slice, 1..), [4, 5, 6, 7]);
643    /// assert_eq!(*Rcs::index(&slice, 8..), []);
644    /// assert_eq!(*Rcs::index(&slice, 5..), []);
645    /// assert_eq!(*Rcs::index(&slice, ..2), [3, 4]);
646    /// assert_eq!(*Rcs::index(&slice, ..70), [3, 4, 5, 6, 7]);
647    /// assert_eq!(*Rcs::index(&slice, 3..8), [6, 7]);
648    ///```
649    pub fn index<R: RangeBounds<usize>>(it: &Self, range: R) -> Self {
650        use Bound::*;
651        let mut start = match range.start_bound() {
652            Unbounded => it.start,
653            Included(s) => it.start.saturating_add(*s),
654            Excluded(s) => it.start.saturating_add(*s).saturating_sub(1),
655        };
656        let end = match range.end_bound() {
657            Unbounded => it.end,
658            Included(s) => usize::min(it.end, it.start.saturating_add(*s).saturating_add(1)),
659            Excluded(s) => usize::min(it.end, it.start.saturating_add(*s)),
660        };
661        start = usize::min(start, end);
662        RcSlice {
663            underlying: it.underlying.clone(),
664            start,
665            end,
666        }
667    }
668}
669
670impl<T: RcSliceContainer + ?Sized + Default> RcSlice<T> {
671    /// Tries to reduce the size of the original buffer, if this is the only
672    /// Rc or RcSlice referencing the buffer.
673    ///
674    /// This operation doesn't preserve weak references.
675    /// ```
676    /// # extern crate alloc;
677    /// # use alloc::rc::Rc;
678    /// # use rc_slice2::RcSlice;
679    /// use RcSlice as Rcs;
680    ///
681    /// let buffer: Rc<Vec<u8>> = Rc::new(vec![2, 4, 6, 8, 10, 12]);
682    /// let mut slice = Rcs::new(&buffer, 1..4);
683    /// let weak_buffer = Rc::downgrade(&buffer);
684    ///
685    /// assert_eq!(*slice, [4, 6, 8]);
686    /// assert_eq!(**Rcs::inner(&slice), [2, 4, 6, 8, 10, 12]);
687    ///
688    /// // Shrink fails: there are two strong references.
689    /// assert_eq!(Rcs::shrink(&mut slice), false);
690    ///
691    /// core::mem::drop(buffer);
692    ///
693    /// // Shrink successful: only one strong reference.
694    /// assert_eq!(Rcs::shrink(&mut slice), true);
695    ///
696    /// // The slice is unchanged, and the buffer has shrunk.
697    /// assert_eq!(*slice, [4, 6, 8]);
698    /// assert_eq!(**Rcs::inner(&slice), [4, 6, 8]);
699    ///
700    /// // Weak references were not preserved.
701    /// assert_eq!(weak_buffer.upgrade(), None);
702    ///
703    /// ```
704    pub fn shrink(it: &mut Self) -> bool {
705        // This will be optimized away
706        if !T::IS_SHRINKABLE {
707            return false;
708        }
709
710        if it.start == 0 && it.end == it.underlying.len() {
711            return false;
712        }
713
714        let mut temp = Rc::new(T::default());
715        core::mem::swap(&mut temp, &mut it.underlying);
716        match Rc::try_unwrap(temp) {
717            Ok(mut container) => {
718                if let Some(new_range) = container.shrink_container_to_range(it.start..it.end) {
719                    it.start = new_range.start;
720                    it.end = new_range.end;
721                }
722                let mut temp2 = Rc::new(container);
723                core::mem::swap(&mut temp2, &mut it.underlying);
724                true
725            }
726            Err(mut temp2) => {
727                core::mem::swap(&mut temp2, &mut it.underlying);
728                false
729            }
730        }
731    }
732}
733
734#[test]
735fn test_index_ranges() {
736    use RcSlice as Rcs;
737
738    let buffer: Rc<alloc::vec::Vec<u8>> = Rc::new((0..10).into_iter().collect());
739    let slice = Rcs::new(&buffer, 3..8);
740    assert_eq!(*slice, [3, 4, 5, 6, 7]);
741
742    assert_eq!(*Rcs::index(&slice, ..), [3, 4, 5, 6, 7]);
743    assert_eq!(*Rcs::index(&slice, 1..), [4, 5, 6, 7]);
744    assert_eq!(*Rcs::index(&slice, 8..), []);
745    assert_eq!(*Rcs::index(&slice, 5..), []);
746    assert_eq!(*Rcs::index(&slice, ..2), [3, 4]);
747    assert_eq!(*Rcs::index(&slice, ..70), [3, 4, 5, 6, 7]);
748    assert_eq!(*Rcs::index(&slice, 3..8), [6, 7]);
749}
750
751impl<T: ?Sized> Clone for RcSlice<T> {
752    fn clone(&self) -> Self {
753        Self {
754            underlying: self.underlying.clone(),
755            start: self.start,
756            end: self.end,
757        }
758    }
759}
760
761impl<T: RcSliceContainer + ?Sized> AsRef<[T::Item]> for RcSlice<T> {
762    fn as_ref(&self) -> &[T::Item] {
763        // TODO: Evaluate whether this will panic, and when.
764        // I believe it will only panic if the container trait impl
765        // is implemented weirdly.
766        self.underlying.get(self.start..self.end).unwrap()
767    }
768}
769
770impl<T: RcSliceContainer + ?Sized> Deref for RcSlice<T> {
771    type Target = [T::Item];
772
773    fn deref(&self) -> &Self::Target {
774        self.as_ref()
775    }
776}
777
778impl<T: RcSliceContainer + ?Sized> From<Rc<T>> for RcSlice<T> {
779    fn from(underlying: Rc<T>) -> Self {
780        Self::new(&underlying, ..)
781    }
782}
783
784#[test]
785fn test_from() {
786    let buffer: Rc<[u8]> = Rc::new([4, 5, 6, 7]);
787    let ref_slice: RcSlice<_> = buffer.into();
788    assert_eq!(*ref_slice, [4, 5, 6, 7]);
789}
790
791impl<T: RcSliceContainer + fmt::Debug + ?Sized> fmt::Debug for RcSlice<T> {
792    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
793        self.underlying.fmt(f)
794    }
795}
796
797impl<T: RcSliceContainer + PartialEq + ?Sized> PartialEq for RcSlice<T> {
798    fn eq(&self, other: &Self) -> bool {
799        self.underlying == other.underlying
800    }
801}
802
803impl<T: RcSliceContainer + Eq + ?Sized> Eq for RcSlice<T> {}
804
805impl<T: RcSliceContainer + PartialOrd + ?Sized> PartialOrd for RcSlice<T> {
806    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
807        self.underlying.partial_cmp(&other.underlying)
808    }
809}
810
811impl<T: RcSliceContainer + Ord + ?Sized> Ord for RcSlice<T> {
812    fn cmp(&self, other: &Self) -> Ordering {
813        self.underlying.cmp(&other.underlying)
814    }
815}
816
817impl<T: RcSliceContainer + ?Sized> Borrow<[T::Item]> for RcSlice<T> {
818    fn borrow(&self) -> &[T::Item] {
819        self.as_ref()
820    }
821}
822
823impl<T> Hash for RcSlice<T>
824where
825    T: RcSliceContainer + Hash + ?Sized,
826    T::Item: Hash,
827{
828    fn hash<H: Hasher>(&self, state: &mut H) {
829        Hash::hash_slice(self.deref(), state)
830    }
831}
832
833impl<T: RcSliceContainer + Default + ?Sized> Default for RcSlice<T> {
834    fn default() -> Self {
835        Self::new(&Rc::new(T::default()), ..)
836    }
837}