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