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