Skip to main content

value_traits/impls/
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//! Implementations of by-value traits for (boxed) slices of [cloneable]
10//! types.
11//!
12//! Implementations for boxed slices are only available if the `alloc` feature is
13//! enabled.
14//!
15//! [cloneable]: Clone
16
17use core::{
18    iter::{Cloned, Skip},
19    ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
20};
21
22use crate::{
23    iter::{
24        Iter, IterFrom, IterateByValue, IterateByValueFrom, IterateByValueFromGat,
25        IterateByValueGat,
26    },
27    slices::{
28        SliceByValue, SliceByValueMut, SliceByValueSubsliceGat, SliceByValueSubsliceGatMut,
29        SliceByValueSubsliceRange, SliceByValueSubsliceRangeMut, Subslice, SubsliceMut,
30    },
31};
32
33// --- Implementations for standard slices [T] and usize index ---
34impl<T: Clone> SliceByValue for [T] {
35    type Value = T;
36
37    #[inline]
38    fn len(&self) -> usize {
39        <[T]>::len(self)
40    }
41    #[inline]
42    fn get_value(&self, index: usize) -> Option<Self::Value> {
43        (*self).get(index).cloned()
44    }
45
46    #[inline]
47    fn index_value(&self, index: usize) -> Self::Value {
48        self[index].clone()
49    }
50
51    #[inline]
52    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
53        // SAFETY: index is within bounds
54        let value = unsafe { (*self).get_unchecked(index) };
55        value.clone()
56    }
57}
58
59impl<T: Clone> SliceByValueMut for [T] {
60    #[inline]
61    fn set_value(&mut self, index: usize, value: Self::Value) {
62        self[index] = value;
63    }
64
65    #[inline]
66    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
67        // SAFETY: index is within bounds
68        let val_mut = unsafe { self.get_unchecked_mut(index) };
69        *val_mut = value;
70    }
71
72    #[inline]
73    fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
74        core::mem::replace(&mut self[index], value)
75    }
76
77    #[inline]
78    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
79        // SAFETY: index is within bounds
80        let val_mut = unsafe { self.get_unchecked_mut(index) };
81        core::mem::replace(val_mut, value)
82    }
83
84    type ChunksMut<'a>
85        = core::slice::ChunksMut<'a, T>
86    where
87        Self: 'a;
88
89    type ChunksMutError = core::convert::Infallible;
90
91    #[inline]
92    fn try_chunks_mut(
93        &mut self,
94        chunk_size: usize,
95    ) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
96        Ok(self.chunks_mut(chunk_size))
97    }
98}
99
100impl<'a, T: Clone> SliceByValueSubsliceGat<'a> for [T] {
101    type Subslice = &'a [T];
102}
103
104impl<'a, T: Clone> SliceByValueSubsliceGatMut<'a> for [T] {
105    type SubsliceMut = &'a mut [T];
106}
107
108macro_rules! impl_range_slices {
109    ($range:ty) => {
110        impl<T: Clone> SliceByValueSubsliceRange<$range> for [T] {
111            #[inline]
112            fn get_subslice(&self, index: $range) -> Option<Subslice<'_, Self>> {
113                (*self).get(index)
114            }
115
116            #[inline]
117            fn index_subslice(&self, index: $range) -> Subslice<'_, Self> {
118                &self[index]
119            }
120
121            #[inline]
122            unsafe fn get_subslice_unchecked(&self, index: $range) -> Subslice<'_, Self> {
123                unsafe { (*self).get_unchecked(index) }
124            }
125        }
126
127        impl<T: Clone> SliceByValueSubsliceRangeMut<$range> for [T] {
128            #[inline]
129            fn get_subslice_mut(&mut self, index: $range) -> Option<SubsliceMut<'_, Self>> {
130                (*self).get_mut(index)
131            }
132
133            #[inline]
134            fn index_subslice_mut(&mut self, index: $range) -> SubsliceMut<'_, Self> {
135                &mut self[index]
136            }
137
138            #[inline]
139            unsafe fn get_subslice_unchecked_mut(
140                &mut self,
141                index: $range,
142            ) -> SubsliceMut<'_, Self> {
143                unsafe { (*self).get_unchecked_mut(index) }
144            }
145        }
146    };
147}
148
149impl_range_slices!(RangeFull);
150impl_range_slices!(RangeFrom<usize>);
151impl_range_slices!(RangeTo<usize>);
152impl_range_slices!(Range<usize>);
153impl_range_slices!(RangeInclusive<usize>);
154impl_range_slices!(RangeToInclusive<usize>);
155
156impl<'a, T: Clone> IterateByValueGat<'a> for [T] {
157    type Item = T;
158    type Iter = Cloned<core::slice::Iter<'a, T>>;
159}
160
161impl<T: Clone> IterateByValue for [T] {
162    fn iter_value(&self) -> Iter<'_, Self> {
163        self.iter().cloned()
164    }
165}
166
167impl<'a, T: Clone> IterateByValueFromGat<'a> for [T] {
168    type Item = T;
169    type IterFrom = Cloned<Skip<core::slice::Iter<'a, T>>>;
170}
171
172impl<T: Clone> IterateByValueFrom for [T] {
173    fn iter_value_from(&self, from: usize) -> IterFrom<'_, Self> {
174        let len = self.len();
175        assert!(
176            from <= len,
177            "index out of bounds: the len is {len} but the starting index is {from}"
178        );
179        self.iter().skip(from).cloned()
180    }
181}