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