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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// devela::data::collections::array::d1::methods::bare
//
//! 1-dimensional array *Bare* methods.
//
// TOC
// - constructors
// - methods
// - indexing methods (panicking)
// - Option<T> methods

use crate::{array_init, iif, Array, Bare, BareBox};

/// # *Bare* constructors
impl<T, const CAP: usize> Array<T, CAP, Bare> {
    /// Returns a new [`Array`] allocated in the stack,
    /// from the given primitive `array` in compile-time.
    pub const fn new_bare(array: [T; CAP]) -> Self {
        Self { data: BareBox::new(array) }
    }

    /// Returns an array, allocated in the stack, filled with `element`, cloned.
    ///
    /// # Example
    /// ```
    /// # use devela::data::Array;
    /// let a = Array::<_, 16>::with_cloned(0);
    /// ```
    pub fn with_cloned(element: T) -> Self
    where
        T: Clone,
    {
        let data = BareBox::new(array_init!(clone [T; CAP], "safe_data", "unsafe_array", element));
        Self { data }
    }

    /// Returns an array, allocated in the stack, filled with `element`, copied, in compile-time.
    ///
    /// # Example
    /// ```
    /// # use devela::data::Array;
    /// const A: Array<i32, 16> = Array::with_copied(0);
    /// ```
    pub const fn with_copied(element: T) -> Self
    where
        T: Copy,
    {
        let data = BareBox::new([element; CAP]);
        Self { data }
    }
}

/// # *Bare* methods
impl<T, const CAP: usize> Array<T, CAP, Bare> {
    /// Returns a slice containing the entire array in compile time.
    ///
    /// It allows to sidestep `Deref` coercion for indexing purposes.
    #[must_use]
    pub const fn as_bare_slice(&self) -> &[T] {
        self.data.as_ref() // const method on BareBox
    }

    /// Returns a slice containing the entire array in compile time.
    ///
    /// It allows to sidestep `Deref` coercion for indexing purposes.
    #[must_use]
    pub const fn as_bare_mut_slice(&mut self) -> &mut [T] {
        self.data.as_mut() // const method on BareBox
    }

    /// Returns the inner [`BareBox`]ed primitive array.
    #[must_use]
    pub fn into_array(self) -> [T; CAP] {
        self.data.into_inner()
    }

    /// Returns the inner [`BareBox`]ed primitive array in compile-time.
    #[must_use]
    pub const fn into_array_copy(self) -> [T; CAP]
    where
        T: Copy,
    {
        self.data.into_inner_copy()
    }
}

/// # *Bare* indexing methods (panicking)
impl<T, const CAP: usize> Array<T, CAP, Bare> {
    /// Returns a shared reference to the element at the given `index` in compile-time.
    ///
    /// # Panics
    /// Panics if the `index` is out of bounds in a non-const context.
    ///
    /// # Example
    /// ```
    /// # use devela::Array;
    /// const A: Array<i32, 4> = Array::new_bare([10, 20, 30, 40]);
    /// const VALUE: i32 = *A.get(2);
    /// assert_eq!(VALUE, 30);
    /// ```
    #[must_use]
    pub const fn get(&self, index: usize) -> &T {
        assert!(index < CAP, "Index out of bounds in const context");
        &self.as_bare_slice()[index]
    }

    /// Returns an exclusive reference to the element at the given `index` in compile-time.
    ///
    /// # Panics
    /// Panics if the `index` is out of bounds in a non-const context.
    ///
    /// # Example
    /// ```
    /// # use devela::Array;
    /// const fn modify_array() -> Array<i32, 4> {
    ///     let mut a = Array::new_bare([10, 20, 30, 40]);
    ///     *a.get_mut(2) = 50;
    ///     a
    /// }
    /// const A: Array<i32, 4> = modify_array();
    /// assert_eq!(A.get_mut(2), &50);
    /// ```
    #[must_use]
    pub const fn get_mut(&mut self, index: usize) -> &mut T {
        assert!(index < CAP, "Index out of bounds in const context");
        &mut self.as_bare_mut_slice()[index]
    }
}

/// # *Bare* `Option<T>` methods
impl<T, const CAP: usize> Array<Option<T>, CAP, Bare> {
    /// Checks if all elements are `None`, returning early if a `Some` is found.
    pub const fn is_bare_empty(&self) -> bool {
        let mut n = 0;
        while n <= CAP {
            iif![self.as_bare_slice()[n].is_some(); return false];
            n += 1;
        }
        true
    }

    /// Checks if all elements are `Some`, returning early if a `None` is found.
    pub const fn is_bare_full(&self) -> bool {
        let mut n = 0;
        while n <= CAP {
            iif![self.as_bare_slice()[n].is_none(); return false];
            n += 1;
        }
        true
    }
}