Skip to main content

ps_util/
array.rs

1use std::{cmp::Ordering, fmt::Write};
2
3use crate::{subarray, subarray_checked, subarray_unchecked};
4
5pub trait Array<T> {
6    /// Returns a reference to the element at the specified index,
7    /// or `None` if the index is out of bounds.
8    ///
9    /// # Examples
10    ///
11    /// ```
12    /// use ps_util::Array;
13    /// let arr = [1, 2, 3];
14    /// assert_eq!(arr.at(0), Some(&1));
15    /// assert_eq!(arr.at(5), None);
16    /// ```
17    fn at(&self, index: usize) -> Option<&T>;
18
19    /// Concatenates this array with another slice and returns a new vector.
20    ///
21    /// # Examples
22    ///
23    /// ```
24    /// use ps_util::Array;
25    /// let arr = [1, 2];
26    /// let result = arr.concat(&[3, 4]);
27    /// assert_eq!(result, vec![1, 2, 3, 4]);
28    /// ```
29    fn concat(&self, other: impl AsRef<[T]>) -> Vec<T>
30    where
31        T: Clone;
32
33    /// Returns an iterator of (index, &T) tuples for each element.
34    ///
35    /// # Examples
36    ///
37    /// ```
38    /// use ps_util::Array;
39    /// let arr = ['a', 'b'];
40    /// let entries: Vec<_> = arr.entries().collect();
41    /// assert_eq!(entries, vec![(0, &'a'), (1, &'b')]);
42    /// ```
43    fn entries<'a>(&'a self) -> impl Iterator<Item = (usize, &'a T)>
44    where
45        T: 'a;
46
47    /// Tests whether all elements match the predicate.
48    ///
49    /// Returns `true` if the predicate returns `true` for every element,
50    /// or if the array is empty.
51    ///
52    /// # Examples
53    ///
54    /// ```
55    /// use ps_util::Array;
56    /// let arr = [2, 4, 6];
57    /// assert!(arr.every(|x| x % 2 == 0));
58    /// assert!(!arr.every(|x| x > &5));
59    /// ```
60    fn every(&self, predicate: impl FnMut(&T) -> bool) -> bool;
61
62    /// Tests whether all elements are equal to the comparator target.
63    ///
64    /// Returns `true` if the array is empty or every element compares as
65    /// [`Ordering::Equal`].
66    ///
67    /// **Only the first and last elements are checked.**
68    ///
69    /// The slice must be sorted according to the same ordering used by
70    /// `comparator`.
71    ///
72    /// Time complexity: `O(1)`.
73    ///
74    /// # Examples
75    ///
76    /// ```
77    /// use ps_util::Array;
78    ///
79    /// let arr = [2, 2, 2];
80    /// assert!(arr.every_equal_in_sorted_by(|x| x.cmp(&2)));
81    ///
82    /// let arr = [1, 2, 2];
83    /// assert!(!arr.every_equal_in_sorted_by(|x| x.cmp(&2)));
84    /// ```
85    fn every_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> bool;
86
87    /// Returns a reference to the first element that matches the predicate.
88    ///
89    /// # Examples
90    ///
91    /// ```
92    /// use ps_util::Array;
93    /// let arr = [1, 2, 3, 4];
94    /// assert_eq!(arr.find(|x| x > &2), Some(&3));
95    /// assert_eq!(arr.find(|x| x > &10), None);
96    /// ```
97    fn find(&self, predicate: impl FnMut(&T) -> bool) -> Option<&T>;
98
99    /// Returns the first element equal to the comparator target.
100    ///
101    /// The slice must be sorted according to the same ordering used by
102    /// `comparator`.
103    ///
104    /// Time complexity: `O(log n)`.
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// use ps_util::Array;
110    /// let arr = [1, 2, 2, 2, 3];
111    /// assert_eq!(arr.find_equal_in_sorted_by(|x| x.cmp(&2)), Some(&2));
112    /// assert_eq!(arr.find_equal_in_sorted_by(|x| x.cmp(&5)), None);
113    /// ```
114    fn find_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> Option<&T>;
115
116    /// Returns the index of the first element that matches the predicate.
117    ///
118    /// # Examples
119    ///
120    /// ```
121    /// use ps_util::Array;
122    /// let arr = [1, 2, 3, 4];
123    /// assert_eq!(arr.find_index(|x| x > &2), Some(2));
124    /// assert_eq!(arr.find_index(|x| x > &10), None);
125    /// ```
126    fn find_index(&self, predicate: impl FnMut(&T) -> bool) -> Option<usize>;
127
128    /// Returns the index of the first element equal to the comparator target.
129    ///
130    /// The slice must be sorted according to the same ordering used by
131    /// `comparator`.
132    ///
133    /// Time complexity: `O(log n)`.
134    ///
135    /// # Examples
136    ///
137    /// ```
138    /// use ps_util::Array;
139    /// let arr = [1, 2, 2, 2, 3];
140    /// assert_eq!(arr.find_index_equal_in_sorted_by(|x| x.cmp(&2)), Some(1));
141    /// assert_eq!(arr.find_index_equal_in_sorted_by(|x| x.cmp(&5)), None);
142    /// ```
143    fn find_index_equal_in_sorted_by(
144        &self,
145        comparator: impl FnMut(&T) -> Ordering,
146    ) -> Option<usize>;
147
148    /// Returns a reference to the last element that matches the predicate.
149    ///
150    /// # Examples
151    ///
152    /// ```
153    /// use ps_util::Array;
154    /// let arr = [1, 2, 3, 4];
155    /// assert_eq!(arr.find_last(|x| x < &4), Some(&3));
156    /// assert_eq!(arr.find_last(|x| x > &10), None);
157    /// ```
158    fn find_last(&self, predicate: impl FnMut(&T) -> bool) -> Option<&T>;
159
160    /// Returns the last element equal to the comparator target.
161    ///
162    /// The slice must be sorted according to the same ordering used by
163    /// `comparator`.
164    ///
165    /// Time complexity: `O(log n)`.
166    ///
167    /// # Examples
168    ///
169    /// ```
170    /// use ps_util::Array;
171    /// let arr = [1, 2, 2, 2, 3];
172    /// assert_eq!(arr.find_last_equal_in_sorted_by(|x| x.cmp(&2)), Some(&2));
173    /// assert_eq!(arr.find_last_equal_in_sorted_by(|x| x.cmp(&5)), None);
174    /// ```
175    fn find_last_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> Option<&T>;
176
177    /// Returns the index of the last element that matches the predicate.
178    ///
179    /// # Examples
180    ///
181    /// ```
182    /// use ps_util::Array;
183    /// let arr = [1, 2, 3, 4];
184    /// assert_eq!(arr.find_last_index(|x| x < &4), Some(2));
185    /// assert_eq!(arr.find_last_index(|x| x > &10), None);
186    /// ```
187    fn find_last_index(&self, predicate: impl FnMut(&T) -> bool) -> Option<usize>;
188
189    /// Returns the index of the last element equal to the comparator target.
190    ///
191    /// The slice must be sorted according to the same ordering used by
192    /// `comparator`.
193    ///
194    /// Time complexity: `O(log n)`.
195    ///
196    /// # Examples
197    ///
198    /// ```
199    /// use ps_util::Array;
200    /// let arr = [1, 2, 2, 2, 3];
201    /// assert_eq!(arr.find_last_index_equal_in_sorted_by(|x| x.cmp(&2)), Some(3));
202    /// assert_eq!(arr.find_last_index_equal_in_sorted_by(|x| x.cmp(&5)), None);
203    /// ```
204    fn find_last_index_equal_in_sorted_by(
205        &self,
206        comparator: impl FnMut(&T) -> Ordering,
207    ) -> Option<usize>;
208
209    /// Returns a vector containing all elements that match the predicate.
210    ///
211    /// # Examples
212    ///
213    /// ```
214    /// use ps_util::Array;
215    /// let arr = [1, 2, 3, 4];
216    /// assert_eq!(arr.filter(|x| x % 2 == 0), vec![2, 4]);
217    /// ```
218    fn filter(&self, predicate: impl FnMut(&T) -> bool) -> Vec<T>
219    where
220        T: Clone;
221
222    /// Returns all elements equal to the comparator target.
223    ///
224    /// The slice must be sorted according to the same ordering used by
225    /// `comparator`.
226    ///
227    /// Time complexity: `O(log n + k)`, where `k` is the number of matches.
228    ///
229    /// # Examples
230    ///
231    /// ```
232    /// use ps_util::Array;
233    /// let arr = [1, 2, 2, 2, 3];
234    /// assert_eq!(arr.filter_equal_in_sorted_by(|x| x.cmp(&2)), vec![2, 2, 2]);
235    /// assert_eq!(arr.filter_equal_in_sorted_by(|x| x.cmp(&5)), Vec::<i32>::new());
236    /// ```
237    fn filter_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> Vec<T>
238    where
239        T: Clone;
240
241    /// Flattens a level of nesting in an array of iterables.
242    ///
243    /// # Examples
244    ///
245    /// ```
246    /// use ps_util::Array;
247    /// let arr = [vec![1, 2], vec![3, 4]];
248    /// assert_eq!(arr.flat(), vec![1, 2, 3, 4]);
249    /// ```
250    fn flat(&self) -> Vec<T::Item>
251    where
252        T: Clone + IntoIterator;
253
254    /// Maps each element to an iterable and flattens the result.
255    ///
256    /// # Examples
257    ///
258    /// ```
259    /// use ps_util::Array;
260    /// let arr = [1, 2, 3];
261    /// let result = arr.flat_map(|x| vec![*x, *x * 2]);
262    /// assert_eq!(result, vec![1, 2, 2, 4, 3, 6]);
263    /// ```
264    fn flat_map<O, I>(&self, mapper: impl FnMut(&T) -> I) -> Vec<O>
265    where
266        I: IntoIterator<Item = O>;
267
268    /// Applies a closure to each element for side effects.
269    ///
270    /// # Examples
271    ///
272    /// ```
273    /// use ps_util::Array;
274    /// let arr = [1, 2, 3];
275    /// arr.for_each(|x| println!("{}", x));
276    /// ```
277    fn for_each(&self, cb: impl FnMut(&T));
278
279    /// Checks whether the array contains the specified value.
280    ///
281    /// # Examples
282    ///
283    /// ```
284    /// use ps_util::Array;
285    /// let arr = [1, 2, 3];
286    /// assert!(arr.includes(&2));
287    /// assert!(!arr.includes(&5));
288    /// ```
289    fn includes(&self, value: &T) -> bool
290    where
291        T: PartialEq;
292
293    /// Returns the index of the first occurrence of the specified value,
294    /// or `None` if not found.
295    ///
296    /// # Examples
297    ///
298    /// ```
299    /// use ps_util::Array;
300    /// let arr = [1, 2, 3, 2];
301    /// assert_eq!(arr.index_of(&2), Some(1));
302    /// assert_eq!(arr.index_of(&5), None);
303    /// ```
304    fn index_of(&self, value: &T) -> Option<usize>
305    where
306        T: PartialEq;
307
308    /// Returns `true` if the array is empty.
309    ///
310    /// # Examples
311    ///
312    /// ```
313    /// use ps_util::Array;
314    /// assert!(Vec::<i32>::new().is_empty());
315    /// assert!(![1].is_empty());
316    /// ```
317    fn is_empty(&self) -> bool;
318
319    /// Concatenates all elements into a string, separated by the given separator.
320    ///
321    /// # Examples
322    ///
323    /// ```
324    /// use ps_util::Array;
325    /// let arr = [1, 2, 3];
326    /// assert_eq!(arr.join(", "), "1, 2, 3");
327    /// ```
328    fn join<S>(&self, separator: &S) -> String
329    where
330        S: std::fmt::Display + ?Sized,
331        T: std::fmt::Display;
332
333    /// Returns an iterator of indices (0, 1, 2, ...).
334    ///
335    /// # Examples
336    ///
337    /// ```
338    /// use ps_util::Array;
339    /// let arr = ['a', 'b', 'c'];
340    /// let keys: Vec<_> = arr.keys().collect();
341    /// assert_eq!(keys, vec![0, 1, 2]);
342    /// ```
343    fn keys(&self) -> impl Iterator<Item = usize>;
344
345    /// Returns the index of the last occurrence of the specified value,
346    /// or `None` if not found.
347    ///
348    /// # Examples
349    ///
350    /// ```
351    /// use ps_util::Array;
352    /// let arr = [1, 2, 3, 2];
353    /// assert_eq!(arr.last_index_of(&2), Some(3));
354    /// assert_eq!(arr.last_index_of(&5), None);
355    /// ```
356    fn last_index_of(&self, value: &T) -> Option<usize>
357    where
358        T: PartialEq;
359
360    /// Returns the number of elements in the array.
361    ///
362    /// # Examples
363    ///
364    /// ```
365    /// use ps_util::Array;
366    /// let arr = [1, 2, 3];
367    /// assert_eq!(arr.len(), 3);
368    /// ```
369    fn len(&self) -> usize;
370
371    /// Transforms each element using the provided mapper function
372    /// and returns a vector of the results.
373    ///
374    /// # Examples
375    ///
376    /// ```
377    /// use ps_util::Array;
378    /// let arr = [1, 2, 3u8];
379    /// assert_eq!(arr.as_slice().map(|x| x * 2), vec![2, 4, 6]);
380    /// ```
381    fn map<O>(&self, mapper: impl FnMut(&T) -> O) -> Vec<O>;
382
383    /// Reduces the array to a single value by applying a callback
384    /// with an accumulator, starting from the left.
385    ///
386    /// # Examples
387    ///
388    /// ```
389    /// use ps_util::Array;
390    /// let arr = [1, 2, 3, 4];
391    /// let sum = arr.reduce(|acc, x| acc + x, 0);
392    /// assert_eq!(sum, 10);
393    /// ```
394    fn reduce<O>(&self, reducer: impl FnMut(O, &T) -> O, initial: O) -> O;
395
396    /// Reduces the array to a single value by applying a callback
397    /// with an accumulator, starting from the right.
398    ///
399    /// # Examples
400    ///
401    /// ```
402    /// use ps_util::Array;
403    /// let arr = [1, 2, 3];
404    /// let result = arr.reduce_right(
405    ///     |acc, x| format!("{}{}", acc, x),
406    ///     String::new()
407    /// );
408    /// assert_eq!(result, "321");
409    /// ```
410    fn reduce_right<O>(&self, reducer: impl FnMut(O, &T) -> O, initial: O) -> O;
411
412    /// Returns a slice of the array from `start` to `end` (exclusive).
413    ///
414    /// If `end` is `None`, slices to the end of the array. Indices are clamped
415    /// to valid bounds; if `start` exceeds the array length, an empty slice
416    /// is returned.
417    ///
418    /// # Examples
419    ///
420    /// ```
421    /// use ps_util::Array;
422    /// let arr = [1, 2, 3, 4];
423    /// assert_eq!(arr.slice(1, Some(3)), &[2, 3][..]);
424    /// assert_eq!(arr.slice(2, None), &[3, 4][..]);
425    /// assert_eq!(arr.slice(10, Some(20)), &[][..]);
426    /// ```
427    fn slice(&self, start: usize, end: Option<usize>) -> &[T];
428
429    /// Tests whether any element matches the predicate.
430    ///
431    /// Returns `true` if the predicate returns `true` for at least one element.
432    ///
433    /// # Examples
434    ///
435    /// ```
436    /// use ps_util::Array;
437    /// let arr = [1, 2, 3];
438    /// assert!(arr.some(|x| x > &2));
439    /// assert!(!arr.some(|x| x > &10));
440    /// ```
441    fn some(&self, predicate: impl FnMut(&T) -> bool) -> bool;
442
443    /// Tests whether any element is equal to the comparator target.
444    ///
445    /// The slice must be sorted according to the same ordering used by
446    /// `comparator`.
447    ///
448    /// Time complexity: `O(log n)`.
449    ///
450    /// # Examples
451    ///
452    /// ```
453    /// use ps_util::Array;
454    /// let arr = [1, 2, 2, 3];
455    /// assert!(arr.some_equal_in_sorted_by(|x| x.cmp(&2)));
456    /// assert!(!arr.some_equal_in_sorted_by(|x| x.cmp(&5)));
457    /// ```
458    fn some_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> bool;
459
460    /// Tests whether no elements match the predicate.
461    ///
462    /// Returns `true` if the predicate returns `false` for every element,
463    /// or if the array is empty.
464    ///
465    /// # Examples
466    ///
467    /// ```
468    /// use ps_util::Array;
469    /// let arr = [1, 2, 3];
470    /// assert!(arr.none(|x| x > &10));
471    /// assert!(!arr.none(|x| x > &2));
472    /// ```
473    fn none(&self, predicate: impl FnMut(&T) -> bool) -> bool;
474
475    /// Tests whether no element is equal to the comparator target.
476    ///
477    /// The slice must be sorted according to the same ordering used by
478    /// `comparator`.
479    ///
480    /// Time complexity: `O(log n)`.
481    ///
482    /// # Examples
483    ///
484    /// ```
485    /// use ps_util::Array;
486    /// let arr = [1, 2, 2, 3];
487    /// assert!(arr.none_equal_in_sorted_by(|x| x.cmp(&5)));
488    /// assert!(!arr.none_equal_in_sorted_by(|x| x.cmp(&2)));
489    /// ```
490    fn none_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> bool;
491
492    /// Returns a fixed-size array reference starting at the given index.
493    ///
494    /// # Panics
495    ///
496    /// Panics if there are not enough elements remaining in the array.
497    ///
498    /// # Examples
499    ///
500    /// ```
501    /// use ps_util::Array;
502    /// let arr = [1, 2, 3, 4];
503    /// assert_eq!(arr.subarray::<2>(1), &[2, 3]);
504    /// ```
505    fn subarray<const S: usize>(&self, index: usize) -> &[T; S];
506
507    /// Checked version of `subarray`. Returns `None` if bounds are exceeded.
508    ///
509    /// # Examples
510    ///
511    /// ```
512    /// use ps_util::Array;
513    /// let arr = [1, 2, 3];
514    /// assert_eq!(arr.subarray_checked::<2>(1), Some(&[2, 3]));
515    /// assert_eq!(arr.subarray_checked::<2>(2), None);
516    /// ```
517    fn subarray_checked<const S: usize>(&self, index: usize) -> Option<&[T; S]>;
518
519    /// Unchecked version of `subarray`. Undefined behavior if bounds are exceeded.
520    ///
521    /// # Safety
522    ///
523    /// Caller must ensure that `index + S <= self.len()`.
524    ///
525    /// # Examples
526    ///
527    /// ```
528    /// use ps_util::Array;
529    /// let arr = [1, 2, 3, 4];
530    /// unsafe {
531    ///     assert_eq!(arr.subarray_unchecked::<2>(1), &[2, 3]);
532    /// }
533    /// ```
534    unsafe fn subarray_unchecked<const S: usize>(&self, index: usize) -> &[T; S];
535
536    /// Returns an iterator over references to the elements.
537    ///
538    /// # Examples
539    ///
540    /// ```
541    /// use ps_util::Array;
542    /// let arr = [1, 2, 3];
543    /// let values: Vec<_> = arr.values().collect();
544    /// assert_eq!(values, vec![&1, &2, &3]);
545    /// ```
546    fn values<'a>(&'a self) -> impl Iterator<Item = &'a T>
547    where
548        T: 'a;
549}
550
551impl<A, T> Array<T> for A
552where
553    A: AsRef<[T]>,
554{
555    fn at(&self, index: usize) -> Option<&T> {
556        self.as_ref().get(index)
557    }
558
559    fn concat(&self, other: impl AsRef<[T]>) -> Vec<T>
560    where
561        T: Clone,
562    {
563        let lhs = self.as_ref();
564        let rhs = other.as_ref();
565
566        let mut concatenated = Vec::with_capacity(lhs.len() + rhs.len());
567
568        concatenated.extend_from_slice(lhs);
569        concatenated.extend_from_slice(rhs);
570
571        concatenated
572    }
573
574    fn entries<'a>(&'a self) -> impl Iterator<Item = (usize, &'a T)>
575    where
576        T: 'a,
577    {
578        self.as_ref().iter().enumerate()
579    }
580
581    fn every(&self, predicate: impl FnMut(&T) -> bool) -> bool {
582        self.as_ref().iter().all(predicate)
583    }
584
585    fn every_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> bool {
586        let slice = self.as_ref();
587
588        match slice {
589            [] => true,
590            [only] => comparator(only).is_eq(),
591            [first, .., last] => comparator(first).is_eq() && comparator(last).is_eq(),
592        }
593    }
594
595    fn filter(&self, mut predicate: impl FnMut(&T) -> bool) -> Vec<T>
596    where
597        T: Clone,
598    {
599        self.as_ref()
600            .iter()
601            .filter(|item| predicate(item))
602            .cloned()
603            .collect()
604    }
605
606    fn filter_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> Vec<T>
607    where
608        T: Clone,
609    {
610        let slice = self.as_ref();
611
612        let Some((start, end)) = equal_range_by(slice, &mut comparator) else {
613            return Vec::new();
614        };
615
616        slice[start..end].to_vec()
617    }
618
619    fn find(&self, mut predicate: impl FnMut(&T) -> bool) -> Option<&T> {
620        Iterator::find(&mut self.as_ref().iter(), |item| predicate(item))
621    }
622
623    fn find_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> Option<&T> {
624        let slice = self.as_ref();
625
626        equal_index_by(slice, &mut comparator).map(|idx| &slice[idx])
627    }
628
629    fn find_index(&self, predicate: impl FnMut(&T) -> bool) -> Option<usize> {
630        self.as_ref().iter().position(predicate)
631    }
632
633    fn find_index_equal_in_sorted_by(
634        &self,
635        mut comparator: impl FnMut(&T) -> Ordering,
636    ) -> Option<usize> {
637        equal_index_by(self.as_ref(), &mut comparator)
638    }
639
640    fn find_last(&self, mut predicate: impl FnMut(&T) -> bool) -> Option<&T> {
641        self.as_ref().iter().rfind(|item| predicate(item))
642    }
643
644    fn find_last_equal_in_sorted_by(
645        &self,
646        mut comparator: impl FnMut(&T) -> Ordering,
647    ) -> Option<&T> {
648        let slice = self.as_ref();
649
650        equal_last_index_by(slice, &mut comparator).map(|idx| &slice[idx])
651    }
652
653    fn find_last_index(&self, predicate: impl FnMut(&T) -> bool) -> Option<usize> {
654        self.as_ref().iter().rposition(predicate)
655    }
656
657    fn find_last_index_equal_in_sorted_by(
658        &self,
659        mut comparator: impl FnMut(&T) -> Ordering,
660    ) -> Option<usize> {
661        equal_last_index_by(self.as_ref(), &mut comparator)
662    }
663
664    fn flat(&self) -> Vec<<T>::Item>
665    where
666        T: Clone + IntoIterator,
667    {
668        self.as_ref().iter().cloned().flatten().collect()
669    }
670
671    fn flat_map<O, I>(&self, mapper: impl FnMut(&T) -> I) -> Vec<O>
672    where
673        I: IntoIterator<Item = O>,
674    {
675        self.as_ref().iter().flat_map(mapper).collect()
676    }
677
678    fn for_each(&self, cb: impl FnMut(&T)) {
679        self.as_ref().iter().for_each(cb);
680    }
681
682    fn includes(&self, value: &T) -> bool
683    where
684        T: PartialEq,
685    {
686        self.as_ref().contains(value)
687    }
688
689    fn index_of(&self, value: &T) -> Option<usize>
690    where
691        T: PartialEq,
692    {
693        self.as_ref().iter().position(|x| x == value)
694    }
695
696    fn is_empty(&self) -> bool {
697        self.as_ref().is_empty()
698    }
699
700    fn join<S>(&self, separator: &S) -> String
701    where
702        S: std::fmt::Display + ?Sized,
703        T: std::fmt::Display,
704    {
705        let mut iter = self.as_ref().iter();
706        let first = iter.next().map(ToString::to_string).unwrap_or_default();
707
708        iter.fold(first, |mut out, item| {
709            #[allow(clippy::expect_used)]
710            write!(out, "{separator}{item}").expect("writing to String failed");
711            out
712        })
713    }
714
715    fn keys(&self) -> impl Iterator<Item = usize> {
716        0..self.as_ref().len()
717    }
718
719    fn last_index_of(&self, value: &T) -> Option<usize>
720    where
721        T: PartialEq,
722    {
723        self.find_last_index(|item| item == value)
724    }
725
726    fn len(&self) -> usize {
727        self.as_ref().len()
728    }
729
730    fn map<O>(&self, mapper: impl FnMut(&T) -> O) -> Vec<O> {
731        self.as_ref().iter().map(mapper).collect()
732    }
733
734    fn reduce<O>(&self, reducer: impl FnMut(O, &T) -> O, initial: O) -> O {
735        self.as_ref().iter().fold(initial, reducer)
736    }
737
738    fn reduce_right<O>(&self, reducer: impl FnMut(O, &T) -> O, initial: O) -> O {
739        self.as_ref().iter().rev().fold(initial, reducer)
740    }
741
742    fn slice(&self, start: usize, end: Option<usize>) -> &[T] {
743        let full = self.as_ref();
744        let len = full.len();
745        let start = usize::min(start, len);
746        let end = end.unwrap_or(len).clamp(start, len);
747
748        &full[start..end]
749    }
750
751    fn some(&self, predicate: impl FnMut(&T) -> bool) -> bool {
752        self.as_ref().iter().any(predicate)
753    }
754
755    fn some_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> bool {
756        equal_index_by(self.as_ref(), &mut comparator).is_some()
757    }
758
759    fn none(&self, predicate: impl FnMut(&T) -> bool) -> bool {
760        !self.some(predicate)
761    }
762
763    fn none_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> bool {
764        !self.some_equal_in_sorted_by(comparator)
765    }
766
767    fn subarray<const S: usize>(&self, index: usize) -> &[T; S] {
768        subarray(self.as_ref(), index)
769    }
770
771    fn subarray_checked<const S: usize>(&self, index: usize) -> Option<&[T; S]> {
772        subarray_checked(self.as_ref(), index)
773    }
774
775    unsafe fn subarray_unchecked<const S: usize>(&self, index: usize) -> &[T; S] {
776        subarray_unchecked(self.as_ref(), index)
777    }
778
779    fn values<'a>(&'a self) -> impl Iterator<Item = &'a T>
780    where
781        T: 'a,
782    {
783        self.as_ref().iter()
784    }
785}
786
787fn lower_bound_by<T, F>(slice: &[T], comparator: &mut F) -> usize
788where
789    F: FnMut(&T) -> Ordering,
790{
791    slice.partition_point(|item| comparator(item).is_lt())
792}
793
794fn equal_index_by<T, F>(slice: &[T], comparator: &mut F) -> Option<usize>
795where
796    F: FnMut(&T) -> Ordering,
797{
798    let idx = lower_bound_by(slice, comparator);
799    (idx < slice.len() && comparator(&slice[idx]).is_eq()).then_some(idx)
800}
801
802fn upper_bound_by<T, F>(slice: &[T], comparator: &mut F) -> usize
803where
804    F: FnMut(&T) -> Ordering,
805{
806    slice.partition_point(|item| !comparator(item).is_gt())
807}
808
809fn equal_last_index_by<T, F>(slice: &[T], comparator: &mut F) -> Option<usize>
810where
811    F: FnMut(&T) -> Ordering,
812{
813    let end = upper_bound_by(slice, comparator);
814    (end > 0 && comparator(&slice[end - 1]).is_eq()).then(|| end - 1)
815}
816
817fn equal_range_by<T, F>(slice: &[T], comparator: &mut F) -> Option<(usize, usize)>
818where
819    F: FnMut(&T) -> Ordering,
820{
821    let start = equal_index_by(slice, comparator)?;
822    let end = start + upper_bound_by(&slice[start..], comparator);
823
824    (start < end).then_some((start, end))
825}