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}