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}