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}