value_traits/traits/
slices.rs

1/*
2 * SPDX-FileCopyrightText: 2025 Tommaso Fontana
3 * SPDX-FileCopyrightText: 2025 Sebastiano Vigna
4 * SPDX-FileCopyrightText: 2025 Inria
5 *
6 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
7 */
8
9//! Traits for value-based slices.
10//!
11//! Value-based slices are analogous to Rust's built-in slices, but they operate
12//! on values rather than references. This allows for more flexibility in how
13//! slices are used and manipulated.
14//!
15//! For example, a value-based slice can be defined functionally, implicitly, or
16//! using a succinct/compressed representation.
17//!
18//! The fundamental trait for value-based slices is [`SliceByValue`], which
19//! specifies the type of the values and the length of the slice. Additional
20//! functionality is provided by the [`SliceByValueGet`], [`SliceByValueSet`],
21//! and [`SliceByValueRepl`] traits, which allow for getting, setting, and
22//! replacing values in the slice, respectively. Note that, contrarily to the
23//! standard slices, replacement can be obtained by a pair of get/set
24//! operations: [`SliceByValueRepl`] is just more efficient.
25//!
26//! The [`SliceByValueSubslice`] trait provides methods for obtaining subslices
27//! given a range of indices, and the [`SliceByValueSubsliceMut`] trait provides
28//! mutable versions of these methods.
29//!
30//! Both traits are a combination of underlying traits that provide more
31//! specific subslicing functionality depending on the type of range used. In
32//! the intended usage, these traits are interesting only for implementors, or
33//! in the case an implementation does not provide the full set of ranges.
34//!
35//! ## Examples
36//!
37//! As a very simple worked-out example, let us a by-value read-only slice of
38//! `usize` using a vector of `u8` as a basic form of compression:
39//!
40//! ```rust
41//! use value_traits::slices::*;
42//!
43//! struct CompSlice<'a>(&'a [u8]);
44//!
45//! impl<'a> SliceByValue for CompSlice<'a> {
46//!     type Value = usize;
47//!     fn len(&self) -> usize {
48//!         self.0.len()
49//!     }
50//! }
51//!
52//! impl<'a> SliceByValueGet for CompSlice<'a> {
53//!     unsafe fn get_value_unchecked(&self, index: usize) -> usize {
54//!         self.0.get_value_unchecked(index) as usize
55//!     }
56//! }
57//!
58//! fn f(slice_by_value: impl SliceByValueGet<Value = usize>, index: usize) -> usize {
59//!     slice_by_value.index_value(index)
60//! }
61//!
62//! fn main() {
63//!     let vec = vec![0_u8, 1, 2, 3];
64//!     let slice_by_value = CompSlice(&vec);
65//!     // Note that we can pass a reference
66//!     assert_eq!(f(&slice_by_value, 0), 0);
67//!     assert_eq!(f(&slice_by_value, 1), 1);
68//!     assert_eq!(f(&slice_by_value, 2), 2);
69//!     assert_eq!(f(&slice_by_value, 3), 3);
70//! }
71//!
72//! ```
73//! In this example, instead, we define functionally a slice containing the
74//! first 100 squares:
75//!
76//! ```rust
77//! use value_traits::slices::*;
78//!
79//! struct Squares();
80//!
81//! impl<'a> SliceByValue for Squares {
82//!     type Value = usize;
83//!     fn len(&self) -> usize {
84//!         100
85//!     }
86//! }
87//!
88//! impl<'a> SliceByValueGet for Squares {
89//!     unsafe fn get_value_unchecked(&self, index: usize) -> usize {
90//!         index * index
91//!     }
92//! }
93//!
94//! fn f(slice_by_value: &impl SliceByValueGet<Value = usize>, index: usize) -> usize {
95//!     slice_by_value.index_value(index)
96//! }
97//!
98//! fn main() {
99//!     let squares = Squares();
100//!     for i in 0..100 {
101//!         assert_eq!(squares.index_value(i), i * i);
102//!     }
103//! }
104//! ```
105
106use core::{
107    hint::unreachable_unchecked,
108    ops::{
109        Bound, Range, RangeBounds, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
110    },
111};
112
113use crate::{ImplBound, Ref};
114
115/// Basic slice-by-value trait, specifying just the type of the values and the
116/// length of the slice.
117pub trait SliceByValue {
118    /// The type of the values in the slice.
119    type Value;
120    /// See [`slice::len`].
121    fn len(&self) -> usize;
122
123    /// See [`slice::is_empty`].
124    fn is_empty(&self) -> bool {
125        self.len() == 0
126    }
127}
128
129impl<S: SliceByValue + ?Sized> SliceByValue for &S {
130    type Value = S::Value;
131    #[inline]
132    fn len(&self) -> usize {
133        (**self).len()
134    }
135}
136
137impl<S: SliceByValue + ?Sized> SliceByValue for &mut S {
138    type Value = S::Value;
139    #[inline]
140    fn len(&self) -> usize {
141        (**self).len()
142    }
143}
144
145#[inline(always)]
146fn assert_index(index: usize, len: usize) {
147    assert!(
148        index < len,
149        "index out of bounds: the len is {len} but the index is {index}",
150    );
151}
152
153#[inline(always)]
154fn assert_range(range: &impl RangeCheck, len: usize) {
155    assert!(
156        range.is_valid(len),
157        "range {range:?} out of range for slice of length {len}: ",
158    );
159}
160
161/// Read-only slice-by-value trait.
162///
163/// The only method that must be implemented is
164/// [`get_value_unchecked`](`SliceByValueGet::get_value_unchecked`).
165pub trait SliceByValueGet: SliceByValue {
166    /// See [the `Index` implementation for slices](slice#impl-Index%3CI%3E-for-%5BT%5D).
167    fn index_value(&self, index: usize) -> Self::Value {
168        assert_index(index, self.len());
169        // SAFETY: index is without bounds
170        unsafe { self.get_value_unchecked(index) }
171    }
172
173    /// See [`slice::get_unchecked`].
174    ///
175    /// For a safe alternative see [`get_value`](SliceByValueGet::get_value)
176    /// or [`index_value`](SliceByValueGet::index_value).
177    ///
178    /// # Safety
179    ///
180    /// The index must be within bounds.
181    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value;
182
183    /// See [`slice::get`].
184    fn get_value(&self, index: usize) -> Option<Self::Value> {
185        if index < self.len() {
186            // SAFETY: index is without bounds
187            unsafe { Some(self.get_value_unchecked(index)) }
188        } else {
189            None
190        }
191    }
192}
193
194impl<S: SliceByValueGet + ?Sized> SliceByValueGet for &S {
195    fn get_value(&self, index: usize) -> Option<Self::Value> {
196        (**self).get_value(index)
197    }
198    fn index_value(&self, index: usize) -> Self::Value {
199        (**self).index_value(index)
200    }
201    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
202        unsafe { (**self).get_value_unchecked(index) }
203    }
204}
205
206impl<S: SliceByValueGet + ?Sized> SliceByValueGet for &mut S {
207    fn get_value(&self, index: usize) -> Option<Self::Value> {
208        (**self).get_value(index)
209    }
210    fn index_value(&self, index: usize) -> Self::Value {
211        (**self).index_value(index)
212    }
213    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
214        unsafe { (**self).get_value_unchecked(index) }
215    }
216}
217
218/// Mutable slice-by-value trait providing setting methods.
219///
220/// The only method that must be implemented is
221/// [`set_value_unchecked`](`SliceByValueSet::set_value_unchecked`).
222///
223/// If you need to set a value and get the previous value, use
224/// [`SliceByValueRepl`] instead.
225pub trait SliceByValueSet: SliceByValue {
226    /// Sets the value at the given index to the given value without doing
227    /// bounds checking.
228    ///
229    /// For a safe alternative see [`set_value`](SliceByValueSet::set_value).
230    ///
231    /// # Safety
232    ///
233    /// The index must be within bounds.
234    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value);
235
236    /// Sets the value at the given index to the given value.
237    ///
238    /// # Panics
239    ///
240    /// This method will panic is the index is not within bounds.
241    fn set_value(&mut self, index: usize, value: Self::Value) {
242        assert_index(index, self.len());
243        // SAFETY: index is without bounds
244        unsafe {
245            self.set_value_unchecked(index, value);
246        }
247    }
248}
249
250impl<S: SliceByValueSet + ?Sized> SliceByValueSet for &mut S {
251    fn set_value(&mut self, index: usize, value: Self::Value) {
252        (**self).set_value(index, value);
253    }
254    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
255        (**self).set_value_unchecked(index, value);
256    }
257}
258
259/// Mutable slice-by-value trait providing replacement methods.
260///
261/// If you just need to set a value, use [`SliceByValueSet`] instead.
262pub trait SliceByValueRepl: SliceByValue {
263    /// Sets the value at the given index to the given value and
264    /// returns the previous value, without doing bounds checking.
265    ///
266    /// For a safe alternative see [`SliceByValueRepl::replace_value`].
267    ///
268    /// # Safety
269    ///
270    /// The index must be within bounds.
271    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value;
272
273    /// Sets the value at the given index to the given value and
274    /// returns the previous value.
275    ///
276    /// # Panics
277    ///
278    /// This method will panic is the index is not within bounds.
279    fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
280        assert_index(index, self.len());
281        // SAFETY: index is without bounds
282        unsafe { self.replace_value_unchecked(index, value) }
283    }
284}
285
286impl<S: SliceByValueRepl + ?Sized> SliceByValueRepl for &mut S {
287    fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
288        (**self).replace_value(index, value)
289    }
290    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
291        (**self).replace_value_unchecked(index, value)
292    }
293}
294
295/// A range that can check whether it is within the bounds of a slice.
296///
297/// This traits makes it possible to monomorphize the six different
298/// range checks that are necessary to handle the six type of
299/// ranges available in [`core::ops`].
300pub trait RangeCheck: RangeBounds<usize> + core::fmt::Debug {
301    /// Returns `true` if the range is within the bounds of a slice of given
302    /// length
303    fn is_valid(&self, len: usize) -> bool;
304}
305
306impl RangeCheck for Range<usize> {
307    fn is_valid(&self, len: usize) -> bool {
308        self.start <= len && self.end <= len && self.start <= self.end
309    }
310}
311
312impl RangeCheck for RangeFrom<usize> {
313    fn is_valid(&self, len: usize) -> bool {
314        self.start <= len
315    }
316}
317
318impl RangeCheck for RangeFull {
319    fn is_valid(&self, _len: usize) -> bool {
320        true
321    }
322}
323
324impl RangeCheck for RangeInclusive<usize> {
325    fn is_valid(&self, len: usize) -> bool {
326        // This can be significantly improved once
327        // https://rust-lang.github.io/rfcs/3550-new-range.html is implemented
328        let start = match self.start_bound() {
329            Bound::Included(s) => *s,
330            // SAFETY: we cannot take this branch
331            _ => unsafe { unreachable_unchecked() },
332        };
333        let end = match self.end_bound() {
334            Bound::Included(s) => *s,
335            // SAFETY: we cannot take this branch
336            _ => unsafe { unreachable_unchecked() },
337        };
338        start < len && end < len && start <= end
339    }
340}
341
342impl RangeCheck for RangeTo<usize> {
343    fn is_valid(&self, len: usize) -> bool {
344        self.end <= len
345    }
346}
347
348impl RangeCheck for RangeToInclusive<usize> {
349    fn is_valid(&self, len: usize) -> bool {
350        self.end < len
351    }
352}
353
354/// A GAT-like trait specifying the subslice type.
355///
356/// It implicitly restricts the lifetime `'a` used in `SliceByValueRange` to be
357/// `where Self: 'a`. Moreover, it requires [`SliceByValueGet`].
358///
359/// As in other theoretical applications of GATs (Generic Associated Types),
360/// like [lenders](https://crates.io/crates/lender), using a GAT to express the
361/// type of a subslice is problematic because when bounding the type itself in a
362/// `where` clause using Higher-Ranked Trait Bounds (HRTBs) the bound must be
363/// true for all lifetimes, including `'static`, resulting in the sliced type
364/// having to be `'static` as well.
365///
366/// This is a result of HRTBs not having a way to express qualifiers (`for<'any
367/// where Self: 'any> Self: Trait`) and effectively making HRTBs only useful
368/// when you want to express a trait constraint on ALL lifetimes, including
369/// `'static` (`for<'all> Self: trait`)
370///
371/// Please see [Sabrina's Blog][1] for more information, and how a trait like
372/// this can be used to solve it by implicitly restricting HRTBs.
373///
374/// [1]:
375///     <https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats>
376pub trait SliceByValueSubsliceGat<'a, __Implicit: ImplBound = Ref<'a, Self>>:
377    SliceByValueGet
378{
379    type Subslice: 'a + SliceByValueGet<Value = Self::Value> + SliceByValueSubslice;
380}
381
382impl<'a, T: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for &T {
383    type Subslice = <T as SliceByValueSubsliceGat<'a>>::Subslice;
384}
385
386impl<'a, T: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for &mut T {
387    type Subslice = <T as SliceByValueSubsliceGat<'a>>::Subslice;
388}
389
390/// A convenience type representing the type of subslice
391/// of a type implementing [`SliceByValueSubsliceGat`].
392#[allow(type_alias_bounds)] // yeah the type alias bounds are not enforced, but they are useful for documentation
393pub type Subslice<'a, T: SliceByValueSubsliceGat<'a>> =
394    <T as SliceByValueSubsliceGat<'a>>::Subslice;
395
396/// A trait implementing subslicing for a specific range parameter.
397///
398/// The user should never see this trait. [`SliceByValueSubslice`] combines all
399/// instances of this trait with `R` equal to the various kind of standard
400/// ranges ([`core::ops::Range`], [`core::ops::RangeFull`], etc.).
401///
402/// The only method that must be implemented is
403/// [`get_subslice_unchecked`](`SliceByValueSubsliceRange::get_subslice_unchecked`).
404pub trait SliceByValueSubsliceRange<R: RangeCheck>: for<'a> SliceByValueSubsliceGat<'a> {
405    /// See [the `Index` implementation for slices](slice#impl-Index%3CI%3E-for-%5BT%5D).
406    fn index_subslice(&self, range: R) -> Subslice<'_, Self> {
407        assert_range(&range, self.len());
408        unsafe {
409            // SAFETY: The range is checked to be within bounds.
410            self.get_subslice_unchecked(range)
411        }
412    }
413
414    /// See [`slice::get_unchecked`].
415    ///
416    /// For a safe alternative see
417    /// [`get_subslice`](SliceByValueSubsliceRange::get_subslice) or
418    /// [`index_subslice`](SliceByValueSubsliceRange::index_subslice).
419    ///
420    /// # Safety
421    ///
422    /// The range must be within bounds.
423    unsafe fn get_subslice_unchecked(&self, range: R) -> Subslice<'_, Self>;
424
425    /// See [`slice::get`].
426    fn get_subslice(&self, range: R) -> Option<Subslice<'_, Self>> {
427        if range.is_valid(self.len()) {
428            // SAFETY: range is checked to be within bounds.
429            unsafe { Some(self.get_subslice_unchecked(range)) }
430        } else {
431            None
432        }
433    }
434}
435
436impl<R: RangeCheck, S: SliceByValueSubsliceRange<R> + ?Sized> SliceByValueSubsliceRange<R> for &S {
437    fn get_subslice(&self, range: R) -> Option<Subslice<'_, Self>> {
438        (**self).get_subslice(range)
439    }
440    fn index_subslice(&self, range: R) -> Subslice<'_, Self> {
441        (**self).index_subslice(range)
442    }
443    unsafe fn get_subslice_unchecked(&self, range: R) -> Subslice<'_, Self> {
444        unsafe { (**self).get_subslice_unchecked(range) }
445    }
446}
447impl<R: RangeCheck, S: SliceByValueSubsliceRange<R> + ?Sized> SliceByValueSubsliceRange<R>
448    for &mut S
449{
450    fn get_subslice(&self, range: R) -> Option<Subslice<'_, Self>> {
451        (**self).get_subslice(range)
452    }
453    fn index_subslice(&self, range: R) -> Subslice<'_, Self> {
454        (**self).index_subslice(range)
455    }
456    unsafe fn get_subslice_unchecked(&self, range: R) -> Subslice<'_, Self> {
457        unsafe { (**self).get_subslice_unchecked(range) }
458    }
459}
460
461// TODO: can we implement traits conditionally on the associated type? Like,
462// replace only if it present in the root slice?
463
464/// A GAT-like trait specifying the mutable subslice type.
465///
466/// See [`SliceByValueSubsliceGat`].
467pub trait SliceByValueSubsliceGatMut<'a, __Implicit = &'a Self>:
468    SliceByValueSet + SliceByValueRepl
469{
470    type Subslice: 'a
471        + SliceByValueSet<Value = Self::Value>
472        + SliceByValueRepl<Value = Self::Value>
473        + SliceByValueSubsliceGatMut<'a, Subslice = Self::Subslice> // recursion
474        + SliceByValueSubsliceMut;
475}
476
477impl<'a, T: SliceByValueSubsliceGatMut<'a> + ?Sized> SliceByValueSubsliceGatMut<'a> for &mut T {
478    type Subslice = <T as SliceByValueSubsliceGatMut<'a>>::Subslice;
479}
480
481/// A convenience type representing the type of subslice
482/// of a type implementing [`SliceByValueSubsliceGatMut`].
483#[allow(type_alias_bounds)] // yeah the type alias bounds are not enforced, but they are useful for documentation
484pub type SubsliceMut<'a, T: SliceByValueSubsliceGatMut<'a>> =
485    <T as SliceByValueSubsliceGatMut<'a>>::Subslice;
486
487/// A trait implementing mutable subslicing for a specific range parameter.
488///
489///  The user should never see this trait. [`SliceByValueSubsliceMut`] combines
490/// all instances of this trait with `R` equal to the various kind of standard
491/// ranges ([`core::ops::Range`], [`core::ops::RangeFull`], etc.).
492///
493/// The only method that must be implemented is
494/// [`get_subslice_unchecked_mut`](`SliceByValueSubsliceRangeMut::get_subslice_unchecked_mut`).
495pub trait SliceByValueSubsliceRangeMut<R: RangeCheck>:
496    for<'a> SliceByValueSubsliceGatMut<'a>
497{
498    /// See [the `Index` implementation for slices](slice#impl-Index%3CI%3E-for-%5BT%5D).
499    fn index_subslice_mut(&mut self, range: R) -> SubsliceMut<'_, Self> {
500        assert_range(&range, self.len());
501        unsafe {
502            // SAFETY: The range is checked to be within bounds.
503            self.get_subslice_unchecked_mut(range)
504        }
505    }
506
507    /// See [`slice::get_unchecked`].
508    ///
509    /// For a safe alternative see
510    /// [`get_subslice_mut`](SliceByValueSubsliceRangeMut::get_subslice_mut) or
511    /// [`index_subslice_mut`](SliceByValueSubsliceRangeMut::index_subslice_mut).
512    ///
513    /// # Safety
514    ///
515    /// The range must be within bounds.
516    unsafe fn get_subslice_unchecked_mut(&mut self, range: R) -> SubsliceMut<'_, Self>;
517
518    /// See [`slice::get`].
519    fn get_subslice_mut(&mut self, range: R) -> Option<SubsliceMut<'_, Self>> {
520        if range.is_valid(self.len()) {
521            // SAFETY: range is checked to be within bounds.
522            unsafe { Some(self.get_subslice_unchecked_mut(range)) }
523        } else {
524            None
525        }
526    }
527}
528
529impl<R: RangeCheck, S: SliceByValueSubsliceRangeMut<R> + ?Sized> SliceByValueSubsliceRangeMut<R>
530    for &mut S
531{
532    fn get_subslice_mut(&mut self, range: R) -> Option<SubsliceMut<'_, Self>> {
533        (**self).get_subslice_mut(range)
534    }
535    fn index_subslice_mut(&mut self, range: R) -> SubsliceMut<'_, Self> {
536        (**self).index_subslice_mut(range)
537    }
538    unsafe fn get_subslice_unchecked_mut(&mut self, range: R) -> SubsliceMut<'_, Self> {
539        (**self).get_subslice_unchecked_mut(range)
540    }
541}
542
543/// A convenience trait combining all instances of [`SliceByValueSubsliceRange`]
544/// with `R` equal to the various kind of standard ranges ([`core::ops::Range`],
545/// [`core::ops::RangeFull`], etc.).
546///
547/// A blanket implementation automatically implements the trait if all necessary
548/// implementations of [`SliceByValueSubsliceRange`] are available.
549pub trait SliceByValueSubslice:
550    SliceByValueSubsliceRange<Range<usize>>
551    + SliceByValueSubsliceRange<RangeFrom<usize>>
552    + SliceByValueSubsliceRange<RangeFull>
553    + SliceByValueSubsliceRange<RangeInclusive<usize>>
554    + SliceByValueSubsliceRange<RangeTo<usize>>
555    + SliceByValueSubsliceRange<RangeToInclusive<usize>>
556{
557}
558
559impl<U> SliceByValueSubslice for U
560where
561    U: SliceByValueSubsliceRange<Range<usize>>,
562    U: SliceByValueSubsliceRange<RangeFrom<usize>>,
563    U: SliceByValueSubsliceRange<RangeFull>,
564    U: SliceByValueSubsliceRange<RangeInclusive<usize>>,
565    U: SliceByValueSubsliceRange<RangeTo<usize>>,
566    U: SliceByValueSubsliceRange<RangeToInclusive<usize>>,
567{
568}
569
570/// A convenience trait combining all instances of
571/// [`SliceByValueSubsliceRangeMut`] with `R` equal to the various kind of
572/// standard ranges ([`core::ops::Range`], [`core::ops::RangeFull`], etc.).
573///
574/// A blanket implementation automatically implements the trait if all necessary
575/// implementations of [`SliceByValueSubsliceMut`] are available.
576pub trait SliceByValueSubsliceMut:
577    SliceByValueSubsliceRangeMut<Range<usize>>
578    + SliceByValueSubsliceRangeMut<RangeFrom<usize>>
579    + SliceByValueSubsliceRangeMut<RangeFull>
580    + SliceByValueSubsliceRangeMut<RangeInclusive<usize>>
581    + SliceByValueSubsliceRangeMut<RangeTo<usize>>
582    + SliceByValueSubsliceRangeMut<RangeToInclusive<usize>>
583{
584}
585
586impl<U> SliceByValueSubsliceMut for U
587where
588    U: SliceByValueSubsliceRangeMut<Range<usize>>,
589    U: SliceByValueSubsliceRangeMut<RangeFrom<usize>>,
590    U: SliceByValueSubsliceRangeMut<RangeFull>,
591    U: SliceByValueSubsliceRangeMut<RangeInclusive<usize>>,
592    U: SliceByValueSubsliceRangeMut<RangeTo<usize>>,
593    U: SliceByValueSubsliceRangeMut<RangeToInclusive<usize>>,
594{
595}
596
597#[cfg(feature = "alloc")]
598mod alloc_impls {
599    use super::*;
600    #[cfg(all(feature = "alloc", not(feature = "std")))]
601    use alloc::boxed::Box;
602
603    impl<S: SliceByValue + ?Sized> SliceByValue for Box<S> {
604        type Value = S::Value;
605        #[inline]
606        fn len(&self) -> usize {
607            (**self).len()
608        }
609    }
610
611    impl<S: SliceByValueGet + ?Sized> SliceByValueGet for Box<S> {
612        fn get_value(&self, index: usize) -> Option<Self::Value> {
613            (**self).get_value(index)
614        }
615        fn index_value(&self, index: usize) -> Self::Value {
616            (**self).index_value(index)
617        }
618        unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
619            unsafe { (**self).get_value_unchecked(index) }
620        }
621    }
622
623    impl<S: SliceByValueSet + ?Sized> SliceByValueSet for Box<S> {
624        fn set_value(&mut self, index: usize, value: Self::Value) {
625            (**self).set_value(index, value);
626        }
627        unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
628            unsafe {
629                (**self).set_value_unchecked(index, value);
630            }
631        }
632    }
633
634    impl<S: SliceByValueRepl + ?Sized> SliceByValueRepl for Box<S> {
635        fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
636            (**self).replace_value(index, value)
637        }
638        unsafe fn replace_value_unchecked(
639            &mut self,
640            index: usize,
641            value: Self::Value,
642        ) -> Self::Value {
643            unsafe { (**self).replace_value_unchecked(index, value) }
644        }
645    }
646
647    impl<'a, S: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for Box<S> {
648        type Subslice = S::Subslice;
649    }
650    impl<'a, S: SliceByValueSubsliceGatMut<'a> + ?Sized> SliceByValueSubsliceGatMut<'a> for Box<S> {
651        type Subslice = S::Subslice;
652    }
653
654    macro_rules! impl_range_alloc {
655        ($range:ty) => {
656            impl<S: SliceByValueSubsliceRange<$range> + ?Sized> SliceByValueSubsliceRange<$range>
657                for Box<S>
658            {
659                #[inline]
660                fn get_subslice(&self, index: $range) -> Option<Subslice<'_, Self>> {
661                    (**self).get_subslice(index)
662                }
663
664                #[inline]
665                fn index_subslice(&self, index: $range) -> Subslice<'_, Self> {
666                    (**self).index_subslice(index)
667                }
668
669                #[inline]
670                unsafe fn get_subslice_unchecked(&self, index: $range) -> Subslice<'_, Self> {
671                    unsafe { (**self).get_subslice_unchecked(index) }
672                }
673            }
674            impl<S: SliceByValueSubsliceRangeMut<$range> + ?Sized>
675                SliceByValueSubsliceRangeMut<$range> for Box<S>
676            {
677                #[inline]
678                fn get_subslice_mut(&mut self, index: $range) -> Option<SubsliceMut<'_, Self>> {
679                    (**self).get_subslice_mut(index)
680                }
681
682                #[inline]
683                fn index_subslice_mut(&mut self, index: $range) -> SubsliceMut<'_, Self> {
684                    (**self).index_subslice_mut(index)
685                }
686
687                #[inline]
688                unsafe fn get_subslice_unchecked_mut(
689                    &mut self,
690                    index: $range,
691                ) -> SubsliceMut<'_, Self> {
692                    unsafe { (**self).get_subslice_unchecked_mut(index) }
693                }
694            }
695        };
696    }
697
698    impl_range_alloc!(RangeFull);
699    impl_range_alloc!(RangeFrom<usize>);
700    impl_range_alloc!(RangeTo<usize>);
701    impl_range_alloc!(Range<usize>);
702    impl_range_alloc!(RangeInclusive<usize>);
703    impl_range_alloc!(RangeToInclusive<usize>);
704}
705
706#[cfg(feature = "std")]
707mod std_impls {
708    use super::*;
709    use std::{rc::Rc, sync::Arc};
710
711    impl<S: SliceByValue + ?Sized> SliceByValue for Arc<S> {
712        type Value = S::Value;
713        #[inline]
714        fn len(&self) -> usize {
715            (**self).len()
716        }
717    }
718
719    impl<S: SliceByValueGet + ?Sized> SliceByValueGet for Arc<S> {
720        fn get_value(&self, index: usize) -> Option<Self::Value> {
721            (**self).get_value(index)
722        }
723        fn index_value(&self, index: usize) -> Self::Value {
724            (**self).index_value(index)
725        }
726        unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
727            (**self).get_value_unchecked(index)
728        }
729    }
730    impl<'a, S: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for Arc<S> {
731        type Subslice = S::Subslice;
732    }
733
734    impl<S: SliceByValue + ?Sized> SliceByValue for Rc<S> {
735        type Value = S::Value;
736        #[inline]
737        fn len(&self) -> usize {
738            (**self).len()
739        }
740    }
741
742    impl<S: SliceByValueGet + ?Sized> SliceByValueGet for Rc<S> {
743        fn get_value(&self, index: usize) -> Option<Self::Value> {
744            (**self).get_value(index)
745        }
746        fn index_value(&self, index: usize) -> Self::Value {
747            (**self).index_value(index)
748        }
749        unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
750            (**self).get_value_unchecked(index)
751        }
752    }
753
754    impl<'a, S: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for Rc<S> {
755        type Subslice = S::Subslice;
756    }
757
758    macro_rules! impl_range_arc_and_rc {
759        ($range:ty) => {
760            impl<S: SliceByValueSubsliceRange<$range> + ?Sized> SliceByValueSubsliceRange<$range>
761                for Rc<S>
762            {
763                #[inline]
764                fn get_subslice(&self, index: $range) -> Option<Subslice<'_, Self>> {
765                    (**self).get_subslice(index)
766                }
767
768                #[inline]
769                fn index_subslice(&self, index: $range) -> Subslice<'_, Self> {
770                    (**self).index_subslice(index)
771                }
772
773                #[inline]
774                unsafe fn get_subslice_unchecked(&self, index: $range) -> Subslice<'_, Self> {
775                    unsafe { (**self).get_subslice_unchecked(index) }
776                }
777            }
778            impl<S: SliceByValueSubsliceRange<$range> + ?Sized> SliceByValueSubsliceRange<$range>
779                for Arc<S>
780            {
781                #[inline]
782                fn get_subslice(&self, index: $range) -> Option<Subslice<'_, Self>> {
783                    (**self).get_subslice(index)
784                }
785
786                #[inline]
787                fn index_subslice(&self, index: $range) -> Subslice<'_, Self> {
788                    (**self).index_subslice(index)
789                }
790
791                #[inline]
792                unsafe fn get_subslice_unchecked(&self, index: $range) -> Subslice<'_, Self> {
793                    unsafe { (**self).get_subslice_unchecked(index) }
794                }
795            }
796        };
797    }
798
799    impl_range_arc_and_rc!(RangeFull);
800    impl_range_arc_and_rc!(RangeFrom<usize>);
801    impl_range_arc_and_rc!(RangeTo<usize>);
802    impl_range_arc_and_rc!(Range<usize>);
803    impl_range_arc_and_rc!(RangeInclusive<usize>);
804    impl_range_arc_and_rc!(RangeToInclusive<usize>);
805}
806
807#[cfg(test)]
808mod tests {
809
810    use super::*;
811
812    #[test]
813    #[allow(clippy::reversed_empty_ranges)]
814    fn test_good_ranges() {
815        // Range
816        assert!((0..1).is_valid(1));
817        assert!(!(1..0).is_valid(1));
818        assert!(!(0..1).is_valid(0));
819
820        // RangeFrom
821        assert!((0..).is_valid(1));
822        assert!((1..).is_valid(1));
823        assert!(!(2..).is_valid(1));
824
825        // RangeFull
826        assert!((..).is_valid(0));
827        assert!((..).is_valid(1));
828
829        // RangeInclusive
830        assert!((0..=1).is_valid(2));
831        assert!(!(1..=0).is_valid(2));
832        assert!(!(0..=1).is_valid(1));
833
834        // RangeTo
835        assert!((..0).is_valid(1));
836        assert!((..1).is_valid(1));
837        assert!(!(..2).is_valid(1));
838
839        // RangeToInclusive
840        assert!((..=0).is_valid(2));
841        assert!((..=1).is_valid(2));
842        assert!(!(..=2).is_valid(2));
843    }
844}