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}