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 /// # Errors
322 ///
323 /// Errors are passed from the [`std::fmt::Display`] implementation.
324 ///
325 /// # Examples
326 ///
327 /// ```
328 /// use ps_util::Array;
329 /// let arr = [1, 2, 3];
330 /// assert_eq!(arr.join(", ").unwrap(), "1, 2, 3");
331 /// ```
332 fn join(&self, separator: &str) -> Result<String, std::fmt::Error>
333 where
334 T: std::fmt::Display;
335
336 /// Returns an iterator of indices (0, 1, 2, ...).
337 ///
338 /// # Examples
339 ///
340 /// ```
341 /// use ps_util::Array;
342 /// let arr = ['a', 'b', 'c'];
343 /// let keys: Vec<_> = arr.keys().collect();
344 /// assert_eq!(keys, vec![0, 1, 2]);
345 /// ```
346 fn keys(&self) -> impl Iterator<Item = usize>;
347
348 /// Returns the index of the last occurrence of the specified value,
349 /// or `None` if not found.
350 ///
351 /// # Examples
352 ///
353 /// ```
354 /// use ps_util::Array;
355 /// let arr = [1, 2, 3, 2];
356 /// assert_eq!(arr.last_index_of(&2), Some(3));
357 /// assert_eq!(arr.last_index_of(&5), None);
358 /// ```
359 fn last_index_of(&self, value: &T) -> Option<usize>
360 where
361 T: PartialEq;
362
363 /// Returns the number of elements in the array.
364 ///
365 /// # Examples
366 ///
367 /// ```
368 /// use ps_util::Array;
369 /// let arr = [1, 2, 3];
370 /// assert_eq!(arr.len(), 3);
371 /// ```
372 fn len(&self) -> usize;
373
374 /// Transforms each element using the provided mapper function
375 /// and returns a vector of the results.
376 ///
377 /// # Examples
378 ///
379 /// ```
380 /// use ps_util::Array;
381 /// let arr = [1, 2, 3u8];
382 /// assert_eq!(arr.as_slice().map(|x| x * 2), vec![2, 4, 6]);
383 /// ```
384 fn map<O>(&self, mapper: impl FnMut(&T) -> O) -> Vec<O>;
385
386 /// Reduces the array to a single value by applying a callback
387 /// with an accumulator, starting from the left.
388 ///
389 /// # Examples
390 ///
391 /// ```
392 /// use ps_util::Array;
393 /// let arr = [1, 2, 3, 4];
394 /// let sum = arr.reduce(|acc, x| acc + x, 0);
395 /// assert_eq!(sum, 10);
396 /// ```
397 fn reduce<O>(&self, reducer: impl FnMut(O, &T) -> O, initial: O) -> O;
398
399 /// Reduces the array to a single value by applying a callback
400 /// with an accumulator, starting from the right.
401 ///
402 /// # Examples
403 ///
404 /// ```
405 /// use ps_util::Array;
406 /// let arr = [1, 2, 3];
407 /// let result = arr.reduce_right(
408 /// |acc, x| format!("{}{}", acc, x),
409 /// String::new()
410 /// );
411 /// assert_eq!(result, "321");
412 /// ```
413 fn reduce_right<O>(&self, reducer: impl FnMut(O, &T) -> O, initial: O) -> O;
414
415 /// Returns a slice of the array from `start` to `end` (exclusive).
416 ///
417 /// If `end` is `None`, slices to the end of the array. Indices are clamped
418 /// to valid bounds; if `start` exceeds the array length, an empty slice
419 /// is returned.
420 ///
421 /// # Examples
422 ///
423 /// ```
424 /// use ps_util::Array;
425 /// let arr = [1, 2, 3, 4];
426 /// assert_eq!(arr.slice(1, Some(3)), &[2, 3][..]);
427 /// assert_eq!(arr.slice(2, None), &[3, 4][..]);
428 /// assert_eq!(arr.slice(10, Some(20)), &[][..]);
429 /// ```
430 fn slice(&self, start: usize, end: Option<usize>) -> &[T];
431
432 /// Tests whether any element matches the predicate.
433 ///
434 /// Returns `true` if the predicate returns `true` for at least one element.
435 ///
436 /// # Examples
437 ///
438 /// ```
439 /// use ps_util::Array;
440 /// let arr = [1, 2, 3];
441 /// assert!(arr.some(|x| x > &2));
442 /// assert!(!arr.some(|x| x > &10));
443 /// ```
444 fn some(&self, predicate: impl FnMut(&T) -> bool) -> bool;
445
446 /// Tests whether any element is equal to the comparator target.
447 ///
448 /// The slice must be sorted according to the same ordering used by
449 /// `comparator`.
450 ///
451 /// Time complexity: `O(log n)`.
452 ///
453 /// # Examples
454 ///
455 /// ```
456 /// use ps_util::Array;
457 /// let arr = [1, 2, 2, 3];
458 /// assert!(arr.some_equal_in_sorted_by(|x| x.cmp(&2)));
459 /// assert!(!arr.some_equal_in_sorted_by(|x| x.cmp(&5)));
460 /// ```
461 fn some_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> bool;
462
463 /// Tests whether no elements match the predicate.
464 ///
465 /// Returns `true` if the predicate returns `false` for every element,
466 /// or if the array is empty.
467 ///
468 /// # Examples
469 ///
470 /// ```
471 /// use ps_util::Array;
472 /// let arr = [1, 2, 3];
473 /// assert!(arr.none(|x| x > &10));
474 /// assert!(!arr.none(|x| x > &2));
475 /// ```
476 fn none(&self, predicate: impl FnMut(&T) -> bool) -> bool;
477
478 /// Tests whether no element is equal to the comparator target.
479 ///
480 /// The slice must be sorted according to the same ordering used by
481 /// `comparator`.
482 ///
483 /// Time complexity: `O(log n)`.
484 ///
485 /// # Examples
486 ///
487 /// ```
488 /// use ps_util::Array;
489 /// let arr = [1, 2, 2, 3];
490 /// assert!(arr.none_equal_in_sorted_by(|x| x.cmp(&5)));
491 /// assert!(!arr.none_equal_in_sorted_by(|x| x.cmp(&2)));
492 /// ```
493 fn none_equal_in_sorted_by(&self, comparator: impl FnMut(&T) -> Ordering) -> bool;
494
495 /// Returns a fixed-size array reference starting at the given index.
496 ///
497 /// # Panics
498 ///
499 /// Panics if there are not enough elements remaining in the array.
500 ///
501 /// # Examples
502 ///
503 /// ```
504 /// use ps_util::Array;
505 /// let arr = [1, 2, 3, 4];
506 /// assert_eq!(arr.subarray::<2>(1), &[2, 3]);
507 /// ```
508 fn subarray<const S: usize>(&self, index: usize) -> &[T; S];
509
510 /// Checked version of `subarray`. Returns `None` if bounds are exceeded.
511 ///
512 /// # Examples
513 ///
514 /// ```
515 /// use ps_util::Array;
516 /// let arr = [1, 2, 3];
517 /// assert_eq!(arr.subarray_checked::<2>(1), Some(&[2, 3]));
518 /// assert_eq!(arr.subarray_checked::<2>(2), None);
519 /// ```
520 fn subarray_checked<const S: usize>(&self, index: usize) -> Option<&[T; S]>;
521
522 /// Unchecked version of `subarray`. Undefined behavior if bounds are exceeded.
523 ///
524 /// # Safety
525 ///
526 /// Caller must ensure that `index + S <= self.len()`.
527 ///
528 /// # Examples
529 ///
530 /// ```
531 /// use ps_util::Array;
532 /// let arr = [1, 2, 3, 4];
533 /// unsafe {
534 /// assert_eq!(arr.subarray_unchecked::<2>(1), &[2, 3]);
535 /// }
536 /// ```
537 unsafe fn subarray_unchecked<const S: usize>(&self, index: usize) -> &[T; S];
538
539 /// Returns an iterator over references to the elements.
540 ///
541 /// # Examples
542 ///
543 /// ```
544 /// use ps_util::Array;
545 /// let arr = [1, 2, 3];
546 /// let values: Vec<_> = arr.values().collect();
547 /// assert_eq!(values, vec![&1, &2, &3]);
548 /// ```
549 fn values<'a>(&'a self) -> impl Iterator<Item = &'a T>
550 where
551 T: 'a;
552}
553
554impl<A, T> Array<T> for A
555where
556 A: AsRef<[T]>,
557{
558 fn at(&self, index: usize) -> Option<&T> {
559 self.as_ref().get(index)
560 }
561
562 fn concat(&self, other: impl AsRef<[T]>) -> Vec<T>
563 where
564 T: Clone,
565 {
566 let lhs = self.as_ref();
567 let rhs = other.as_ref();
568
569 let mut concatenated = Vec::with_capacity(lhs.len() + rhs.len());
570
571 concatenated.extend_from_slice(lhs);
572 concatenated.extend_from_slice(rhs);
573
574 concatenated
575 }
576
577 fn entries<'a>(&'a self) -> impl Iterator<Item = (usize, &'a T)>
578 where
579 T: 'a,
580 {
581 self.as_ref().iter().enumerate()
582 }
583
584 fn every(&self, predicate: impl FnMut(&T) -> bool) -> bool {
585 self.as_ref().iter().all(predicate)
586 }
587
588 fn every_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> bool {
589 let slice = self.as_ref();
590
591 match slice {
592 [] => true,
593 [only] => comparator(only).is_eq(),
594 [first, .., last] => comparator(first).is_eq() && comparator(last).is_eq(),
595 }
596 }
597
598 fn filter(&self, mut predicate: impl FnMut(&T) -> bool) -> Vec<T>
599 where
600 T: Clone,
601 {
602 self.as_ref()
603 .iter()
604 .filter(|item| predicate(item))
605 .cloned()
606 .collect()
607 }
608
609 fn filter_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> Vec<T>
610 where
611 T: Clone,
612 {
613 let slice = self.as_ref();
614
615 let Some((start, end)) = equal_range_by(slice, &mut comparator) else {
616 return Vec::new();
617 };
618
619 slice[start..end].to_vec()
620 }
621
622 fn find(&self, mut predicate: impl FnMut(&T) -> bool) -> Option<&T> {
623 Iterator::find(&mut self.as_ref().iter(), |item| predicate(item))
624 }
625
626 fn find_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> Option<&T> {
627 let slice = self.as_ref();
628
629 equal_index_by(slice, &mut comparator).map(|idx| &slice[idx])
630 }
631
632 fn find_index(&self, predicate: impl FnMut(&T) -> bool) -> Option<usize> {
633 self.as_ref().iter().position(predicate)
634 }
635
636 fn find_index_equal_in_sorted_by(
637 &self,
638 mut comparator: impl FnMut(&T) -> Ordering,
639 ) -> Option<usize> {
640 equal_index_by(self.as_ref(), &mut comparator)
641 }
642
643 fn find_last(&self, mut predicate: impl FnMut(&T) -> bool) -> Option<&T> {
644 self.as_ref().iter().rfind(|item| predicate(item))
645 }
646
647 fn find_last_equal_in_sorted_by(
648 &self,
649 mut comparator: impl FnMut(&T) -> Ordering,
650 ) -> Option<&T> {
651 let slice = self.as_ref();
652
653 equal_last_index_by(slice, &mut comparator).map(|idx| &slice[idx])
654 }
655
656 fn find_last_index(&self, predicate: impl FnMut(&T) -> bool) -> Option<usize> {
657 self.as_ref().iter().rposition(predicate)
658 }
659
660 fn find_last_index_equal_in_sorted_by(
661 &self,
662 mut comparator: impl FnMut(&T) -> Ordering,
663 ) -> Option<usize> {
664 equal_last_index_by(self.as_ref(), &mut comparator)
665 }
666
667 fn flat(&self) -> Vec<<T>::Item>
668 where
669 T: Clone + IntoIterator,
670 {
671 self.as_ref().iter().cloned().flatten().collect()
672 }
673
674 fn flat_map<O, I>(&self, mapper: impl FnMut(&T) -> I) -> Vec<O>
675 where
676 I: IntoIterator<Item = O>,
677 {
678 self.as_ref().iter().flat_map(mapper).collect()
679 }
680
681 fn for_each(&self, cb: impl FnMut(&T)) {
682 self.as_ref().iter().for_each(cb);
683 }
684
685 fn includes(&self, value: &T) -> bool
686 where
687 T: PartialEq,
688 {
689 self.as_ref().contains(value)
690 }
691
692 fn index_of(&self, value: &T) -> Option<usize>
693 where
694 T: PartialEq,
695 {
696 self.as_ref().iter().position(|x| x == value)
697 }
698
699 fn is_empty(&self) -> bool {
700 self.as_ref().is_empty()
701 }
702
703 fn join(&self, separator: &str) -> Result<String, std::fmt::Error>
704 where
705 T: std::fmt::Display,
706 {
707 let mut a = String::new();
708 let mut iterator = self.as_ref().iter();
709
710 if let Some(first) = iterator.next() {
711 write!(&mut a, "{first}")?;
712
713 for item in iterator {
714 write!(&mut a, "{separator}{item}")?;
715 }
716 }
717
718 Ok(a)
719 }
720
721 fn keys(&self) -> impl Iterator<Item = usize> {
722 0..self.as_ref().len()
723 }
724
725 fn last_index_of(&self, value: &T) -> Option<usize>
726 where
727 T: PartialEq,
728 {
729 self.find_last_index(|item| item == value)
730 }
731
732 fn len(&self) -> usize {
733 self.as_ref().len()
734 }
735
736 fn map<O>(&self, mapper: impl FnMut(&T) -> O) -> Vec<O> {
737 self.as_ref().iter().map(mapper).collect()
738 }
739
740 fn reduce<O>(&self, reducer: impl FnMut(O, &T) -> O, initial: O) -> O {
741 self.as_ref().iter().fold(initial, reducer)
742 }
743
744 fn reduce_right<O>(&self, reducer: impl FnMut(O, &T) -> O, initial: O) -> O {
745 self.as_ref().iter().rev().fold(initial, reducer)
746 }
747
748 fn slice(&self, start: usize, end: Option<usize>) -> &[T] {
749 let full = self.as_ref();
750 let len = full.len();
751 let start = usize::min(start, len);
752 let end = end.unwrap_or(len).clamp(start, len);
753
754 &full[start..end]
755 }
756
757 fn some(&self, predicate: impl FnMut(&T) -> bool) -> bool {
758 self.as_ref().iter().any(predicate)
759 }
760
761 fn some_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> bool {
762 equal_index_by(self.as_ref(), &mut comparator).is_some()
763 }
764
765 fn none(&self, predicate: impl FnMut(&T) -> bool) -> bool {
766 !self.as_ref().iter().any(predicate)
767 }
768
769 fn none_equal_in_sorted_by(&self, mut comparator: impl FnMut(&T) -> Ordering) -> bool {
770 equal_index_by(self.as_ref(), &mut comparator).is_none()
771 }
772
773 fn subarray<const S: usize>(&self, index: usize) -> &[T; S] {
774 subarray(self.as_ref(), index)
775 }
776
777 fn subarray_checked<const S: usize>(&self, index: usize) -> Option<&[T; S]> {
778 subarray_checked(self.as_ref(), index)
779 }
780
781 unsafe fn subarray_unchecked<const S: usize>(&self, index: usize) -> &[T; S] {
782 subarray_unchecked(self.as_ref(), index)
783 }
784
785 fn values<'a>(&'a self) -> impl Iterator<Item = &'a T>
786 where
787 T: 'a,
788 {
789 self.as_ref().iter()
790 }
791}
792
793fn lower_bound_by<T, F>(slice: &[T], comparator: &mut F) -> usize
794where
795 F: FnMut(&T) -> Ordering,
796{
797 slice.partition_point(|item| comparator(item).is_lt())
798}
799
800fn equal_index_by<T, F>(slice: &[T], comparator: &mut F) -> Option<usize>
801where
802 F: FnMut(&T) -> Ordering,
803{
804 let idx = lower_bound_by(slice, comparator);
805 (idx < slice.len() && comparator(&slice[idx]).is_eq()).then_some(idx)
806}
807
808fn upper_bound_by<T, F>(slice: &[T], comparator: &mut F) -> usize
809where
810 F: FnMut(&T) -> Ordering,
811{
812 slice.partition_point(|item| !comparator(item).is_gt())
813}
814
815fn equal_last_index_by<T, F>(slice: &[T], comparator: &mut F) -> Option<usize>
816where
817 F: FnMut(&T) -> Ordering,
818{
819 let end = upper_bound_by(slice, comparator);
820 (end > 0 && comparator(&slice[end - 1]).is_eq()).then(|| end - 1)
821}
822
823fn equal_range_by<T, F>(slice: &[T], comparator: &mut F) -> Option<(usize, usize)>
824where
825 F: FnMut(&T) -> Ordering,
826{
827 let start = equal_index_by(slice, comparator)?;
828 let end = start + upper_bound_by(&slice[start..], comparator);
829
830 (start < end).then_some((start, end))
831}