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