devela/data/list/array/d1/
impl_traits.rs

1// devela::data::list:array::d1::impl_traits
2//
3//! 1-dimensional array trait impls
4//
5// TOC
6// - utility traits
7// - iterator related
8// - bitwise ops
9
10use crate::{
11    array_init, Array, AsMut, AsRef, Bare, BareBox, BitAnd, BitAndAssign, BitOr, BitOrAssign,
12    BitXor, BitXorAssign, Borrow, BorrowMut, ConstDefault, Debug, Deref, DerefMut, FmtResult,
13    Formatter, Hash, Hasher, Not, Ordering, Storage,
14};
15
16#[cfg(feature = "alloc")]
17use crate::{Box, Boxed};
18
19/* utility traits */
20
21// Deref
22impl<T, const CAP: usize, S: Storage> Deref for Array<T, CAP, S> {
23    type Target = [T];
24
25    fn deref(&self) -> &Self::Target {
26        self.data.deref()
27    }
28}
29// DerefMut
30impl<T, const CAP: usize, S: Storage> DerefMut for Array<T, CAP, S> {
31    fn deref_mut(&mut self) -> &mut Self::Target {
32        self.data.deref_mut()
33    }
34}
35// AsRef
36impl<T, const CAP: usize, S: Storage> AsRef<[T; CAP]> for Array<T, CAP, S> {
37    fn as_ref(&self) -> &[T; CAP] {
38        &self.data
39    }
40}
41// AsMut
42impl<T, const CAP: usize, S: Storage> AsMut<[T; CAP]> for Array<T, CAP, S> {
43    fn as_mut(&mut self) -> &mut [T; CAP] {
44        &mut self.data
45    }
46}
47// Borrow
48impl<T, const CAP: usize, S: Storage> Borrow<[T; CAP]> for Array<T, CAP, S> {
49    fn borrow(&self) -> &[T; CAP] {
50        &self.data
51    }
52}
53// BorrowMut
54impl<T, const CAP: usize, S: Storage> BorrowMut<[T; CAP]> for Array<T, CAP, S> {
55    fn borrow_mut(&mut self) -> &mut [T; CAP] {
56        &mut self.data
57    }
58}
59
60// T: Clone
61impl<T: Clone, const CAP: usize, S: Storage> Clone for Array<T, CAP, S>
62where
63    S::Stored<[T; CAP]>: Clone,
64{
65    fn clone(&self) -> Self {
66        Self { data: self.data.clone() }
67    }
68}
69
70// T: Copy
71impl<T: Copy, const CAP: usize, S: Storage> Copy for Array<T, CAP, S> where S::Stored<[T; CAP]>: Copy
72{}
73
74// T: Debug
75impl<T: Debug, const CAP: usize, S: Storage> Debug for Array<T, CAP, S>
76where
77    S::Stored<[T; CAP]>: Debug,
78{
79    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult<()> {
80        let mut debug = f.debug_struct("Array");
81        debug.field("T", &core::any::type_name::<T>()).field("S", &S::name()).field("CAP", &CAP);
82
83        const MAX: usize = 16;
84        if CAP <= MAX {
85            debug.field("data", &self.data);
86        } else {
87            let first = &self.data[..MAX / 2];
88            let last = &self.data[CAP - MAX / 2..];
89            debug.field("array", &(&first, "...", &last));
90        }
91        debug.finish()
92    }
93}
94// T: PartialEq
95impl<T: PartialEq, const CAP: usize, S: Storage> PartialEq for Array<T, CAP, S>
96where
97    S::Stored<[T; CAP]>: PartialEq,
98{
99    fn eq(&self, other: &Self) -> bool {
100        self.data == other.data && self.capacity() == other.capacity()
101    }
102}
103// T: Eq
104impl<T: Eq, const CAP: usize, S: Storage> Eq for Array<T, CAP, S> where S::Stored<[T; CAP]>: Eq {}
105// T: PartialOrd
106impl<T: PartialOrd, const CAP: usize, S: Storage> PartialOrd for Array<T, CAP, S>
107where
108    S::Stored<[T; CAP]>: PartialOrd,
109{
110    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
111        self.data.partial_cmp(&other.data)
112    }
113}
114// T: Ord
115impl<T: Ord, const CAP: usize, S: Storage> Ord for Array<T, CAP, S>
116where
117    S::Stored<[T; CAP]>: Ord,
118{
119    fn cmp(&self, other: &Self) -> Ordering {
120        self.data.cmp(&other.data)
121    }
122}
123// T: Hash
124impl<T: Hash, const CAP: usize, S: Storage> Hash for Array<T, CAP, S>
125where
126    S::Stored<[T; CAP]>: Hash,
127{
128    fn hash<H: Hasher>(&self, state: &mut H) {
129        self.data.hash(state);
130    }
131}
132
133// T: Default, S: Bare
134impl<T: Default, const CAP: usize> Default for Array<T, CAP, Bare> {
135    /// Returns an array, allocated in the stack,
136    /// using the default value to fill the data.
137    fn default() -> Self {
138        let data = BareBox::new(array_init!(default [T; CAP], "safe_data", "unsafe_array"));
139        Array { data }
140    }
141}
142// T: ConstDefault, S: Bare
143impl<T: ConstDefault, const CAP: usize> ConstDefault for Array<T, CAP, Bare> {
144    /// Returns an array, allocated in the stack,
145    /// using the default value to fill the data.
146    const DEFAULT: Self = { Array { data: BareBox::new([T::DEFAULT; CAP]) } };
147}
148
149// T: Default, S: Boxed
150#[cfg(feature = "alloc")]
151#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alloc")))]
152impl<T: Default, const CAP: usize> Default for Array<T, CAP, Boxed> {
153    /// Returns an array, allocated in the heap,
154    /// using the default value to fill the data.
155    ///
156    /// # Examples
157    /// ```
158    /// # use devela::{Array, Boxed};
159    /// let mut s = Array::<i32, 100, Boxed>::default();
160    /// ```
161    fn default() -> Self {
162        let data = array_init!(default_heap [T; CAP], "safe_data", "unsafe_array");
163        Array { data }
164    }
165}
166
167impl<T, const CAP: usize> From<Array<T, CAP, Bare>> for [T; CAP] {
168    fn from(array: Array<T, CAP, Bare>) -> [T; CAP] {
169        array.data.0
170    }
171}
172#[cfg(feature = "alloc")]
173#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alloc")))]
174impl<T, const CAP: usize> From<Array<T, CAP, Boxed>> for Box<[T; CAP]> {
175    fn from(array: Array<T, CAP, Boxed>) -> Box<[T; CAP]> {
176        array.data
177    }
178}
179
180/* iterator related */
181
182impl<T: Default, I, const CAP: usize> From<I> for Array<T, CAP, Bare>
183where
184    I: IntoIterator<Item = T>,
185{
186    /// Returns a array filled with an iterator, in the stack.
187    ///
188    /// If the `iterator` length is less than the array capacity `CAP`,
189    /// the missing elements will be the default value of `T`.
190    ///
191    /// # Examples
192    /// ```
193    /// # use devela::data::Array;
194    /// let s: Array<_, 4> = [1, 2, 3].into();
195    /// assert_eq![s.as_slice(), &[1, 2, 3, 0]];
196    /// ```
197    fn from(iterator: I) -> Array<T, CAP, Bare> {
198        let data = BareBox::new(array_init!(iter [T; CAP], "safe_data", "unsafe_array", iterator));
199        Array { data }
200    }
201}
202
203#[cfg(feature = "alloc")]
204#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alloc")))]
205impl<T: Default, I, const CAP: usize> From<I> for Array<T, CAP, Boxed>
206where
207    I: IntoIterator<Item = T>,
208{
209    /// Returns a array filled with an iterator, in the heap.
210    ///
211    /// # Examples
212    /// ```
213    /// # use devela::{Array, Boxed};
214    /// let s: Array<_, 4, Boxed> = [1, 2, 3].into();
215    ///
216    /// assert_eq![s.as_slice(), &[1, 2, 3, 0]];
217    /// ```
218    fn from(iterator: I) -> Array<T, CAP, Boxed> {
219        let data = array_init!(iter_heap [T; CAP], "safe_data", "unsafe_array", iterator);
220        Array { data }
221    }
222}
223
224/* impl bitwise ops */
225
226impl<T, const CAP: usize, S: Storage> BitAnd for Array<T, CAP, S>
227where
228    S::Stored<[T; CAP]>: Copy,
229    T: BitAnd<Output = T> + Copy,
230{
231    type Output = Self;
232
233    fn bitand(self, rhs: Self) -> Self::Output {
234        let mut result = self;
235        for i in 0..CAP {
236            result.data[i] = result.data[i] & rhs.data[i];
237        }
238        result
239    }
240}
241impl<T, const CAP: usize, S: Storage> BitOr for Array<T, CAP, S>
242where
243    S::Stored<[T; CAP]>: Copy,
244    T: BitOr<Output = T> + Copy,
245{
246    type Output = Self;
247
248    fn bitor(self, rhs: Self) -> Self::Output {
249        let mut result = self;
250        for i in 0..CAP {
251            result.data[i] = result.data[i] | rhs.data[i];
252        }
253        result
254    }
255}
256impl<T, const CAP: usize, S: Storage> BitXor for Array<T, CAP, S>
257where
258    S::Stored<[T; CAP]>: Copy,
259    T: BitXor<Output = T> + Copy,
260{
261    type Output = Self;
262
263    fn bitxor(self, rhs: Self) -> Self::Output {
264        let mut result = self;
265        for i in 0..CAP {
266            result.data[i] = result.data[i] ^ rhs.data[i];
267        }
268        result
269    }
270}
271
272impl<T, const CAP: usize, S: Storage> BitAndAssign for Array<T, CAP, S>
273where
274    S::Stored<[T; CAP]>: Copy,
275    T: BitAndAssign + Copy,
276{
277    fn bitand_assign(&mut self, rhs: Self) {
278        for i in 0..CAP {
279            self.data[i] &= rhs.data[i];
280        }
281    }
282}
283
284impl<T, const CAP: usize, S: Storage> BitOrAssign for Array<T, CAP, S>
285where
286    S::Stored<[T; CAP]>: Copy,
287    T: BitOrAssign + Copy,
288{
289    fn bitor_assign(&mut self, rhs: Self) {
290        for i in 0..CAP {
291            self.data[i] |= rhs.data[i];
292        }
293    }
294}
295
296impl<T, const CAP: usize, S: Storage> BitXorAssign for Array<T, CAP, S>
297where
298    S::Stored<[T; CAP]>: Copy,
299    T: BitXorAssign + Copy,
300{
301    fn bitxor_assign(&mut self, rhs: Self) {
302        for i in 0..CAP {
303            self.data[i] ^= rhs.data[i];
304        }
305    }
306}
307
308impl<T, const CAP: usize, S: Storage> Not for Array<T, CAP, S>
309where
310    S::Stored<[T; CAP]>: Clone,
311    T: Not<Output = T> + Copy,
312{
313    type Output = Self;
314
315    fn not(self) -> Self::Output {
316        let mut result = self;
317        for i in 0..CAP {
318            result.data[i] = !result.data[i];
319        }
320        result
321    }
322}