rc_slice2/
arc.rs

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