Skip to main content

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

1// devela::data::layout::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, Bare, BareBox, init_array, is};
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    /// # Examples
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(init_array!(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    /// # Examples
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`][crate::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    /// # Examples
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    /// # Examples
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
130/// # *Bare* `Option<T>` methods
131impl<T, const CAP: usize> Array<Option<T>, CAP, Bare> {
132    /// Checks if all elements are `None`, returning early if a `Some` is found.
133    pub const fn is_bare_empty(&self) -> bool {
134        let mut n = 0;
135        while n <= CAP {
136            is![self.as_bare_slice()[n].is_some(), return false];
137            n += 1;
138        }
139        true
140    }
141
142    /// Checks if all elements are `Some`, returning early if a `None` is found.
143    pub const fn is_bare_full(&self) -> bool {
144        let mut n = 0;
145        while n <= CAP {
146            is![self.as_bare_slice()[n].is_none(), return false];
147            n += 1;
148        }
149        true
150    }
151}