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