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