Skip to main content

value_traits/impls/
arrays.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 arrays of [cloneable] types.
10//!
11//! [cloneable]: Clone
12
13use core::{
14    iter::{Cloned, Skip},
15    ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
16};
17
18use crate::{
19    iter::{
20        Iter, IterFrom, IterateByValue, IterateByValueFrom, IterateByValueFromGat,
21        IterateByValueGat,
22    },
23    slices::{
24        SliceByValue, SliceByValueMut, SliceByValueSubsliceGat, SliceByValueSubsliceGatMut,
25        SliceByValueSubsliceRange, SliceByValueSubsliceRangeMut, Subslice, SubsliceMut,
26    },
27};
28
29impl<T: Clone, const N: usize> SliceByValue for [T; N] {
30    type Value = T;
31
32    #[inline(always)]
33    fn len(&self) -> usize {
34        N
35    }
36    #[inline]
37    fn get_value(&self, index: usize) -> Option<Self::Value> {
38        (*self).get(index).cloned()
39    }
40
41    #[inline]
42    fn index_value(&self, index: usize) -> Self::Value {
43        self[index].clone()
44    }
45
46    #[inline]
47    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
48        // SAFETY: index is within bounds
49        let val_ref = unsafe { (*self).get_unchecked(index) };
50        val_ref.clone()
51    }
52}
53
54impl<T: Clone, const N: usize> SliceByValueMut for [T; N] {
55    #[inline]
56    fn set_value(&mut self, index: usize, value: Self::Value) {
57        self[index] = value;
58    }
59
60    #[inline]
61    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
62        // SAFETY: index is within bounds
63        let val_mut = unsafe { self.get_unchecked_mut(index) };
64        *val_mut = value;
65    }
66
67    #[inline]
68    fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
69        core::mem::replace(&mut self[index], value)
70    }
71
72    #[inline]
73    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
74        // SAFETY: index is within bounds
75        let val_mut = unsafe { self.get_unchecked_mut(index) };
76        core::mem::replace(val_mut, value)
77    }
78
79    type ChunksMut<'a>
80        = core::slice::ChunksMut<'a, T>
81    where
82        Self: 'a;
83
84    type ChunksMutError = core::convert::Infallible;
85
86    #[inline]
87    fn try_chunks_mut(
88        &mut self,
89        chunk_size: usize,
90    ) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
91        Ok(self.chunks_mut(chunk_size))
92    }
93}
94
95impl<'a, T: Clone, const N: usize> SliceByValueSubsliceGat<'a> for [T; N] {
96    type Subslice = &'a [T];
97}
98
99impl<'a, T: Clone, const N: usize> SliceByValueSubsliceGatMut<'a> for [T; N] {
100    type SubsliceMut = &'a mut [T];
101}
102
103macro_rules! impl_range_arrays {
104    ($range:ty) => {
105        impl<T: Clone, const N: usize> SliceByValueSubsliceRange<$range> for [T; N] {
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, const N: usize> SliceByValueSubsliceRangeMut<$range> for [T; N] {
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_arrays!(RangeFull);
145impl_range_arrays!(RangeFrom<usize>);
146impl_range_arrays!(RangeTo<usize>);
147impl_range_arrays!(Range<usize>);
148impl_range_arrays!(RangeInclusive<usize>);
149impl_range_arrays!(RangeToInclusive<usize>);
150
151impl<'a, T: Clone, const N: usize> IterateByValueGat<'a> for [T; N] {
152    type Item = T;
153    type Iter = Cloned<core::slice::Iter<'a, T>>;
154}
155
156impl<T: Clone, const N: usize> IterateByValue for [T; N] {
157    fn iter_value(&self) -> Iter<'_, Self> {
158        self.iter().cloned()
159    }
160}
161
162impl<'a, T: Clone, const N: usize> IterateByValueFromGat<'a> for [T; N] {
163    type Item = T;
164    type IterFrom = Cloned<Skip<core::slice::Iter<'a, T>>>;
165}
166
167impl<T: Clone, const N: usize> IterateByValueFrom for [T; N] {
168    fn iter_value_from(&self, from: usize) -> IterFrom<'_, Self> {
169        assert!(
170            from <= N,
171            "index out of bounds: the len is {N} but the starting index is {from}"
172        );
173        self.iter().skip(from).cloned()
174    }
175}