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}