Skip to main content

combo_vec/
re_arr.rs

1#[cfg(feature = "alloc")]
2use alloc::{
3    string::{String, ToString},
4    vec::Vec,
5};
6
7use core::{
8    array::IntoIter as ArrayIter,
9    cmp::Ordering,
10    fmt::{Debug, Display, Formatter, Result as FmtResult},
11    hash::{Hash, Hasher},
12    iter::Flatten,
13    ops,
14};
15
16/// Easy way to create a new [`ReArr`] with elements.
17///
18/// ## Examples
19///
20/// ```rust
21/// use combo_vec::{re_arr, ReArr};
22///
23/// const SOME_ITEMS: ReArr<i8, 3> = re_arr![1, 2, 3];
24/// const MANY_ITEMS: ReArr<u16, 90> = re_arr![5; 90];
25/// const EXTRA_ITEMS: ReArr<&str, 5> = re_arr!["Hello", "world", "!"; None, None];
26///
27/// // Infer the type and size of the ReArr
28/// const NO_STACK_F32: ReArr<f32, 0> = re_arr![];
29///
30/// // No const-initialization is needed to create a ComboVec with allocated elements on the stack
31/// use std::collections::HashMap;
32/// const EMPTY_HASHMAP_ALLOC: ReArr<HashMap<&str, i32>, 3> = re_arr![];
33///
34/// // Creating a new ReArr at compile time and doing this does have performance benefits
35/// let my_re_arr = EMPTY_HASHMAP_ALLOC;
36/// ```
37#[macro_export]
38macro_rules! re_arr {
39    () => (
40        $crate::ReArr::new()
41    );
42    ($elem:expr; $n:expr) => (
43        $crate::ReArr::from_arr([Some($elem); $n])
44    );
45    ($($x:expr),+ $(,)?) => (
46        $crate::ReArr::from_arr([$(Some($x)),+])
47    );
48    ($($x:expr),+; $($rest:expr),* $(,)?) => (
49        $crate::ReArr::from_arr([$(Some($x)),+, $($rest),*])
50    );
51}
52
53/// A [`ReArr`] is a fixed-size array with a variable number of elements.
54///
55/// Create a new [`ReArr`] using the [`re_arr!`] macro.
56///
57/// ## Examples
58///
59/// ```rust
60/// use combo_vec::{re_arr, ReArr};
61///
62/// const SOME_ITEMS: ReArr<i8, 3> = re_arr![1, 2, 3];
63/// const MANY_ITEMS: ReArr<u16, 90> = re_arr![5; 90];
64///
65/// // Infer the type and size of the ReArr
66/// const NO_STACK_F32: ReArr<f32, 0> = re_arr![];
67///
68/// // No const-initialization is needed to create a ReArr with allocated elements on the stack
69/// use std::collections::HashMap;
70/// const EMPTY_HASHMAP_ALLOC: ReArr<HashMap<&str, i32>, 3> = re_arr![];
71///
72/// let mut my_re_arr = re_arr![1, 2, 3; None, None];
73/// // Allocate an extra element on the heap
74/// my_re_arr.push(4);
75/// assert_eq!(my_re_arr.len(), 4);
76/// // Truncate to only the first 2 elements
77/// my_re_arr.truncate(2);
78/// assert_eq!(my_re_arr.len(), 2);
79/// // Fill the last element on the stack, then allocate the next two items on the heap
80/// my_re_arr.extend([3, 4, 5]);
81/// ```
82pub struct ReArr<T, const N: usize> {
83    pub(crate) arr: [Option<T>; N],
84    arr_len: usize,
85}
86
87impl<T: Clone, const N: usize> Clone for ReArr<T, N> {
88    #[inline]
89    fn clone(&self) -> Self {
90        Self {
91            arr: self.arr.clone(),
92            arr_len: self.arr_len,
93        }
94    }
95}
96
97impl<T: PartialOrd, const N: usize> PartialOrd for ReArr<T, N> {
98    #[inline]
99    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
100        self.iter().partial_cmp(other.iter())
101    }
102}
103
104impl<T: Ord, const N: usize> Ord for ReArr<T, N> {
105    #[inline]
106    fn cmp(&self, other: &Self) -> Ordering {
107        self.iter().cmp(other.iter())
108    }
109}
110
111impl<T: PartialEq, const N: usize> PartialEq for ReArr<T, N> {
112    #[inline]
113    fn eq(&self, other: &Self) -> bool {
114        self.iter().eq(other.iter())
115    }
116}
117
118impl<T: PartialEq + Eq, const N: usize> Eq for ReArr<T, N> {}
119
120impl<T: Hash, const N: usize> Hash for ReArr<T, N> {
121    #[inline]
122    fn hash<H: Hasher>(&self, state: &mut H) {
123        self.iter().for_each(|x| x.hash(state));
124    }
125}
126
127impl<T, const N: usize> Default for ReArr<T, N> {
128    #[inline]
129    fn default() -> Self {
130        Self::new()
131    }
132}
133
134impl<T, const N: usize> ReArr<T, N> {
135    const DEFAULT_ARR_VALUE: Option<T> = None;
136
137    /// Create a new, empty [`ReArr`] with the ability for `N` element to stored on the stack.
138    ///
139    /// This is used by the [`re_arr!`] macro, and you should consider using it instead.
140    ///
141    /// ## Examples
142    ///
143    /// ```rust
144    /// use combo_vec::{re_arr, ReArr};
145    ///
146    /// const RE_ARR: ReArr::<i32, 3> = re_arr![];
147    /// let my_re_arr = ReArr::<i32, 3>::new();
148    /// assert_eq!(my_re_arr, RE_ARR);
149    /// ```
150    #[must_use]
151    #[inline]
152    pub const fn new() -> Self {
153        Self {
154            arr: [Self::DEFAULT_ARR_VALUE; N],
155            arr_len: 0,
156        }
157    }
158
159    /// Create a new [`ReArr`] from an array.
160    ///
161    /// All slots must be populated with `Some` values until
162    /// the first `None` value is encountered, or the end of the array is reached.
163    /// After that, all remaining slots must be `None`.
164    ///
165    /// This is used by the [`re_arr!`] macro.
166    ///
167    /// ## Examples
168    ///
169    /// ```rust
170    /// use combo_vec::{re_arr, ReArr};
171    ///
172    /// let my_re_arr = ReArr::from_arr([Some(1), Some(2), Some(3), None, None]);
173    /// let convenient_re_arr = re_arr![1, 2, 3; None, None];
174    ///
175    /// assert_eq!(my_re_arr, convenient_re_arr);
176    /// assert_eq!(my_re_arr.len(), 3);
177    /// assert_eq!(my_re_arr.capacity(), 5);
178    /// ```
179    #[must_use]
180    #[inline]
181    pub const fn from_arr(arr: [Option<T>; N]) -> Self {
182        let mut arr_len = 0;
183        while arr_len < N && arr[arr_len].is_some() {
184            arr_len += 1;
185        }
186
187        Self { arr, arr_len }
188    }
189
190    // Create a new [`ReArr`] from an iterator reference, taking up to N items
191    //
192    // Allows for initialization without consuming the iterator, leaving its
193    // remaining content for another procedure.
194    //
195    // This is useful for ComboVec::from_iter, which needs to initialise both
196    // a ReArr and a Vec.
197    pub(crate) fn from_iter_ref(iter: &mut impl Iterator<Item = T>) -> Self {
198        let mut re_arr = Self::new();
199        for _ in 0..N {
200            if let Some(val) = iter.next() {
201                re_arr.push(val);
202                continue;
203            }
204            break;
205        }
206        re_arr
207    }
208
209    /// Push an element to the end of the array.
210    ///
211    /// ## Panics
212    ///
213    /// Panics if the array is full.
214    ///
215    /// ## Examples
216    ///
217    /// ```rust
218    /// use combo_vec::{re_arr, ReArr};
219    ///
220    /// let mut my_re_arr = re_arr![1, 2, 3; None];
221    /// my_re_arr.push(4);
222    ///
223    /// assert_eq!(my_re_arr.len(), 4);
224    /// assert_eq!(my_re_arr.capacity(), 4);
225    /// #[cfg(feature = "alloc")]
226    /// assert_eq!(my_re_arr.to_vec(), vec![1, 2, 3, 4]);
227    /// ```
228    #[inline]
229    pub fn push(&mut self, val: T) {
230        self.arr[self.arr_len] = Some(val);
231        self.arr_len += 1;
232    }
233
234    /// Remove the last element from the array and return it, or None if it is empty.
235    ///
236    /// ## Examples
237    ///
238    /// ```rust
239    /// use combo_vec::{re_arr, ReArr};
240    ///
241    /// let mut my_re_arr = re_arr![1, 2, 3; None];
242    ///
243    /// assert_eq!(my_re_arr.pop(), Some(3));
244    /// assert_eq!(my_re_arr.pop(), Some(2));
245    /// assert_eq!(my_re_arr.pop(), Some(1));
246    /// assert_eq!(my_re_arr.pop(), None);
247    /// ```
248    #[inline]
249    pub const fn pop(&mut self) -> Option<T> {
250        if self.is_empty() {
251            None
252        } else {
253            self.arr_len -= 1;
254            self.arr[self.arr_len].take()
255        }
256    }
257
258    /// Get any element from the array as a reference, returning `None` if out of bounds.
259    ///
260    /// ## Examples
261    ///
262    /// ```rust
263    /// use combo_vec::{re_arr, ReArr};
264    ///
265    /// let my_re_arr = re_arr![1, 2, 3; None];
266    ///
267    /// assert_eq!(my_re_arr.get(0), Some(&1));
268    /// assert_eq!(my_re_arr.get(1), Some(&2));
269    /// assert_eq!(my_re_arr.get(2), Some(&3));
270    /// assert_eq!(my_re_arr[2], 3);
271    /// assert_eq!(my_re_arr.get(3), None);
272    /// assert_eq!(my_re_arr.get(4), None);
273    /// assert_eq!(my_re_arr.get(5), None);
274    /// ```
275    #[must_use]
276    #[inline]
277    pub fn get(&self, idx: usize) -> Option<&T> {
278        self.arr.get(idx).and_then(|item| item.as_ref())
279    }
280
281    /// Get any element from the array as a mutable reference, `None` if out of bounds.
282    ///
283    /// ## Examples
284    ///
285    /// ```rust
286    /// use combo_vec::{re_arr, ReArr};
287    ///
288    /// let mut my_re_arr = re_arr![1, 2, 3; None];
289    ///
290    /// assert_eq!(my_re_arr.get_mut(0), Some(&mut 1));
291    /// assert_eq!(my_re_arr.get_mut(1), Some(&mut 2));
292    /// my_re_arr[1] = 4;
293    /// assert_eq!(my_re_arr.get_mut(1), Some(&mut 4));
294    /// assert_eq!(my_re_arr.get_mut(2), Some(&mut 3));
295    /// assert_eq!(my_re_arr.get_mut(3), None);
296    /// assert_eq!(my_re_arr.get_mut(4), None);
297    /// assert_eq!(my_re_arr.get_mut(5), None);
298    /// ```
299    #[must_use]
300    #[inline]
301    pub fn get_mut(&mut self, idx: usize) -> Option<&mut T> {
302        self.arr.get_mut(idx).and_then(|item| item.as_mut())
303    }
304
305    /// How many elements are currently stored.
306    ///
307    /// This is not the same as the capacity of the internal array.
308    ///
309    /// ## Examples
310    ///
311    /// ```rust
312    /// use combo_vec::{re_arr, ReArr};
313    ///
314    /// let mut my_re_arr = re_arr![1, 2, 3; None];
315    ///
316    /// assert_eq!(my_re_arr.len(), 3);
317    /// my_re_arr.push(4);
318    /// assert_eq!(my_re_arr.len(), 4);
319    /// my_re_arr.pop();
320    /// assert_eq!(my_re_arr.len(), 3);
321    /// ```
322    #[inline]
323    pub const fn len(&self) -> usize {
324        self.arr_len
325    }
326
327    /// How many elements can be stored.
328    ///
329    /// ## Examples
330    ///
331    /// ```rust
332    /// use combo_vec::{re_arr, ReArr};
333    ///
334    /// let mut my_re_arr = re_arr![1, 2, 3; None];
335    ///
336    /// assert_eq!(my_re_arr.capacity(), 4);
337    /// my_re_arr.push(4);
338    /// assert_eq!(my_re_arr.capacity(), 4);
339    /// my_re_arr.pop();
340    /// assert_eq!(my_re_arr.capacity(), 4);
341    /// ```
342    #[inline]
343    pub const fn capacity(&self) -> usize {
344        N
345    }
346
347    /// Reduce the number of elements to the given length.
348    ///
349    /// If `new_len` is greater than the current length, this has no effect.
350    ///
351    /// ## Examples
352    ///
353    /// ```rust
354    /// use combo_vec::{re_arr, ReArr};
355    ///
356    /// let mut my_re_arr = re_arr![1, 2, 3; None];
357    ///
358    /// assert_eq!(my_re_arr.len(), 3);
359    /// my_re_arr.truncate(2);
360    /// assert_eq!(my_re_arr.len(), 2);
361    /// ```
362    #[inline]
363    pub fn truncate(&mut self, len: usize) {
364        self.arr[len..].iter_mut().for_each(|x| *x = None);
365        self.arr_len = self.arr_len.min(len);
366    }
367
368    /// Remove all elements from the array.
369    ///
370    /// ## Examples
371    ///
372    /// ```rust
373    /// use combo_vec::{re_arr, ReArr};
374    ///
375    /// let mut my_re_arr = re_arr![1, 2, 3; None];
376    ///
377    /// assert_eq!(my_re_arr.len(), 3);
378    /// my_re_arr.clear();
379    /// assert_eq!(my_re_arr.len(), 0);
380    /// ```
381    #[inline]
382    pub fn clear(&mut self) {
383        self.arr.iter_mut().for_each(|x| *x = None);
384        self.arr_len = 0;
385    }
386
387    /// Removes and returns the element at position with a valid index, shifting all elements after it to the left.
388    ///
389    /// ## Panics
390    ///
391    /// Panics if `index` is out of bounds.
392    ///
393    /// ## Examples
394    ///
395    /// ```rust
396    /// use combo_vec::{re_arr, ReArr};
397    ///
398    /// let mut my_re_arr = re_arr![1, 2, 3; None];
399    ///
400    /// assert_eq!(my_re_arr.remove(1), 2);
401    /// assert_eq!(my_re_arr.len(), 2);
402    /// #[cfg(feature = "alloc")]
403    /// assert_eq!(my_re_arr.to_vec(), vec![1, 3]);
404    /// ```
405    #[inline]
406    pub fn remove(&mut self, index: usize) -> T {
407        let val = self.arr[index].take().unwrap();
408
409        for i in index..self.arr_len - 1 {
410            self.arr[i] = self.arr[i + 1].take();
411        }
412
413        self.arr_len -= 1;
414
415        val
416    }
417
418    /// Removes an element from the `ReArr` and returns it.
419    ///
420    /// The removed element is replaced by the last element of the `ReArr`.
421    ///
422    /// This does not preserve ordering, but is O(1). If you need to preserve the element order, use remove instead.
423    ///
424    /// ## Panics
425    ///
426    /// Panics if `index` is out of bounds, or if it is the last value.
427    ///
428    /// ## Examples
429    ///
430    /// ```rust
431    /// use combo_vec::{re_arr, ReArr};
432    ///
433    /// let mut my_re_arr = re_arr![1, 2, 3; None];
434    ///
435    /// assert_eq!(my_re_arr.swap_remove(0), 1);
436    /// assert_eq!(my_re_arr.len(), 2);
437    /// #[cfg(feature = "alloc")]
438    /// assert_eq!(my_re_arr.to_vec(), vec![3, 2]);
439    /// ```
440    #[inline]
441    pub const fn swap_remove(&mut self, index: usize) -> T {
442        let last_value = self.pop().unwrap();
443        self.arr[index].replace(last_value).unwrap()
444    }
445
446    /// Get the first element, returning `None` if there are no elements.
447    ///
448    /// ## Examples
449    ///
450    /// ```rust
451    /// use combo_vec::{re_arr, ReArr};
452    ///
453    /// let my_re_arr = re_arr![1, 2, 3; None];
454    ///
455    /// assert_eq!(my_re_arr.first(), Some(&1));
456    /// ```
457    #[inline]
458    pub const fn first(&self) -> Option<&T> {
459        if N == 0 {
460            None
461        } else {
462            self.arr[0].as_ref()
463        }
464    }
465
466    /// Get the first element as a mutable reference, returning `None` if there are no elements.
467    ///
468    /// ## Examples
469    ///
470    /// ```rust
471    /// use combo_vec::{re_arr, ReArr};
472    ///
473    /// let mut my_re_arr = re_arr![1, 2, 3; None];
474    ///
475    /// assert_eq!(my_re_arr.first_mut(), Some(&mut 1));
476    /// ```
477    #[inline]
478    pub const fn first_mut(&mut self) -> Option<&mut T> {
479        if N == 0 {
480            None
481        } else {
482            self.arr[0].as_mut()
483        }
484    }
485
486    /// Get the last element, returning `None` if there are no elements.
487    ///
488    /// ## Examples
489    ///
490    /// ```rust
491    /// use combo_vec::{re_arr, ReArr};
492    ///
493    /// let my_re_arr = re_arr![1, 2, 3; None];
494    ///
495    /// assert_eq!(my_re_arr.last(), Some(&3));
496    /// ```
497    #[inline]
498    pub const fn last(&self) -> Option<&T> {
499        if self.is_empty() {
500            None
501        } else {
502            self.arr[self.arr_len - 1].as_ref()
503        }
504    }
505
506    /// Get the last element as a mutable reference, returning `None` if there are no elements.
507    ///
508    /// ## Examples
509    ///
510    /// ```rust
511    /// use combo_vec::{re_arr, ReArr};
512    ///
513    /// let mut my_re_arr = re_arr![1, 2, 3; None];
514    ///
515    /// assert_eq!(my_re_arr.last_mut(), Some(&mut 3));
516    /// ```
517    #[inline]
518    pub const fn last_mut(&mut self) -> Option<&mut T> {
519        if self.is_empty() {
520            None
521        } else {
522            self.arr[self.arr_len - 1].as_mut()
523        }
524    }
525
526    /// Check if there are no elements.
527    ///
528    /// ## Examples
529    ///
530    /// ```rust
531    /// use combo_vec::{re_arr, ReArr};
532    ///
533    /// let my_re_arr = re_arr![1, 2, 3; None];
534    /// assert_eq!(my_re_arr.is_empty(), false);
535    ///
536    /// let empty_re_arr = ReArr::<i32, 3>::new();
537    /// assert_eq!(empty_re_arr.is_empty(), true);
538    /// ```
539    #[inline]
540    pub const fn is_empty(&self) -> bool {
541        self.arr_len == 0
542    }
543
544    /// Get an iterator over the elements of the array.
545    ///
546    /// ## Examples
547    ///
548    /// ```rust
549    /// use combo_vec::{re_arr, ReArr};
550    ///
551    /// let my_re_arr = re_arr![1, 2, 3; None];
552    ///
553    /// assert_eq!(my_re_arr.iter().collect::<Vec<_>>(), vec![&1, &2, &3]);
554    /// ```
555    #[inline]
556    pub fn iter(&self) -> impl Iterator<Item = &T> + '_ {
557        self.arr.iter().flatten()
558    }
559
560    /// Get an iterator over the elements of the array, returning mutable references.
561    ///
562    /// ## Examples
563    ///
564    /// ```rust
565    /// use combo_vec::{re_arr, ReArr};
566    ///
567    /// let mut my_re_arr = re_arr![1, 2, 3; None];
568    ///
569    /// assert_eq!(my_re_arr.iter_mut().collect::<Vec<_>>(), vec![&mut 1, &mut 2, &mut 3]);
570    /// ```
571    #[inline]
572    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> + '_ {
573        self.arr.iter_mut().flatten()
574    }
575
576    /// Extend this array with all the elements from the given iterator.
577    ///
578    /// ## Panics
579    ///
580    /// Panics if the iterator tries to push more elements than the internal array can hold.
581    ///
582    /// ## Examples
583    ///
584    /// ```rust
585    /// use combo_vec::{re_arr, ReArr};
586    ///
587    /// let mut my_re_arr = re_arr![1, 2, 3; None, None, None];
588    /// assert_eq!(my_re_arr.len(), 3);
589    /// assert_eq!(my_re_arr.capacity(), 6);
590    ///
591    /// my_re_arr.extend([4, 5, 6]);
592    /// assert_eq!(my_re_arr.len(), 6);
593    /// ```
594    #[inline]
595    pub fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
596        iter.into_iter().for_each(|x| self.push(x));
597    }
598
599    /// Get this [`ReArr`] transformed into a [`Vec`].
600    ///
601    /// ## Examples
602    ///
603    /// ```rust
604    /// use combo_vec::{re_arr, ReArr};
605    ///
606    /// let my_re_arr = re_arr![1, 2, 3; None];
607    ///
608    /// assert_eq!(my_re_arr.into_vec(), vec![1, 2, 3]);
609    /// ```
610    #[cfg(feature = "alloc")]
611    #[inline]
612    pub fn into_vec(self) -> Vec<T> {
613        self.into_iter().collect()
614    }
615
616    /// Get this [`ReArr`] represented as a [`Vec`], borrowing data instead of moving it.
617    ///
618    /// ## Examples
619    ///
620    /// ```rust
621    /// use combo_vec::{re_arr, ReArr};
622    ///
623    /// let my_re_arr = re_arr![1, 2, 3; None];
624    ///
625    /// assert_eq!(my_re_arr.ref_vec(), vec![&1, &2, &3]);
626    /// ```
627    #[cfg(feature = "alloc")]
628    #[inline]
629    pub fn ref_vec(&self) -> Vec<&T> {
630        self.iter().collect()
631    }
632}
633
634impl<T: Clone, const N: usize> ReArr<T, N> {
635    /// Get this [`ReArr`] represented as a [`Vec`].
636    ///
637    /// ## Examples
638    ///
639    /// ```rust
640    /// use combo_vec::{re_arr, ReArr};
641    ///
642    /// let my_re_arr = re_arr![1, 2, 3; None];
643    ///
644    /// assert_eq!(my_re_arr.to_vec(), vec![1, 2, 3]);
645    /// // my_re_arr is still usable
646    /// assert_eq!(my_re_arr.len(), 3);
647    /// ```
648    #[cfg(feature = "alloc")]
649    #[inline]
650    pub fn to_vec(&self) -> Vec<T> {
651        self.iter().cloned().collect()
652    }
653
654    /// Resizes the [`ReArr`] in-place so that `len` is equal to `new_len`.
655    ///
656    /// If `new_len` is greater than `len`, the [`ReArr`] is extended by the
657    /// difference, with each additional slot filled with `val`.
658    ///
659    /// If `new_len` is less than `len`, the [`ReArr`] is truncated.
660    ///
661    /// ## Panics
662    ///
663    /// If `new_len` is greater than the length of the internal array.
664    ///
665    /// # Examples
666    ///
667    /// ```rust
668    /// use combo_vec::{re_arr, ReArr};
669    ///
670    /// let mut my_re_arr = re_arr![1, 2, 3; None, None];
671    ///
672    /// assert_eq!(my_re_arr.len(), 3);
673    /// my_re_arr.resize(5, 4);
674    /// assert_eq!(my_re_arr.len(), 5);
675    /// #[cfg(feature = "alloc")]
676    /// assert_eq!(my_re_arr.to_vec(), vec![1, 2, 3, 4, 4]);
677    /// my_re_arr.resize(2, 4);
678    /// assert_eq!(my_re_arr.len(), 2);
679    /// #[cfg(feature = "alloc")]
680    /// assert_eq!(my_re_arr.to_vec(), vec![1, 2]);
681    /// ```
682    pub fn resize(&mut self, new_len: usize, val: T) {
683        assert!(
684            new_len <= N,
685            "new length cannot be greater than the internal array length"
686        );
687
688        if new_len > self.arr_len {
689            self.arr[self.arr_len..new_len].fill(Some(val));
690        } else {
691            self.arr[new_len..].fill(None);
692        }
693
694        self.arr_len = new_len;
695    }
696
697    /// Resizes the [`ReArr`] in-place so that `len` is equal to `new_len`.
698    ///
699    /// If `new_len` is greater than `len`, the [`ReArr`] is extended
700    /// with the result of calling the closure `f`.
701    ///
702    /// If `new_len` is less than `len`, the [`ReArr`] is truncated.
703    ///
704    /// ## Panics
705    ///
706    /// If `new_len` is greater than the length of the internal array.
707    ///
708    /// # Examples
709    ///
710    /// ```rust
711    /// use combo_vec::{re_arr, ReArr};
712    ///
713    /// let mut my_re_arr = re_arr![1, 2, 3; None, None];
714    ///
715    /// assert_eq!(my_re_arr.len(), 3);
716    /// my_re_arr.resize_with(5, Default::default);
717    /// assert_eq!(my_re_arr.len(), 5);
718    /// #[cfg(feature = "alloc")]
719    /// assert_eq!(my_re_arr.to_vec(), vec![1, 2, 3, 0, 0]);
720    /// my_re_arr.resize_with(2, Default::default);
721    /// assert_eq!(my_re_arr.len(), 2);
722    /// #[cfg(feature = "alloc")]
723    /// assert_eq!(my_re_arr.to_vec(), vec![1, 2]);
724    /// ```
725    pub fn resize_with<F: FnMut() -> T>(&mut self, new_len: usize, mut f: F) {
726        assert!(
727            new_len <= N,
728            "new length cannot be greater than the internal array length"
729        );
730
731        if new_len > self.arr_len {
732            self.arr[self.arr_len..new_len].fill(Some(f()));
733        } else {
734            self.arr[new_len..].fill(None);
735        }
736
737        self.arr_len = new_len;
738    }
739}
740
741#[cfg(feature = "alloc")]
742impl<T: ToString, const N: usize> ReArr<T, N> {
743    /// Joins the [`ReArr`] into a string with a separator.
744    ///
745    /// ## Examples
746    ///
747    /// ```rust
748    /// use combo_vec::re_arr;
749    ///
750    /// let x = re_arr![1, 2, 3];
751    /// assert_eq!(x.join(", "), "1, 2, 3");
752    /// ```
753    pub fn join(&self, sep: &str) -> String {
754        self.iter()
755            .enumerate()
756            .fold(String::with_capacity(self.arr_len), |mut s, (i, item)| {
757                if i != 0 {
758                    s.push_str(sep);
759                }
760
761                s.push_str(&item.to_string());
762                s
763            })
764    }
765}
766
767impl<T, const N: usize> ops::Index<usize> for ReArr<T, N> {
768    type Output = T;
769
770    #[inline]
771    fn index(&self, idx: usize) -> &Self::Output {
772        self.arr[idx].as_ref().unwrap()
773    }
774}
775
776impl<T, const N: usize> ops::IndexMut<usize> for ReArr<T, N> {
777    #[inline]
778    fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
779        self.arr[idx].as_mut().unwrap()
780    }
781}
782
783impl<T, const N: usize> IntoIterator for ReArr<T, N> {
784    type Item = T;
785    type IntoIter = Flatten<ArrayIter<Option<T>, N>>;
786
787    #[inline]
788    fn into_iter(self) -> Self::IntoIter {
789        self.arr.into_iter().flatten()
790    }
791}
792
793impl<T, const N: usize> FromIterator<T> for ReArr<T, N> {
794    #[inline]
795    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
796        Self::from_iter_ref(&mut iter.into_iter())
797    }
798}
799
800impl<T: Debug, const N: usize> Debug for ReArr<T, N> {
801    #[inline]
802    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
803        f.debug_struct("ReArr")
804            .field("arr", &self.arr)
805            .field("arr_len", &self.arr_len)
806            .finish()
807    }
808}
809
810impl<T: Debug, const N: usize> Display for ReArr<T, N> {
811    #[inline]
812    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
813        f.debug_list().entries(self.arr.iter().flatten()).finish()
814    }
815}