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
9use core::{
10    iter::{Cloned, Skip},
11    ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
12};
13
14use crate::{
15    iter::{IterableByValue, IterableByValueFrom},
16    slices::{
17        SliceByValue, SliceByValueGet, SliceByValueRepl, SliceByValueSet, SliceByValueSubsliceGat,
18        SliceByValueSubsliceGatMut, SliceByValueSubsliceRange, SliceByValueSubsliceRangeMut,
19        Subslice, SubsliceMut,
20    },
21};
22
23impl<T, const N: usize> SliceByValue for [T; N] {
24    type Value = T;
25    #[inline(always)]
26    fn len(&self) -> usize {
27        N
28    }
29}
30
31impl<T: Clone, const N: usize> SliceByValueGet for [T; N] {
32    #[inline]
33    fn get_value(&self, index: usize) -> Option<Self::Value> {
34        // slice.get returns Option<&T>, .copied() converts to Option<T>
35        (*self).get(index).cloned()
36    }
37
38    #[inline]
39    fn index_value(&self, index: usize) -> Self::Value {
40        // Standard indexing panics on out-of-bounds.
41        // It returns &T, which we copy to return T.
42        self[index].clone()
43    }
44
45    #[inline]
46    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
47        // Safety: The caller must ensure that `*self` (the index) is in bounds.
48        // slice.get_unchecked returns &T, which we dereference and copy.
49        unsafe { (*self).get_unchecked(index).clone() }
50    }
51}
52
53impl<T: Clone, const N: usize> SliceByValueSet for [T; N] {
54    #[inline]
55    fn set_value(&mut self, index: usize, value: Self::Value) {
56        // Standard indexing panics on out-of-bounds.
57        self[index] = value;
58    }
59
60    #[inline]
61    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
62        // Safety: The caller must ensure that `*self` (the index) is in bounds.
63        unsafe {
64            let elem = self.get_unchecked_mut(index);
65            *elem = value;
66        }
67    }
68}
69
70impl<T: Clone, const N: usize> SliceByValueRepl for [T; N] {
71    #[inline]
72    fn replace_value(&mut self, index: usize, value: Self::Value) -> Self::Value {
73        // Standard indexing panics on out-of-bounds.
74        // We get a mutable reference `&mut T`.
75        // mem::replace swaps the value at the location with the new `value`
76        // and returns the old value.
77        core::mem::replace(&mut self[index], value)
78    }
79
80    #[inline]
81    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
82        // Safety: The caller must ensure that `*self` (the index) is in bounds.
83        unsafe {
84            let elem = self.get_unchecked_mut(index);
85            core::mem::replace(elem, value)
86        }
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 Subslice = &'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<T: Clone, const N: usize> IterableByValueFrom for [T; N] {
147    type IterFrom<'a>
148        = Cloned<Skip<core::slice::Iter<'a, T>>>
149    where
150        T: 'a;
151
152    fn iter_value_from(&self, from: usize) -> Self::IterFrom<'_> {
153        self.iter().skip(from).cloned()
154    }
155}
156
157impl<T: Clone, const N: usize> IterableByValue for [T; N] {
158    type Item = T;
159    type Iter<'a>
160        = Cloned<core::slice::Iter<'a, T>>
161    where
162        T: 'a;
163
164    fn iter_value(&self) -> Self::Iter<'_> {
165        self.iter().cloned()
166    }
167}