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