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