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