ladata/list/array/
methods.rs

1// ladata::list::array::methods
2//
3//! Arrays.
4//
5
6#[cfg(feature = "unsafe_init")]
7use core::mem::{self, MaybeUninit};
8
9use crate::all::{Array, Direct, Storage};
10
11#[allow(unused)]
12#[cfg(feature = "alloc")]
13use {
14    crate::mem::Boxed,
15    alloc::{boxed::Box, vec::Vec},
16};
17
18// ``
19impl<T, S: Storage, const LEN: usize> Array<T, S, LEN> {
20    /// Returns an new `Array` from the given primitive `array`.
21    pub fn new(array: [T; LEN]) -> Self {
22        Self {
23            array: array.into(),
24        }
25    }
26}
27
28// `S:() + T:Clone`
29impl<T: Clone, const LEN: usize> Array<T, (), LEN> {
30    /// Returns an array, allocated in the stack,
31    /// filled with `element`, cloned.
32    ///
33    /// # Examples
34    /// ```
35    /// use ladata::list::Array;
36    ///
37    /// let s = Array::<_, (), 16>::with(0);
38    /// ```
39    pub fn with(element: T) -> Self {
40        #[cfg(feature = "unsafe_init")]
41        let data = Direct::new({
42            let mut arr: [MaybeUninit<T>; LEN] = unsafe { MaybeUninit::uninit().assume_init() };
43
44            for i in &mut arr[..] {
45                let _ = i.write(element.clone());
46            }
47
48            // TEMP:FIX: can't use transmute for now:
49            // - https://github.com/rust-lang/rust/issues/62875
50            // - https://github.com/rust-lang/rust/issues/61956
51            // mem::transmute::<_, [T; LEN]>(&arr)
52            //
53            // SAFETY: we've initialized all the elements
54            unsafe { mem::transmute_copy::<_, [T; LEN]>(&arr) }
55        });
56
57        #[cfg(not(feature = "unsafe_init"))]
58        let data = Direct::new(core::array::from_fn(|_| element.clone()));
59
60        Self { array: data }
61    }
62}
63
64// `S:Boxed + T:Clone`
65#[cfg(feature = "alloc")]
66#[cfg_attr(feature = "nightly", doc(cfg(feature = "alloc")))]
67impl<T: Clone, const LEN: usize> Array<T, Boxed, LEN> {
68    /// Returns an empty stack, allocated in the heap,
69    /// using `element` to fill the remaining free data.
70    ///
71    /// # Examples
72    /// ```
73    /// use ladata::list::BoxedArray;
74    ///
75    /// let mut s = BoxedArray::<_, 1_000>::with(0);
76    /// ```
77    pub fn with(element: T) -> Self {
78        #[cfg(not(feature = "unsafe_init"))]
79        let data = {
80            let mut v = Vec::<T>::with_capacity(LEN);
81
82            for _ in 0..LEN {
83                v.push(element.clone());
84            }
85
86            let Ok(array) = v.into_boxed_slice().try_into() else {
87                panic!("Can't turn the boxed slice into a boxed array");
88            };
89            array
90        };
91
92        #[cfg(feature = "unsafe_init")]
93        let data = {
94            let mut v = Vec::<T>::with_capacity(LEN);
95
96            for _ in 0..LEN {
97                v.push(element.clone());
98            }
99
100            let slice = v.into_boxed_slice();
101            let raw_slice = Box::into_raw(slice);
102            // SAFETY: pointer comes from using `into_raw`, and capacity is right.
103            unsafe { Box::from_raw(raw_slice as *mut [T; LEN]) }
104        };
105
106        Self { array: data }
107    }
108}
109
110// `T: PartialEq`
111impl<T: PartialEq, S: Storage, const CAP: usize> Array<T, S, CAP> {
112    /// Returns true if the array contains `element`.
113    ///
114    /// # Examples
115    /// ```
116    /// use ladata::all::Array;
117    ///
118    /// let a = Array::<_, (), 5>::new([5, 78, 42, 33, 9]);
119    ///
120    /// assert![a.contains(&9)];
121    /// assert![!a.contains(&8)];
122    /// ```
123    pub fn contains(&self, element: &T) -> bool {
124        self.iter().any(|n| n == element)
125    }
126}
127
128// ``
129impl<T, S: Storage, const LEN: usize> Array<T, S, LEN> {
130    /// Returns the number of elements in the array.
131    #[inline]
132    pub const fn len(&self) -> usize {
133        LEN
134    }
135
136    /// Returns `true` if the array has a length of 0.
137    #[inline]
138    pub const fn is_empty(&self) -> bool {
139        LEN == 0
140    }
141
142    /// Returns a slice containing the entire array.
143    pub fn as_slice(&self) -> &[T] {
144        self.array.as_slice()
145    }
146
147    /// Returns an exclusive slice containing the entire array.
148    pub fn as_mut_slice(&mut self) -> &mut [T] {
149        self.array.as_mut_slice()
150    }
151}
152
153// `S: Boxed`
154#[cfg(feature = "alloc")]
155#[cfg_attr(feature = "nightly", doc(cfg(feature = "alloc")))]
156impl<T, const LEN: usize> Array<T, Boxed, LEN> {
157    /// Returns the inner boxed primitive array.
158    pub fn into_array(self) -> Box<[T; LEN]> {
159        self.array
160    }
161}
162// `S: ()`
163impl<T, const LEN: usize> Array<T, (), LEN> {
164    /// Returns the inner boxed primitive array.
165    pub fn into_array(self) -> [T; LEN] {
166        self.array.0
167    }
168}