Skip to main content

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 by-value slices.
10//!
11//! By-value 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 by-value slice can be defined functionally, implicitly, or
16//! using a succinct/compressed representation.
17//!
18//! The fundamental trait for by-value slices is [`SliceByValue`], which
19//! specifies the type of the values, the length of the slice, and provides
20//! read-only access. Additional functionality is provided by the
21//! [`SliceByValueMut`] trait, which provides mutation methods. Note that,
22//! contrarily to the standard slices, replacement can be obtained by a pair of
23//! get/set operations: [`SliceByValueMut`] provides both methods for
24//! efficiency.
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 define a by-value read-only
38//! slice of `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//!     unsafe fn get_value_unchecked(&self, index: usize) -> usize {
52//!         unsafe { self.0.get_value_unchecked(index) as usize }
53//!     }
54//! }
55//!
56//! fn f(slice_by_value: impl SliceByValue<Value = usize>, index: usize) -> usize {
57//!     slice_by_value.index_value(index)
58//! }
59//!
60//! fn main() {
61//!     let vec = vec![0_u8, 1, 2, 3];
62//!     let slice_by_value = CompSlice(&vec);
63//!     // Note that we can pass a reference
64//!     assert_eq!(f(&slice_by_value, 0), 0);
65//!     assert_eq!(f(&slice_by_value, 1), 1);
66//!     assert_eq!(f(&slice_by_value, 2), 2);
67//!     assert_eq!(f(&slice_by_value, 3), 3);
68//! }
69//!
70//! ```
71//! In this example, instead, we define functionally a slice containing the
72//! first 100 squares:
73//!
74//! ```rust
75//! use value_traits::slices::*;
76//!
77//! struct Squares();
78//!
79//! impl SliceByValue for Squares {
80//!     type Value = usize;
81//!     fn len(&self) -> usize {
82//!         100
83//!     }
84//!
85//!     unsafe fn get_value_unchecked(&self, index: usize) -> usize {
86//!         index * index
87//!     }
88//! }
89//!
90//! fn f(slice_by_value: &impl SliceByValue<Value = usize>, index: usize) -> usize {
91//!     slice_by_value.index_value(index)
92//! }
93//!
94//! fn main() {
95//!     let squares = Squares();
96//!     for i in 0..100 {
97//!         assert_eq!(squares.index_value(i), i * i);
98//!     }
99//! }
100//! ```
101
102use core::ops::{
103    Range, RangeBounds, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
104};
105
106use crate::{ImplBound, Ref};
107
108/// Error type returned when [`try_chunks_mut`] is not supported by a type.
109///
110/// This error is typically returned by derived subslice types which cannot
111/// provide mutable chunks due to their implementation constraints.
112///
113/// [`try_chunks_mut`]: SliceByValueMut::try_chunks_mut
114#[derive(Debug, Clone, Copy, PartialEq, Eq)]
115pub struct ChunksMutNotSupported;
116
117impl core::fmt::Display for ChunksMutNotSupported {
118    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
119        write!(f, "try_chunks_mut is not supported on subslices")
120    }
121}
122
123impl core::error::Error for ChunksMutNotSupported {}
124
125#[inline(always)]
126fn assert_index(index: usize, len: usize) {
127    assert!(
128        index < len,
129        "index out of bounds: the len is {len} but the index is {index}",
130    );
131}
132
133#[inline(always)]
134fn assert_range(range: &impl ComposeRange, len: usize) {
135    assert!(
136        range.is_valid(len),
137        "range {range:?} out of range for slice of length {len}",
138    );
139}
140
141/// Read-only by-value slice trait.
142///
143/// The only methods that must be implemented are
144/// [`get_value_unchecked`] and [`len`].
145///
146/// [`get_value_unchecked`]: SliceByValue::get_value_unchecked
147/// [`len`]: SliceByValue::len
148pub trait SliceByValue {
149    /// The type of the values in the slice.
150    type Value;
151
152    /// See [`slice::len`].
153    fn len(&self) -> usize;
154
155    /// See [`slice::is_empty`].
156    fn is_empty(&self) -> bool {
157        self.len() == 0
158    }
159    /// See [the `Index` implementation for slices][slice-index].
160    ///
161    /// [slice-index]: slice#impl-Index%3CI%3E-for-%5BT%5D
162    fn index_value(&self, index: usize) -> Self::Value {
163        assert_index(index, self.len());
164        // SAFETY: index is within bounds
165        unsafe { self.get_value_unchecked(index) }
166    }
167
168    /// See [`slice::get_unchecked`].
169    ///
170    /// For a safe alternative see [`get_value`] or [`index_value`].
171    ///
172    /// # Safety
173    ///
174    /// The index must be within bounds.
175    ///
176    /// [`get_value`]: SliceByValue::get_value
177    /// [`index_value`]: SliceByValue::index_value
178    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value;
179
180    /// See [`slice::get`].
181    fn get_value(&self, index: usize) -> Option<Self::Value> {
182        if index < self.len() {
183            // SAFETY: index is within bounds
184            let value = unsafe { self.get_value_unchecked(index) };
185            Some(value)
186        } else {
187            None
188        }
189    }
190}
191
192impl<S: SliceByValue + ?Sized> SliceByValue for &S {
193    type Value = S::Value;
194
195    #[inline]
196    fn len(&self) -> usize {
197        (**self).len()
198    }
199
200    fn get_value(&self, index: usize) -> Option<Self::Value> {
201        (**self).get_value(index)
202    }
203    fn index_value(&self, index: usize) -> Self::Value {
204        (**self).index_value(index)
205    }
206    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
207        unsafe { (**self).get_value_unchecked(index) }
208    }
209}
210
211impl<S: SliceByValue + ?Sized> SliceByValue for &mut S {
212    type Value = S::Value;
213
214    #[inline]
215    fn len(&self) -> usize {
216        (**self).len()
217    }
218
219    fn get_value(&self, index: usize) -> Option<Self::Value> {
220        (**self).get_value(index)
221    }
222    fn index_value(&self, index: usize) -> Self::Value {
223        (**self).index_value(index)
224    }
225    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
226        unsafe { (**self).get_value_unchecked(index) }
227    }
228}
229
230/// Mutable by-value slice trait providing setting and replacement methods.
231///
232/// This trait provides both [`set_value`] (for setting without returning the
233/// previous value) and [`replace_value`] (for setting and returning the
234/// previous value).
235///
236/// The only methods that must be implemented are [`set_value_unchecked`] and
237/// [`replace_value_unchecked`].
238///
239/// [`set_value`]: SliceByValueMut::set_value
240/// [`replace_value`]: SliceByValueMut::replace_value
241/// [`set_value_unchecked`]: SliceByValueMut::set_value_unchecked
242/// [`replace_value_unchecked`]: SliceByValueMut::replace_value_unchecked
243pub trait SliceByValueMut: SliceByValue {
244    /// Sets the value at the given index to the given value without doing
245    /// bounds checking.
246    ///
247    /// For a safe alternative see [`set_value`].
248    ///
249    /// # Safety
250    ///
251    /// The index must be within bounds.
252    ///
253    /// [`set_value`]: SliceByValueMut::set_value
254    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value);
255
256    /// Sets the value at the given index to the given value.
257    ///
258    /// # Panics
259    ///
260    /// This method will panic if the index is not within bounds.
261    fn set_value(&mut self, index: usize, value: Self::Value) {
262        assert_index(index, self.len());
263        // SAFETY: index is within bounds
264        unsafe {
265            self.set_value_unchecked(index, value);
266        }
267    }
268
269    /// Sets the value at the given index to the given value and
270    /// returns the previous value, without doing bounds checking.
271    ///
272    /// For a safe alternative see [`replace_value`].
273    ///
274    /// This default implementation uses [`get_value_unchecked`] and
275    /// [`set_value_unchecked`].
276    ///
277    /// # Safety
278    ///
279    /// The index must be within bounds.
280    ///
281    /// [`replace_value`]: SliceByValueMut::replace_value
282    /// [`get_value_unchecked`]: SliceByValue::get_value_unchecked
283    /// [`set_value_unchecked`]: SliceByValueMut::set_value_unchecked
284    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
285        let old_value = unsafe { self.get_value_unchecked(index) };
286        unsafe { self.set_value_unchecked(index, value) };
287        old_value
288    }
289
290    /// Sets the value at the given index to the given value and
291    /// returns the previous value.
292    ///
293    /// # Panics
294    ///
295    /// This method will panic if the index is not within bounds.
296    fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
297        assert_index(index, self.len());
298        // SAFETY: index is within bounds
299        unsafe { self.replace_value_unchecked(index, value) }
300    }
301
302    /// Copy part of the content of the slice to another slice.
303    ///
304    /// At most `len` elements are copied, compatibly with the elements
305    /// available in both slices.
306    ///
307    /// # Arguments
308    ///
309    /// * `from`: the index of the first element to copy.
310    ///
311    /// * `dst`: the destination slice.
312    ///
313    /// * `to`: the index of the first element in the destination slice.
314    ///
315    /// * `len`: the maximum number of elements to copy.
316    ///
317    /// # Implementation Notes
318    ///
319    /// The default implementation is a simple loop that copies the elements one
320    /// by one. It is expected to be implemented in a more efficient way.
321    fn copy(
322        &self,
323        from: usize,
324        dst: &mut (impl SliceByValueMut<Value = Self::Value> + ?Sized),
325        to: usize,
326        len: usize,
327    ) {
328        // Reduce len to the elements available in both vectors
329        let len = Ord::min(
330            Ord::min(len, dst.len().saturating_sub(to)),
331            self.len().saturating_sub(from),
332        );
333        for i in 0..len {
334            dst.set_value(to + i, self.index_value(from + i));
335        }
336    }
337
338    /// Applies a function to all elements of the slice in place without
339    /// checks.
340    ///
341    /// This method is semantically equivalent to:
342    /// ```ignore
343    /// for i in 0..self.len() {
344    ///     self.set_value_unchecked(i, f(self.get_value_unchecked(i)));
345    /// }
346    /// ```
347    /// and this is indeed the default implementation.
348    ///
349    /// See [`apply_in_place`] for examples.
350    ///
351    /// # Safety
352    ///
353    /// The function must return a value that agrees with the safety
354    /// requirements of [`set_value_unchecked`].
355    ///
356    /// [`apply_in_place`]: SliceByValueMut::apply_in_place
357    /// [`set_value_unchecked`]: SliceByValueMut::set_value_unchecked
358    unsafe fn apply_in_place_unchecked<F>(&mut self, mut f: F)
359    where
360        F: FnMut(Self::Value) -> Self::Value,
361    {
362        for idx in 0..self.len() {
363            let value = unsafe { self.get_value_unchecked(idx) };
364            let new_value = f(value);
365            unsafe { self.set_value_unchecked(idx, new_value) };
366        }
367    }
368
369    /// Applies a function to all elements of the slice in place.
370    ///
371    /// This method is semantically equivalent to:
372    /// ```ignore
373    /// for i in 0..self.len() {
374    ///     self.set_value(i, f(self.index_value(i)));
375    /// }
376    /// ```
377    /// and this is indeed the default implementation.
378    ///
379    /// The function is applied from the first element to the last: thus,
380    /// it possible to compute cumulative sums as follows:
381    ///
382    /// ```
383    /// use value_traits::slices::SliceByValueMut;
384    /// let mut vec = vec![0; 10];
385    ///
386    /// for i in 0..10 {
387    ///     vec.set_value(i, i as u16);
388    /// }
389    ///
390    /// let mut total = 0;
391    /// vec.apply_in_place(|x| {
392    ///     total += x;
393    ///     total
394    /// });
395    /// ```
396    fn apply_in_place<F>(&mut self, mut f: F)
397    where
398        F: FnMut(Self::Value) -> Self::Value,
399    {
400        for idx in 0..self.len() {
401            let value = unsafe { self.get_value_unchecked(idx) };
402            let new_value = f(value);
403            unsafe { self.set_value_unchecked(idx, new_value) };
404        }
405    }
406
407    /// The iterator type returned by [`try_chunks_mut`].
408    ///
409    /// [`try_chunks_mut`]: SliceByValueMut::try_chunks_mut
410    type ChunksMut<'a>: Iterator<Item: SliceByValueMut<Value = Self::Value>>
411    where
412        Self: 'a;
413
414    /// The error type returned by [`try_chunks_mut`].
415    ///
416    /// For implementations that always succeed (like slices, arrays, and vectors),
417    /// this should be [`core::convert::Infallible`].
418    ///
419    /// [`try_chunks_mut`]: SliceByValueMut::try_chunks_mut
420    type ChunksMutError: core::fmt::Debug;
421
422    /// Tries and returns an iterator over mutable chunks of a slice, starting
423    /// at the beginning of the slice.
424    ///
425    /// This might not always be possible; implementations must document when
426    /// the method will succeed (see, for example, [the implementation for
427    /// `BitFieldVec`][bit-field-vec]).
428    ///
429    /// When the slice len is not evenly divided by the chunk size, the last
430    /// chunk of the iteration will be the remainder.
431    ///
432    /// # Errors
433    ///
434    /// Returns an error of type [`ChunksMutError`] if the operation is not
435    /// supported by the implementation. For example, derived subslice types
436    /// return [`ChunksMutNotSupported`].
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// use value_traits::slices::SliceByValueMut;
442    /// let mut b = vec![4, 500, 2, 3, 1];
443    /// for mut c in b.try_chunks_mut(2)? {
444    ///     c.set_value(0, 5);
445    /// }
446    /// assert_eq!(b, vec![5, 500, 5, 3, 5]);
447    /// # Ok::<(), Box<dyn std::error::Error>>(())
448    /// ```
449    ///
450    /// [bit-field-vec]: https://docs.rs/sux/latest/sux/bits/bit_field_vec/struct.BitFieldVec.html#impl-BitFieldSliceMut<W>-for-BitFieldVec<W,+B>
451    /// [`ChunksMutError`]: SliceByValueMut::ChunksMutError
452    fn try_chunks_mut(
453        &mut self,
454        chunk_size: usize,
455    ) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError>;
456}
457
458impl<S: SliceByValueMut + ?Sized> SliceByValueMut for &mut S {
459    fn set_value(&mut self, index: usize, value: Self::Value) {
460        (**self).set_value(index, value);
461    }
462    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
463        unsafe {
464            (**self).set_value_unchecked(index, value);
465        }
466    }
467    fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
468        (**self).replace_value(index, value)
469    }
470    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
471        unsafe { (**self).replace_value_unchecked(index, value) }
472    }
473
474    type ChunksMut<'a>
475        = S::ChunksMut<'a>
476    where
477        Self: 'a;
478
479    type ChunksMutError = S::ChunksMutError;
480
481    fn try_chunks_mut(
482        &mut self,
483        chunk_size: usize,
484    ) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
485        (**self).try_chunks_mut(chunk_size)
486    }
487}
488
489/// A range that can check whether it is within the bounds of a slice, and
490/// intersect itself with another range.
491///
492/// This trait is implemented for the six Rust range types in [`core::ops`],
493/// making it possible to treat them uniformly in implementations, and in
494/// particular in procedural macros.
495pub trait ComposeRange: RangeBounds<usize> + core::fmt::Debug {
496    /// Returns `true` if the range is within the bounds of a slice of given
497    /// length
498    fn is_valid(&self, len: usize) -> bool;
499
500    /// Returns a new range that is the composition of `base` with the range.
501    ///
502    /// The resulting range is guaranteed to be contained in `base` if `self`
503    /// [is valid][ComposeRange::is_valid] for `base.len()`.
504    ///
505    /// ```rust
506    /// use value_traits::slices::ComposeRange;
507    ///
508    /// assert_eq!((2..5).compose(10..20),  12..15);
509    /// assert_eq!((2..=5).compose(10..20), 12..16);
510    /// assert_eq!((..5).compose(10..20),   10..15);
511    /// assert_eq!((..=5).compose(10..20),  10..16);
512    /// assert_eq!((2..).compose(10..20),   12..20);
513    /// assert_eq!((..).compose(10..20),    10..20);
514    /// ```
515    fn compose(&self, base: Range<usize>) -> Range<usize>;
516}
517
518impl ComposeRange for Range<usize> {
519    fn is_valid(&self, len: usize) -> bool {
520        self.start <= len && self.end <= len && self.start <= self.end
521    }
522
523    fn compose(&self, base: Range<usize>) -> Range<usize> {
524        (base.start + self.start)..(base.start + self.end)
525    }
526}
527
528impl ComposeRange for RangeFrom<usize> {
529    fn is_valid(&self, len: usize) -> bool {
530        self.start <= len
531    }
532
533    fn compose(&self, base: Range<usize>) -> Range<usize> {
534        (base.start + self.start)..base.end
535    }
536}
537
538impl ComposeRange for RangeFull {
539    fn is_valid(&self, _len: usize) -> bool {
540        true
541    }
542
543    fn compose(&self, base: Range<usize>) -> Range<usize> {
544        base
545    }
546}
547
548impl ComposeRange for RangeInclusive<usize> {
549    fn is_valid(&self, len: usize) -> bool {
550        // Same semantics as the standard library: empty inclusive ranges
551        // (start == end + 1) are valid if they are within bounds. Note that
552        // the first condition guarantees that end + 1 cannot overflow.
553        *self.end() < len && *self.start() <= *self.end() + 1
554    }
555
556    fn compose(&self, base: Range<usize>) -> Range<usize> {
557        (base.start + self.start())..(base.start + self.end() + 1)
558    }
559}
560
561impl ComposeRange for RangeTo<usize> {
562    fn is_valid(&self, len: usize) -> bool {
563        self.end <= len
564    }
565
566    fn compose(&self, base: Range<usize>) -> Range<usize> {
567        base.start..(base.start + self.end)
568    }
569}
570
571impl ComposeRange for RangeToInclusive<usize> {
572    fn is_valid(&self, len: usize) -> bool {
573        self.end < len
574    }
575
576    fn compose(&self, base: Range<usize>) -> Range<usize> {
577        base.start..(base.start + self.end + 1)
578    }
579}
580
581/// A GAT-like trait specifying the subslice type.
582///
583/// It implicitly restricts the lifetime `'a` used in `SliceByValueRange` to be
584/// `where Self: 'a`. Moreover, it requires [`SliceByValue`].
585///
586/// As in other theoretical applications of GATs (Generic Associated Types),
587/// like [lenders], using a GAT to express the
588/// type of a subslice is problematic because when bounding the type itself in a
589/// `where` clause using Higher-Rank Trait Bounds (HRTBs) the bound must be true
590/// for all lifetimes, including `'static`, resulting in the sliced type having
591/// to be `'static` as well.
592///
593/// This is a result of HRTBs not having a way to express qualifiers (`for<'any
594/// where Self: 'any> Self: Trait`) and effectively making HRTBs only useful
595/// when you want to express a trait constraint on *all* lifetimes, including
596/// `'static` (`for<'all> Self: trait`)
597///
598/// Please see [Sabrina's Blog][1] for more information, and how a trait like
599/// this can be used to solve it by implicitly restricting HRTBs.
600///
601/// [lenders]: https://crates.io/crates/lender
602/// [1]:
603///     <https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats>
604pub trait SliceByValueSubsliceGat<'a, __Implicit: ImplBound = Ref<'a, Self>>: SliceByValue {
605    /// The type of the subslice.
606    type Subslice: 'a + SliceByValue<Value = Self::Value> + SliceByValueSubslice;
607}
608
609/// A convenience type representing the type of subslice
610/// of a type implementing [`SliceByValueSubsliceGat`].
611#[allow(type_alias_bounds)] // yeah the type alias bounds are not enforced, but they are useful for documentation
612pub type Subslice<'a, T: SliceByValueSubsliceGat<'a>> =
613    <T as SliceByValueSubsliceGat<'a>>::Subslice;
614
615impl<'a, T: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for &T {
616    type Subslice = T::Subslice;
617}
618
619impl<'a, T: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for &mut T {
620    type Subslice = T::Subslice;
621}
622
623/// A trait implementing subslicing for a specific range parameter.
624///
625/// The user should never see this trait. [`SliceByValueSubslice`] combines all
626/// instances of this trait with `R` equal to the various kind of standard
627/// ranges ([`core::ops::Range`], [`core::ops::RangeFull`], etc.).
628///
629/// The only method that must be implemented is
630/// [`get_subslice_unchecked`].
631///
632/// [`get_subslice_unchecked`]: SliceByValueSubsliceRange::get_subslice_unchecked
633pub trait SliceByValueSubsliceRange<R: ComposeRange>: for<'a> SliceByValueSubsliceGat<'a> {
634    /// See [the `Index` implementation for slices][slice-index].
635    ///
636    /// [slice-index]: slice#impl-Index%3CI%3E-for-%5BT%5D
637    fn index_subslice(&self, range: R) -> Subslice<'_, Self> {
638        assert_range(&range, self.len());
639        unsafe {
640            // SAFETY: range is within bounds
641            self.get_subslice_unchecked(range)
642        }
643    }
644
645    /// See [`slice::get_unchecked`].
646    ///
647    /// For a safe alternative see [`get_subslice`] or [`index_subslice`].
648    ///
649    /// # Safety
650    ///
651    /// The range must be within bounds.
652    ///
653    /// [`get_subslice`]: SliceByValueSubsliceRange::get_subslice
654    /// [`index_subslice`]: SliceByValueSubsliceRange::index_subslice
655    unsafe fn get_subslice_unchecked(&self, range: R) -> Subslice<'_, Self>;
656
657    /// See [`slice::get`].
658    fn get_subslice(&self, range: R) -> Option<Subslice<'_, Self>> {
659        if range.is_valid(self.len()) {
660            let subslice = unsafe { self.get_subslice_unchecked(range) };
661            Some(subslice)
662        } else {
663            None
664        }
665    }
666}
667
668impl<R: ComposeRange, S: SliceByValueSubsliceRange<R> + ?Sized> SliceByValueSubsliceRange<R>
669    for &S
670{
671    fn get_subslice(&self, range: R) -> Option<Subslice<'_, Self>> {
672        (**self).get_subslice(range)
673    }
674    fn index_subslice(&self, range: R) -> Subslice<'_, Self> {
675        (**self).index_subslice(range)
676    }
677    unsafe fn get_subslice_unchecked(&self, range: R) -> Subslice<'_, Self> {
678        unsafe { (**self).get_subslice_unchecked(range) }
679    }
680}
681impl<R: ComposeRange, S: SliceByValueSubsliceRange<R> + ?Sized> SliceByValueSubsliceRange<R>
682    for &mut S
683{
684    fn get_subslice(&self, range: R) -> Option<Subslice<'_, Self>> {
685        (**self).get_subslice(range)
686    }
687    fn index_subslice(&self, range: R) -> Subslice<'_, Self> {
688        (**self).index_subslice(range)
689    }
690    unsafe fn get_subslice_unchecked(&self, range: R) -> Subslice<'_, Self> {
691        unsafe { (**self).get_subslice_unchecked(range) }
692    }
693}
694
695/// A GAT-like trait specifying the mutable subslice type.
696///
697/// See [`SliceByValueSubsliceGat`].
698pub trait SliceByValueSubsliceGatMut<'a, __Implicit: ImplBound = Ref<'a, Self>>:
699    SliceByValueMut
700{
701    /// The type of the mutable subslice.
702    type SubsliceMut: 'a
703        + SliceByValueMut<Value = Self::Value>
704        + SliceByValueSubsliceGatMut<'a, SubsliceMut = Self::SubsliceMut> // recursion
705        + SliceByValueSubsliceMut;
706}
707
708/// A convenience type representing the type of subslice
709/// of a type implementing [`SliceByValueSubsliceGatMut`].
710#[allow(type_alias_bounds)] // yeah the type alias bounds are not enforced, but they are useful for documentation
711pub type SubsliceMut<'a, T: SliceByValueSubsliceGatMut<'a>> =
712    <T as SliceByValueSubsliceGatMut<'a>>::SubsliceMut;
713
714impl<'a, T: SliceByValueSubsliceGatMut<'a> + ?Sized> SliceByValueSubsliceGatMut<'a> for &mut T {
715    type SubsliceMut = T::SubsliceMut;
716}
717
718/// A trait implementing mutable subslicing for a specific range parameter.
719///
720///  The user should never see this trait. [`SliceByValueSubsliceMut`] combines
721/// all instances of this trait with `R` equal to the various kind of standard
722/// ranges ([`core::ops::Range`], [`core::ops::RangeFull`], etc.).
723///
724/// The only method that must be implemented is
725/// [`get_subslice_unchecked_mut`].
726///
727/// [`get_subslice_unchecked_mut`]: SliceByValueSubsliceRangeMut::get_subslice_unchecked_mut
728pub trait SliceByValueSubsliceRangeMut<R: ComposeRange>:
729    for<'a> SliceByValueSubsliceGatMut<'a>
730{
731    /// See [the `Index` implementation for slices][slice-index].
732    ///
733    /// [slice-index]: slice#impl-Index%3CI%3E-for-%5BT%5D
734    fn index_subslice_mut(&mut self, range: R) -> SubsliceMut<'_, Self> {
735        assert_range(&range, self.len());
736        unsafe {
737            // SAFETY: range is within bounds
738            self.get_subslice_unchecked_mut(range)
739        }
740    }
741
742    /// See [`slice::get_unchecked`].
743    ///
744    /// For a safe alternative see [`get_subslice_mut`] or
745    /// [`index_subslice_mut`].
746    ///
747    /// # Safety
748    ///
749    /// The range must be within bounds.
750    ///
751    /// [`get_subslice_mut`]: SliceByValueSubsliceRangeMut::get_subslice_mut
752    /// [`index_subslice_mut`]: SliceByValueSubsliceRangeMut::index_subslice_mut
753    unsafe fn get_subslice_unchecked_mut(&mut self, range: R) -> SubsliceMut<'_, Self>;
754
755    /// See [`slice::get`].
756    fn get_subslice_mut(&mut self, range: R) -> Option<SubsliceMut<'_, Self>> {
757        if range.is_valid(self.len()) {
758            // SAFETY: range is within bounds
759            let subslice_mut = unsafe { self.get_subslice_unchecked_mut(range) };
760            Some(subslice_mut)
761        } else {
762            None
763        }
764    }
765}
766
767impl<R: ComposeRange, S: SliceByValueSubsliceRangeMut<R> + ?Sized> SliceByValueSubsliceRangeMut<R>
768    for &mut S
769{
770    fn get_subslice_mut(&mut self, range: R) -> Option<SubsliceMut<'_, Self>> {
771        (**self).get_subslice_mut(range)
772    }
773    fn index_subslice_mut(&mut self, range: R) -> SubsliceMut<'_, Self> {
774        (**self).index_subslice_mut(range)
775    }
776    unsafe fn get_subslice_unchecked_mut(&mut self, range: R) -> SubsliceMut<'_, Self> {
777        unsafe { (**self).get_subslice_unchecked_mut(range) }
778    }
779}
780
781/// A convenience trait combining all instances of [`SliceByValueSubsliceRange`]
782/// with `R` equal to the various kind of standard ranges ([`core::ops::Range`],
783/// [`core::ops::RangeFull`], etc.).
784///
785/// A blanket implementation automatically implements the trait if all necessary
786/// implementations of [`SliceByValueSubsliceRange`] are available.
787///
788/// ## Binding the Subslice Type
789///
790/// To bind the iterator type you need to use higher-rank trait
791/// bounds, as in:
792///
793/// ```rust
794/// use value_traits::slices::*;
795///
796/// fn f<S>(s: S) where
797///    S: SliceByValueSubslice + for<'a> SliceByValueSubsliceGat<'a, Subslice = &'a [u8]>,
798/// {
799///     let _: &[u8] = s.index_subslice(0..10);
800/// }
801/// ```
802///
803/// The bound applies uniformly to all type of ranges.
804///
805/// You can also bind the subslice using traits:
806///
807/// ```rust
808/// use value_traits::slices::*;
809///
810/// fn f<S>(s: S) where
811///    S: SliceByValueSubslice + for<'a> SliceByValueSubsliceGat<'a, Subslice: AsRef<[u8]>>,
812/// {
813///     let _: &[u8] = s.index_subslice(0..10).as_ref();
814/// }
815/// ```
816///
817/// In this case, you can equivalently use the [`Subslice`] type alias, which might
818/// be more concise:
819///
820/// ```rust
821/// use value_traits::slices::*;
822///
823/// fn f<S>(s: S) where
824///    S: SliceByValueSubslice,
825///    for<'a> Subslice<'a, S>: AsRef<[u8]>,
826/// {
827///     let _: &[u8] = s.index_subslice(0..10).as_ref();
828/// }
829/// ```
830pub trait SliceByValueSubslice:
831    SliceByValueSubsliceRange<Range<usize>>
832    + SliceByValueSubsliceRange<RangeFrom<usize>>
833    + SliceByValueSubsliceRange<RangeFull>
834    + SliceByValueSubsliceRange<RangeInclusive<usize>>
835    + SliceByValueSubsliceRange<RangeTo<usize>>
836    + SliceByValueSubsliceRange<RangeToInclusive<usize>>
837{
838}
839
840impl<U> SliceByValueSubslice for U
841where
842    U: SliceByValueSubsliceRange<Range<usize>>,
843    U: SliceByValueSubsliceRange<RangeFrom<usize>>,
844    U: SliceByValueSubsliceRange<RangeFull>,
845    U: SliceByValueSubsliceRange<RangeInclusive<usize>>,
846    U: SliceByValueSubsliceRange<RangeTo<usize>>,
847    U: SliceByValueSubsliceRange<RangeToInclusive<usize>>,
848{
849}
850
851/// A convenience trait combining all instances of
852/// [`SliceByValueSubsliceRangeMut`] with `R` equal to the various kind of
853/// standard ranges ([`core::ops::Range`], [`core::ops::RangeFull`], etc.).
854///
855/// A blanket implementation automatically implements the trait if all necessary
856/// implementations of [`SliceByValueSubsliceMut`] are available.
857///
858/// ## Binding the Subslice Type
859///
860/// To bind the iterator type you need to use higher-rank trait
861/// bounds, as in:
862///
863/// ```rust
864/// use value_traits::slices::*;
865///
866/// fn f<S>(mut s: S) where
867///    S: SliceByValueSubsliceMut + for<'a> SliceByValueSubsliceGatMut<'a, SubsliceMut = &'a mut [u8]>,
868/// {
869///     let _: &mut [u8] = s.index_subslice_mut(0..10);
870/// }
871/// ```
872///
873/// The bound applies uniformly to all type of ranges.
874///
875/// You can also bind the subslice using traits:
876///
877/// ```rust
878/// use value_traits::slices::*;
879///
880/// fn f<S>(mut s: S) where
881///    S: SliceByValueSubsliceMut + for<'a> SliceByValueSubsliceGatMut<'a, SubsliceMut: AsMut<[u8]>>,
882/// {
883///     let _: &mut [u8] = s.index_subslice_mut(0..10).as_mut();
884/// }
885/// ```
886///
887/// In this case, you can equivalently use the [`SubsliceMut`] type alias, which might
888/// be more concise:
889///
890/// ```rust
891/// use value_traits::slices::*;
892///
893/// fn f<S>(mut s: S) where
894///    S: SliceByValueSubsliceMut,
895///    for<'a> SubsliceMut<'a, S>: AsMut<[u8]>,
896/// {
897///     let _: &mut [u8] = s.index_subslice_mut(0..10).as_mut();
898/// }
899/// ```
900pub trait SliceByValueSubsliceMut:
901    SliceByValueSubsliceRangeMut<Range<usize>>
902    + SliceByValueSubsliceRangeMut<RangeFrom<usize>>
903    + SliceByValueSubsliceRangeMut<RangeFull>
904    + SliceByValueSubsliceRangeMut<RangeInclusive<usize>>
905    + SliceByValueSubsliceRangeMut<RangeTo<usize>>
906    + SliceByValueSubsliceRangeMut<RangeToInclusive<usize>>
907{
908}
909
910impl<U> SliceByValueSubsliceMut for U
911where
912    U: SliceByValueSubsliceRangeMut<Range<usize>>,
913    U: SliceByValueSubsliceRangeMut<RangeFrom<usize>>,
914    U: SliceByValueSubsliceRangeMut<RangeFull>,
915    U: SliceByValueSubsliceRangeMut<RangeInclusive<usize>>,
916    U: SliceByValueSubsliceRangeMut<RangeTo<usize>>,
917    U: SliceByValueSubsliceRangeMut<RangeToInclusive<usize>>,
918{
919}
920
921#[cfg(feature = "alloc")]
922mod alloc_impls {
923    use super::*;
924    #[cfg(all(feature = "alloc", not(feature = "std")))]
925    use alloc::boxed::Box;
926
927    impl<S: SliceByValue + ?Sized> SliceByValue for Box<S> {
928        type Value = S::Value;
929
930        #[inline]
931        fn len(&self) -> usize {
932            (**self).len()
933        }
934
935        fn get_value(&self, index: usize) -> Option<Self::Value> {
936            (**self).get_value(index)
937        }
938        fn index_value(&self, index: usize) -> Self::Value {
939            (**self).index_value(index)
940        }
941        unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
942            unsafe { (**self).get_value_unchecked(index) }
943        }
944    }
945
946    impl<S: SliceByValueMut + ?Sized> SliceByValueMut for Box<S> {
947        fn set_value(&mut self, index: usize, value: Self::Value) {
948            (**self).set_value(index, value);
949        }
950        unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
951            unsafe {
952                (**self).set_value_unchecked(index, value);
953            }
954        }
955        fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
956            (**self).replace_value(index, value)
957        }
958        unsafe fn replace_value_unchecked(
959            &mut self,
960            index: usize,
961            value: Self::Value,
962        ) -> Self::Value {
963            unsafe { (**self).replace_value_unchecked(index, value) }
964        }
965
966        type ChunksMut<'a>
967            = S::ChunksMut<'a>
968        where
969            Self: 'a;
970
971        type ChunksMutError = S::ChunksMutError;
972
973        fn try_chunks_mut(
974            &mut self,
975            chunk_size: usize,
976        ) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
977            (**self).try_chunks_mut(chunk_size)
978        }
979    }
980
981    impl<'a, S: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for Box<S> {
982        type Subslice = S::Subslice;
983    }
984    impl<'a, S: SliceByValueSubsliceGatMut<'a> + ?Sized> SliceByValueSubsliceGatMut<'a> for Box<S> {
985        type SubsliceMut = S::SubsliceMut;
986    }
987
988    macro_rules! impl_range_alloc {
989        ($range:ty) => {
990            impl<S: SliceByValueSubsliceRange<$range> + ?Sized> SliceByValueSubsliceRange<$range>
991                for Box<S>
992            {
993                #[inline]
994                fn get_subslice(&self, index: $range) -> Option<Subslice<'_, Self>> {
995                    (**self).get_subslice(index)
996                }
997
998                #[inline]
999                fn index_subslice(&self, index: $range) -> Subslice<'_, Self> {
1000                    (**self).index_subslice(index)
1001                }
1002
1003                #[inline]
1004                unsafe fn get_subslice_unchecked(&self, index: $range) -> Subslice<'_, Self> {
1005                    unsafe { (**self).get_subslice_unchecked(index) }
1006                }
1007            }
1008            impl<S: SliceByValueSubsliceRangeMut<$range> + ?Sized>
1009                SliceByValueSubsliceRangeMut<$range> for Box<S>
1010            {
1011                #[inline]
1012                fn get_subslice_mut(&mut self, index: $range) -> Option<SubsliceMut<'_, Self>> {
1013                    (**self).get_subslice_mut(index)
1014                }
1015
1016                #[inline]
1017                fn index_subslice_mut(&mut self, index: $range) -> SubsliceMut<'_, Self> {
1018                    (**self).index_subslice_mut(index)
1019                }
1020
1021                #[inline]
1022                unsafe fn get_subslice_unchecked_mut(
1023                    &mut self,
1024                    index: $range,
1025                ) -> SubsliceMut<'_, Self> {
1026                    unsafe { (**self).get_subslice_unchecked_mut(index) }
1027                }
1028            }
1029        };
1030    }
1031
1032    impl_range_alloc!(RangeFull);
1033    impl_range_alloc!(RangeFrom<usize>);
1034    impl_range_alloc!(RangeTo<usize>);
1035    impl_range_alloc!(Range<usize>);
1036    impl_range_alloc!(RangeInclusive<usize>);
1037    impl_range_alloc!(RangeToInclusive<usize>);
1038}
1039
1040#[cfg(feature = "std")]
1041mod std_impls {
1042    use super::*;
1043    use std::{rc::Rc, sync::Arc};
1044
1045    impl<S: SliceByValue + ?Sized> SliceByValue for Arc<S> {
1046        type Value = S::Value;
1047
1048        #[inline]
1049        fn len(&self) -> usize {
1050            (**self).len()
1051        }
1052
1053        fn get_value(&self, index: usize) -> Option<Self::Value> {
1054            (**self).get_value(index)
1055        }
1056        fn index_value(&self, index: usize) -> Self::Value {
1057            (**self).index_value(index)
1058        }
1059        unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
1060            unsafe { (**self).get_value_unchecked(index) }
1061        }
1062    }
1063    impl<'a, S: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for Arc<S> {
1064        type Subslice = S::Subslice;
1065    }
1066
1067    impl<S: SliceByValue + ?Sized> SliceByValue for Rc<S> {
1068        type Value = S::Value;
1069
1070        #[inline]
1071        fn len(&self) -> usize {
1072            (**self).len()
1073        }
1074
1075        fn get_value(&self, index: usize) -> Option<Self::Value> {
1076            (**self).get_value(index)
1077        }
1078        fn index_value(&self, index: usize) -> Self::Value {
1079            (**self).index_value(index)
1080        }
1081        unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
1082            unsafe { (**self).get_value_unchecked(index) }
1083        }
1084    }
1085
1086    impl<'a, S: SliceByValueSubsliceGat<'a> + ?Sized> SliceByValueSubsliceGat<'a> for Rc<S> {
1087        type Subslice = S::Subslice;
1088    }
1089
1090    macro_rules! impl_range_arc_and_rc {
1091        ($range:ty) => {
1092            impl<S: SliceByValueSubsliceRange<$range> + ?Sized> SliceByValueSubsliceRange<$range>
1093                for Rc<S>
1094            {
1095                #[inline]
1096                fn get_subslice(&self, index: $range) -> Option<Subslice<'_, Self>> {
1097                    (**self).get_subslice(index)
1098                }
1099
1100                #[inline]
1101                fn index_subslice(&self, index: $range) -> Subslice<'_, Self> {
1102                    (**self).index_subslice(index)
1103                }
1104
1105                #[inline]
1106                unsafe fn get_subslice_unchecked(&self, index: $range) -> Subslice<'_, Self> {
1107                    unsafe { (**self).get_subslice_unchecked(index) }
1108                }
1109            }
1110            impl<S: SliceByValueSubsliceRange<$range> + ?Sized> SliceByValueSubsliceRange<$range>
1111                for Arc<S>
1112            {
1113                #[inline]
1114                fn get_subslice(&self, index: $range) -> Option<Subslice<'_, Self>> {
1115                    (**self).get_subslice(index)
1116                }
1117
1118                #[inline]
1119                fn index_subslice(&self, index: $range) -> Subslice<'_, Self> {
1120                    (**self).index_subslice(index)
1121                }
1122
1123                #[inline]
1124                unsafe fn get_subslice_unchecked(&self, index: $range) -> Subslice<'_, Self> {
1125                    unsafe { (**self).get_subslice_unchecked(index) }
1126                }
1127            }
1128        };
1129    }
1130
1131    impl_range_arc_and_rc!(RangeFull);
1132    impl_range_arc_and_rc!(RangeFrom<usize>);
1133    impl_range_arc_and_rc!(RangeTo<usize>);
1134    impl_range_arc_and_rc!(Range<usize>);
1135    impl_range_arc_and_rc!(RangeInclusive<usize>);
1136    impl_range_arc_and_rc!(RangeToInclusive<usize>);
1137}
1138
1139#[cfg(test)]
1140mod tests {
1141
1142    use super::*;
1143
1144    #[test]
1145    #[allow(clippy::reversed_empty_ranges)]
1146    fn test_good_ranges() {
1147        // Range
1148        assert!((0..1).is_valid(1));
1149        assert!(!(1..0).is_valid(1));
1150        assert!(!(0..1).is_valid(0));
1151
1152        // RangeFrom
1153        assert!((0..).is_valid(1));
1154        assert!((1..).is_valid(1));
1155        assert!(!(2..).is_valid(1));
1156
1157        // RangeFull
1158        assert!((..).is_valid(0));
1159        assert!((..).is_valid(1));
1160
1161        // RangeInclusive
1162        assert!((0..=1).is_valid(2));
1163        // Empty inclusive ranges are valid if within bounds, as in the
1164        // standard library
1165        assert!((1..=0).is_valid(2));
1166        assert!((2..=1).is_valid(2));
1167        assert!(!(3..=1).is_valid(2));
1168        assert!(!(0..=1).is_valid(1));
1169        assert!(!(0..=usize::MAX).is_valid(usize::MAX));
1170
1171        // RangeTo
1172        assert!((..0).is_valid(1));
1173        assert!((..1).is_valid(1));
1174        assert!(!(..2).is_valid(1));
1175
1176        // RangeToInclusive
1177        assert!((..=0).is_valid(2));
1178        assert!((..=1).is_valid(2));
1179        assert!(!(..=2).is_valid(2));
1180    }
1181}