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}