devela/data/list/array/d1/methods/
bare.rs

1// devela::data::list::array::d1::methods::bare
2//
3//! 1-dimensional array *Bare* methods.
4//
5// TOC
6// - constructors
7// - methods
8// - indexing methods (panicking)
9// - Option<T> methods
10
11use crate::{array_init, iif, Array, Bare, BareBox, Slice};
12
13/// # *Bare* constructors
14impl<T, const CAP: usize> Array<T, CAP, Bare> {
15    /// Returns a new [`Array`] allocated in the stack,
16    /// from the given primitive `array` in compile-time.
17    pub const fn new_bare(array: [T; CAP]) -> Self {
18        Self { data: BareBox::new(array) }
19    }
20
21    /// Returns an array, allocated in the stack, filled with `element`, cloned.
22    ///
23    /// # Example
24    /// ```
25    /// # use devela::data::Array;
26    /// let a = Array::<_, 16>::with_cloned(0);
27    /// ```
28    pub fn with_cloned(element: T) -> Self
29    where
30        T: Clone,
31    {
32        let data = BareBox::new(array_init!(clone [T; CAP], "safe_data", "unsafe_array", element));
33        Self { data }
34    }
35
36    /// Returns an array, allocated in the stack, filled with `element`, copied, in compile-time.
37    ///
38    /// # Example
39    /// ```
40    /// # use devela::data::Array;
41    /// const A: Array<i32, 16> = Array::with_copied(0);
42    /// ```
43    pub const fn with_copied(element: T) -> Self
44    where
45        T: Copy,
46    {
47        let data = BareBox::new([element; CAP]);
48        Self { data }
49    }
50}
51
52/// # *Bare* methods
53impl<T, const CAP: usize> Array<T, CAP, Bare> {
54    /// Returns a slice containing the entire array in compile time.
55    ///
56    /// It allows to sidestep `Deref` coercion for indexing purposes.
57    #[must_use]
58    pub const fn as_bare_slice(&self) -> &[T] {
59        self.data.as_ref() // const method on BareBox
60    }
61
62    /// Returns a slice containing the entire array in compile time.
63    ///
64    /// It allows to sidestep `Deref` coercion for indexing purposes.
65    /// It's composable with [`Slice`] methods for *const* operations.
66    #[must_use]
67    pub const fn as_bare_mut_slice(&mut self) -> &mut [T] {
68        self.data.as_mut() // const method on BareBox
69    }
70
71    /// Returns the inner [`BareBox`]ed primitive array.
72    #[must_use]
73    pub fn into_array(self) -> [T; CAP] {
74        self.data.into_inner()
75    }
76
77    /// Returns the inner [`BareBox`]ed primitive array in compile-time.
78    #[must_use]
79    pub const fn into_array_copy(self) -> [T; CAP]
80    where
81        T: Copy,
82    {
83        self.data.into_inner_copy()
84    }
85}
86
87/// # *Bare* indexing methods (panicking)
88impl<T, const CAP: usize> Array<T, CAP, Bare> {
89    /// Returns a shared reference to the element at the given `index` in compile-time.
90    ///
91    /// # Panics
92    /// Panics if the `index` is out of bounds in a non-const context.
93    ///
94    /// # Example
95    /// ```
96    /// # use devela::Array;
97    /// const A: Array<i32, 4> = Array::new_bare([10, 20, 30, 40]);
98    /// const VALUE: i32 = *A.get(2);
99    /// assert_eq!(VALUE, 30);
100    /// ```
101    #[must_use]
102    pub const fn get(&self, index: usize) -> &T {
103        assert!(index < CAP, "Index out of bounds in const context");
104        &self.as_bare_slice()[index]
105    }
106
107    /// Returns an exclusive reference to the element at the given `index` in compile-time.
108    ///
109    /// # Panics
110    /// Panics if the `index` is out of bounds in a non-const context.
111    ///
112    /// # Example
113    /// ```
114    /// # use devela::Array;
115    /// const fn modify_array() -> Array<i32, 4> {
116    ///     let mut a = Array::new_bare([10, 20, 30, 40]);
117    ///     *a.get_mut(2) = 50;
118    ///     a
119    /// }
120    /// const A: Array<i32, 4> = modify_array();
121    /// assert_eq!(A.get_mut(2), &50);
122    /// ```
123    #[must_use]
124    pub const fn get_mut(&mut self, index: usize) -> &mut T {
125        assert!(index < CAP, "Index out of bounds in const context");
126        &mut self.as_bare_mut_slice()[index]
127    }
128
129    // MAYBE compose, not repeat
130
131    /// Returns a subslice up to the given `end` index.
132    pub const fn range_to(&self, end: usize) -> &[T] {
133        Slice::range_to(self.as_bare_slice(), end)
134    }
135    /// Returns an exclusive subslice up to the given `end` index.
136    pub const fn range_to_mut(&mut self, end: usize) -> &mut [T] {
137        Slice::range_to_mut(self.as_bare_mut_slice(), end)
138    }
139}
140
141/// # *Bare* `Option<T>` methods
142impl<T, const CAP: usize> Array<Option<T>, CAP, Bare> {
143    /// Checks if all elements are `None`, returning early if a `Some` is found.
144    pub const fn is_bare_empty(&self) -> bool {
145        let mut n = 0;
146        while n <= CAP {
147            iif![self.as_bare_slice()[n].is_some(); return false];
148            n += 1;
149        }
150        true
151    }
152
153    /// Checks if all elements are `Some`, returning early if a `None` is found.
154    pub const fn is_bare_full(&self) -> bool {
155        let mut n = 0;
156        while n <= CAP {
157            iif![self.as_bare_slice()[n].is_none(); return false];
158            n += 1;
159        }
160        true
161    }
162}