Skip to main content

value_traits/impls/
vectors.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 [`Vec`] and [`VecDeque`] of
10//! [cloneable] types.
11//!
12//! The [`Vec`] implementations are available only if the `alloc` feature is
13//! enabled, while the [`VecDeque`] implementations are available only if the
14//! `std` feature is enabled.
15//!
16//! [`VecDeque`]: std::collections::VecDeque
17//! [cloneable]: Clone
18
19#![cfg(feature = "alloc")]
20
21#[cfg(all(feature = "alloc", not(feature = "std")))]
22use alloc::vec::Vec;
23
24use core::{
25    iter::{Cloned, Skip},
26    ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
27};
28
29use crate::{
30    iter::{
31        Iter, IterFrom, IterateByValue, IterateByValueFrom, IterateByValueFromGat,
32        IterateByValueGat,
33    },
34    slices::{
35        SliceByValue, SliceByValueMut, SliceByValueSubsliceGat, SliceByValueSubsliceGatMut,
36        SliceByValueSubsliceRange, SliceByValueSubsliceRangeMut, Subslice, SubsliceMut,
37    },
38};
39
40impl<T: Clone> SliceByValue for Vec<T> {
41    type Value = T;
42
43    #[inline]
44    fn len(&self) -> usize {
45        <[T]>::len(self)
46    }
47    #[inline]
48    fn get_value(&self, index: usize) -> Option<Self::Value> {
49        (*self).get(index).cloned()
50    }
51
52    #[inline]
53    fn index_value(&self, index: usize) -> Self::Value {
54        self[index].clone()
55    }
56
57    #[inline]
58    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
59        // SAFETY: index is within bounds
60        let val_ref = unsafe { (*self).get_unchecked(index) };
61        val_ref.clone()
62    }
63}
64
65impl<T: Clone> SliceByValueMut for Vec<T> {
66    #[inline]
67    fn set_value(&mut self, index: usize, value: Self::Value) {
68        self[index] = value;
69    }
70
71    #[inline]
72    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
73        unsafe {
74            // SAFETY: index is within bounds
75            let val_mut = { self.get_unchecked_mut(index) };
76            *val_mut = value;
77        }
78    }
79
80    #[inline]
81    fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
82        core::mem::replace(&mut self[index], value)
83    }
84
85    #[inline]
86    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
87        // SAFETY: index is within bounds
88        let val_mut = unsafe { self.get_unchecked_mut(index) };
89        core::mem::replace(val_mut, value)
90    }
91
92    type ChunksMut<'a>
93        = core::slice::ChunksMut<'a, T>
94    where
95        Self: 'a;
96
97    type ChunksMutError = core::convert::Infallible;
98
99    #[inline]
100    fn try_chunks_mut(
101        &mut self,
102        chunk_size: usize,
103    ) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
104        Ok(self.chunks_mut(chunk_size))
105    }
106}
107
108impl<'a, T: Clone> SliceByValueSubsliceGat<'a> for Vec<T> {
109    type Subslice = &'a [T];
110}
111impl<'a, T: Clone> SliceByValueSubsliceGatMut<'a> for Vec<T> {
112    type SubsliceMut = &'a mut [T];
113}
114
115macro_rules! impl_range_vecs {
116    ($range:ty) => {
117        impl<T: Clone> SliceByValueSubsliceRange<$range> for Vec<T> {
118            #[inline]
119            fn get_subslice(&self, index: $range) -> Option<Subslice<'_, Self>> {
120                (*self).get(index)
121            }
122
123            #[inline]
124            fn index_subslice(&self, index: $range) -> Subslice<'_, Self> {
125                &self[index]
126            }
127
128            #[inline]
129            unsafe fn get_subslice_unchecked(&self, index: $range) -> Subslice<'_, Self> {
130                unsafe { (*self).get_unchecked(index) }
131            }
132        }
133        impl<T: Clone> SliceByValueSubsliceRangeMut<$range> for Vec<T> {
134            #[inline]
135            fn get_subslice_mut(&mut self, index: $range) -> Option<SubsliceMut<'_, Self>> {
136                (*self).get_mut(index)
137            }
138
139            #[inline]
140            fn index_subslice_mut(&mut self, index: $range) -> SubsliceMut<'_, Self> {
141                &mut self[index]
142            }
143
144            #[inline]
145            unsafe fn get_subslice_unchecked_mut(
146                &mut self,
147                index: $range,
148            ) -> SubsliceMut<'_, Self> {
149                unsafe { (*self).get_unchecked_mut(index) }
150            }
151        }
152    };
153}
154
155impl_range_vecs!(RangeFull);
156impl_range_vecs!(RangeFrom<usize>);
157impl_range_vecs!(RangeTo<usize>);
158impl_range_vecs!(Range<usize>);
159impl_range_vecs!(RangeInclusive<usize>);
160impl_range_vecs!(RangeToInclusive<usize>);
161
162impl<'a, T: Clone> IterateByValueGat<'a> for Vec<T> {
163    type Item = T;
164    type Iter = Cloned<core::slice::Iter<'a, T>>;
165}
166
167impl<T: Clone> IterateByValue for Vec<T> {
168    fn iter_value(&self) -> Iter<'_, Self> {
169        self.iter().cloned()
170    }
171}
172
173impl<'a, T: Clone> IterateByValueFromGat<'a> for Vec<T> {
174    type Item = T;
175    type IterFrom = Cloned<Skip<core::slice::Iter<'a, T>>>;
176}
177
178impl<T: Clone> IterateByValueFrom for Vec<T> {
179    fn iter_value_from(&self, from: usize) -> IterFrom<'_, Self> {
180        let len = self.len();
181        assert!(
182            from <= len,
183            "index out of bounds: the len is {len} but the starting index is {from}"
184        );
185        self.iter().skip(from).cloned()
186    }
187}
188
189#[cfg(feature = "std")]
190mod vec_deque {
191    use super::*;
192    use std::collections::VecDeque;
193
194    impl<T: Clone> SliceByValue for VecDeque<T> {
195        type Value = T;
196
197        #[inline]
198        fn len(&self) -> usize {
199            self.len()
200        }
201        #[inline]
202        fn get_value(&self, index: usize) -> Option<Self::Value> {
203            (*self).get(index).cloned()
204        }
205
206        #[inline]
207        fn index_value(&self, index: usize) -> Self::Value {
208            self[index].clone()
209        }
210
211        #[inline]
212        unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
213            // SAFETY: index is within bounds
214            let val_ref = unsafe { (*self).get(index).unwrap_unchecked() };
215            val_ref.clone()
216        }
217    }
218
219    impl<T: Clone> SliceByValueMut for VecDeque<T> {
220        #[inline]
221        fn set_value(&mut self, index: usize, value: Self::Value) {
222            self[index] = value;
223        }
224
225        #[inline]
226        unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
227            unsafe {
228                // SAFETY: index is within bounds
229                let val_mut = { self.get_mut(index).unwrap_unchecked() };
230                *val_mut = value;
231            }
232        }
233
234        #[inline]
235        fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
236            core::mem::replace(&mut self[index], value)
237        }
238
239        #[inline]
240        unsafe fn replace_value_unchecked(
241            &mut self,
242            index: usize,
243            value: Self::Value,
244        ) -> Self::Value {
245            // SAFETY: index is within bounds
246            let val_mut = unsafe { self.get_mut(index).unwrap_unchecked() };
247            core::mem::replace(val_mut, value)
248        }
249
250        type ChunksMut<'a>
251            = core::slice::ChunksMut<'a, T>
252        where
253            Self: 'a;
254
255        type ChunksMutError = core::convert::Infallible;
256
257        /// This implementation always succeeds.
258        ///
259        /// Note that it calls [`VecDeque::make_contiguous`], which
260        /// rearranges the internal storage of the deque in *O*(*n*) time.
261        #[inline]
262        fn try_chunks_mut(
263            &mut self,
264            chunk_size: usize,
265        ) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
266            Ok(self.make_contiguous().chunks_mut(chunk_size))
267        }
268    }
269
270    impl<'a, T: Clone> IterateByValueGat<'a> for VecDeque<T> {
271        type Item = T;
272        type Iter = Cloned<std::collections::vec_deque::Iter<'a, T>>;
273    }
274
275    impl<T: Clone> IterateByValue for VecDeque<T> {
276        fn iter_value(&self) -> Iter<'_, Self> {
277            self.iter().cloned()
278        }
279    }
280
281    impl<'a, T: Clone> IterateByValueFromGat<'a> for VecDeque<T> {
282        type Item = T;
283        type IterFrom = Cloned<Skip<std::collections::vec_deque::Iter<'a, T>>>;
284    }
285
286    impl<T: Clone> IterateByValueFrom for VecDeque<T> {
287        fn iter_value_from(&self, from: usize) -> IterFrom<'_, Self> {
288            let len = self.len();
289            assert!(
290                from <= len,
291                "index out of bounds: the len is {len} but the starting index is {from}"
292            );
293            self.iter().skip(from).cloned()
294        }
295    }
296}